ObsidianDragon - DragonX ImGui Wallet
Full-node GUI wallet for DragonX cryptocurrency. Built with Dear ImGui, SDL3, and OpenGL3/DX11. Features: - Send/receive shielded and transparent transactions - Autoshield with merged transaction display - Built-in CPU mining (xmrig) - Peer management and network monitoring - Wallet encryption with PIN lock - QR code generation for receive addresses - Transaction history with pagination - Console for direct RPC commands - Cross-platform (Linux, Windows)
173
.github/copilot-instructions.md
vendored
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
# Copilot Instructions — DragonX ImGui Wallet
|
||||||
|
|
||||||
|
## UI Layout: All values in `ui.toml`
|
||||||
|
|
||||||
|
**Every UI layout constant must be defined in `res/themes/ui.toml` and read at runtime via the schema API.** Never hardcode pixel sizes, ratios, rounding values, thicknesses, or spacing constants directly in C++ source files. This is critical for maintainability, theming support, and hot-reload.
|
||||||
|
|
||||||
|
### Schema API reference
|
||||||
|
|
||||||
|
The singleton is accessed via `schema::UI()` (header: `#include "../schema/ui_schema.h"`).
|
||||||
|
|
||||||
|
| Method | Returns | Use for |
|
||||||
|
|---|---|---|
|
||||||
|
| `drawElement(section, name)` | `DrawElementStyle` | Custom DrawList layout values (`.size`, `.height`, `.thickness`, `.radius`, `.opacity`) |
|
||||||
|
| `button(section, name)` | `ButtonStyle` | Button width/height/font |
|
||||||
|
| `input(section, name)` | `InputStyle` | Input field dimensions |
|
||||||
|
| `label(section, name)` | `LabelStyle` | Label styling |
|
||||||
|
| `table(section, name)` | `TableStyle` | Table layout |
|
||||||
|
| `window(section, name)` | `WindowStyle` | Window/dialog dimensions |
|
||||||
|
| `combo(section, name)` | `ComboStyle` | Combo box styling |
|
||||||
|
| `slider(section, name)` | `SliderStyle` | Slider styling |
|
||||||
|
| `checkbox(section, name)` | `CheckboxStyle` | Checkbox styling |
|
||||||
|
| `separator(section, name)` | `SeparatorStyle` | Separator/divider styling |
|
||||||
|
|
||||||
|
### Section naming convention
|
||||||
|
|
||||||
|
Sections use dot-separated paths matching the file/feature:
|
||||||
|
|
||||||
|
- `tabs.send`, `tabs.receive`, `tabs.transactions`, `tabs.mining`, `tabs.peers`, `tabs.market` — tab-specific values
|
||||||
|
- `tabs.balance` — balance/home tab
|
||||||
|
- `components.main-layout`, `components.settings-page` — shared components
|
||||||
|
- `dialogs.about`, `dialogs.backup`, etc. — dialog-specific values
|
||||||
|
- `sidebar` — navigation sidebar
|
||||||
|
|
||||||
|
### How to add a new layout value
|
||||||
|
|
||||||
|
1. **Add the entry to `res/themes/ui.toml`** under the appropriate section:
|
||||||
|
```toml
|
||||||
|
[tabs.example]
|
||||||
|
my-element = {size = 42.0}
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Read it in C++** instead of using a literal:
|
||||||
|
```cpp
|
||||||
|
// WRONG — hardcoded
|
||||||
|
float myValue = 42.0f;
|
||||||
|
|
||||||
|
// CORRECT — schema-driven
|
||||||
|
float myValue = schema::UI().drawElement("tabs.example", "my-element").size;
|
||||||
|
```
|
||||||
|
|
||||||
|
3. For values used as min/max pairs with scaling:
|
||||||
|
```cpp
|
||||||
|
// WRONG
|
||||||
|
float h = std::max(18.0f, 24.0f * vScale);
|
||||||
|
|
||||||
|
// CORRECT
|
||||||
|
float h = std::max(
|
||||||
|
schema::UI().drawElement("tabs.example", "row-min-height").size,
|
||||||
|
schema::UI().drawElement("tabs.example", "row-height").size * vScale
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
### What belongs in `ui.toml`
|
||||||
|
|
||||||
|
- Pixel sizes (card heights, icon sizes, bar widths/heights)
|
||||||
|
- Ratios (column width ratios, max-width ratios)
|
||||||
|
- Rounding values (`FrameRounding`, corner radius)
|
||||||
|
- Thickness values (accent bars, chart lines, borders)
|
||||||
|
- Dot/circle radii
|
||||||
|
- Fade zones, padding constants
|
||||||
|
- Min/max dimension bounds
|
||||||
|
- Font selection (via schema font name strings, resolved with `S.resolveFont()`)
|
||||||
|
- Colors (via `schema::UI().resolveColor()` or color variable references like `"var(--primary)"`)
|
||||||
|
- Animation durations (transition times, fade durations, pulse speeds)
|
||||||
|
- Business logic values (fee amounts, ticker strings, buffer sizes, reward amounts)
|
||||||
|
|
||||||
|
### What does NOT belong in `ui.toml`
|
||||||
|
|
||||||
|
- Spacing that already goes through `Layout::spacing*()` or `spacing::dp()`
|
||||||
|
|
||||||
|
### Legacy system: `UILayout`
|
||||||
|
|
||||||
|
`UILayout::instance()` is the older layout system still used for fonts, typography, panels, and global spacing. New layout values should use `schema::UI().drawElement()` instead. Do not add new keys to `UILayout`.
|
||||||
|
|
||||||
|
### Validation
|
||||||
|
|
||||||
|
After editing `ui.toml`, always validate:
|
||||||
|
```bash
|
||||||
|
python3 -c "import toml; toml.load('res/themes/ui.toml'); print('Valid TOML')"
|
||||||
|
```
|
||||||
|
|
||||||
|
Or with the C++ toml++ parser (which is what the app uses):
|
||||||
|
```bash
|
||||||
|
cd build && make -j$(nproc)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Build
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Linux
|
||||||
|
cd build && make -j$(nproc)
|
||||||
|
|
||||||
|
# Windows cross-compile
|
||||||
|
./build.sh --win-release
|
||||||
|
```
|
||||||
|
|
||||||
|
## Plans
|
||||||
|
|
||||||
|
When asked to "create a plan", always create a new markdown document in the `docs/` directory with the plan contents.
|
||||||
|
|
||||||
|
## Icons: Use Material Design icon font, never Unicode symbols
|
||||||
|
|
||||||
|
**Never use raw Unicode symbols or emoji characters** (e.g. `↓`, `↗`, `⛏`, `🔍`, `📬`, `⚠️`, `ℹ`) for icons in C++ code. Always use the **Material Design Icons font** via the `ICON_MD_*` defines from `#include "../../embedded/IconsMaterialDesign.h"`.
|
||||||
|
|
||||||
|
### Icon font API
|
||||||
|
|
||||||
|
| Method | Size | Fallback |
|
||||||
|
|---|---|---|
|
||||||
|
| `Type().iconSmall()` | 14px | Body2 |
|
||||||
|
| `Type().iconMed()` | 18px | Body1 |
|
||||||
|
| `Type().iconLarge()` | 24px | H5 |
|
||||||
|
| `Type().iconXL()` | 40px | H3 |
|
||||||
|
|
||||||
|
### Correct usage
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
#include "../../embedded/IconsMaterialDesign.h"
|
||||||
|
|
||||||
|
// WRONG — raw Unicode symbol
|
||||||
|
itemSpec.leadingIcon = "↙";
|
||||||
|
|
||||||
|
// CORRECT — Material Design icon codepoint
|
||||||
|
itemSpec.leadingIcon = ICON_MD_CALL_RECEIVED;
|
||||||
|
|
||||||
|
// WRONG — emoji for search
|
||||||
|
searchSpec.leadingIcon = "🔍";
|
||||||
|
|
||||||
|
// CORRECT — Material Design icon
|
||||||
|
searchSpec.leadingIcon = ICON_MD_SEARCH;
|
||||||
|
|
||||||
|
// For rendering with icon font directly:
|
||||||
|
ImGui::PushFont(Type().iconSmall());
|
||||||
|
ImGui::TextUnformatted(ICON_MD_ARROW_DOWNWARD);
|
||||||
|
ImGui::PopFont();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Why
|
||||||
|
|
||||||
|
Raw Unicode symbols and emoji render inconsistently across platforms and may not be present in the loaded text fonts. The Material Design icon font is always loaded and provides consistent, scalable glyphs on both Linux and Windows.
|
||||||
|
|
||||||
|
### Audit for Unicode symbols
|
||||||
|
|
||||||
|
Before completing any task that touches UI code, search for and replace any raw Unicode symbols that may have been introduced. Common symbols to look for:
|
||||||
|
|
||||||
|
| Unicode | Replacement |
|
||||||
|
|---------|-------------|
|
||||||
|
| `▶` `▷` | `ICON_MD_PLAY_ARROW` |
|
||||||
|
| `■` `□` `◼` `◻` | `ICON_MD_STOP` or `ICON_MD_SQUARE` |
|
||||||
|
| `●` `○` `◉` `◎` | `ICON_MD_FIBER_MANUAL_RECORD` or `ICON_MD_CIRCLE` |
|
||||||
|
| `↑` `↓` `←` `→` | `ICON_MD_ARROW_UPWARD`, `_DOWNWARD`, `_BACK`, `_FORWARD` |
|
||||||
|
| `↙` `↗` `↖` `↘` | `ICON_MD_CALL_RECEIVED`, `_MADE`, etc. |
|
||||||
|
| `✓` `✔` | `ICON_MD_CHECK` |
|
||||||
|
| `✗` `✕` `✖` | `ICON_MD_CLOSE` |
|
||||||
|
| `⚠` `⚠️` | `ICON_MD_WARNING` |
|
||||||
|
| `ℹ` `ℹ️` | `ICON_MD_INFO` |
|
||||||
|
| `🔍` | `ICON_MD_SEARCH` |
|
||||||
|
| `📋` | `ICON_MD_CONTENT_COPY` or `ICON_MD_DESCRIPTION` |
|
||||||
|
| `🛡` `🛡️` | `ICON_MD_SHIELD` |
|
||||||
|
| `⏳` | `ICON_MD_HOURGLASS_EMPTY` |
|
||||||
|
| `🔄` `↻` `⟳` | `ICON_MD_SYNC` or `ICON_MD_REFRESH` |
|
||||||
|
| `⚙` `⚙️` | `ICON_MD_SETTINGS` |
|
||||||
|
| `🔒` | `ICON_MD_LOCK` |
|
||||||
|
| `★` `☆` | `ICON_MD_STAR` or `ICON_MD_STAR_BORDER` |
|
||||||
35
.gitignore
vendored
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
# Build trees per platform (build/linux/, build/windows/, build/mac/)
|
||||||
|
build/*
|
||||||
|
|
||||||
|
# Release distributable artifacts (release/linux/, release/windows/, release/mac/)
|
||||||
|
release/
|
||||||
|
|
||||||
|
# Prebuilt binaries (ignore contents, keep dirs via .gitkeep)
|
||||||
|
prebuilt-binaries/dragonxd-linux/*
|
||||||
|
!prebuilt-binaries/dragonxd-linux/.gitkeep
|
||||||
|
prebuilt-binaries/dragonxd-win/*
|
||||||
|
!prebuilt-binaries/dragonxd-win/.gitkeep
|
||||||
|
prebuilt-binaries/dragonxd-mac/*
|
||||||
|
!prebuilt-binaries/dragonxd-mac/.gitkeep
|
||||||
|
prebuilt-binaries/xmrig-hac/*
|
||||||
|
!prebuilt-binaries/xmrig-hac/.gitkeep
|
||||||
|
|
||||||
|
|
||||||
|
# External sources / toolchains (created by scripts/setup.sh)
|
||||||
|
external/
|
||||||
|
|
||||||
|
# Internal docs
|
||||||
|
doc/
|
||||||
|
|
||||||
|
# Downloaded libsodium (built by scripts/fetch-libsodium.sh)
|
||||||
|
libs/libsodium-mac/
|
||||||
|
libs/libsodium-win/
|
||||||
|
libs/libsodium/
|
||||||
|
libs/libsodium-*.tar.gz
|
||||||
|
|
||||||
|
# dev artifacts
|
||||||
|
imgui.ini
|
||||||
|
*.bak
|
||||||
|
*.bak*
|
||||||
|
*.params
|
||||||
|
asmap.dat
|
||||||
578
CMakeLists.txt
Normal file
@@ -0,0 +1,578 @@
|
|||||||
|
# DragonX Wallet - ImGui Edition
|
||||||
|
# Copyright 2024-2026 The Hush Developers
|
||||||
|
# Released under the GPLv3
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.20)
|
||||||
|
project(ObsidianDragon
|
||||||
|
VERSION 1.0.0
|
||||||
|
LANGUAGES C CXX
|
||||||
|
DESCRIPTION "DragonX Cryptocurrency Wallet"
|
||||||
|
)
|
||||||
|
|
||||||
|
# C++17 standard
|
||||||
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
|
|
||||||
|
# Build type
|
||||||
|
if(NOT CMAKE_BUILD_TYPE)
|
||||||
|
set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Options
|
||||||
|
option(DRAGONX_USE_SYSTEM_SDL3 "Use system SDL3 instead of fetching" ON)
|
||||||
|
option(DRAGONX_ENABLE_EMBEDDED_DAEMON "Enable embedded dragonxd support" ON)
|
||||||
|
|
||||||
|
# Output directories
|
||||||
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
||||||
|
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
||||||
|
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Dependencies
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# OpenGL (Linux only - Windows uses DirectX 11, macOS uses frameworks)
|
||||||
|
if(NOT WIN32 AND NOT APPLE)
|
||||||
|
find_package(OpenGL REQUIRED)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# miniz - bundled zip library (MIT / public domain)
|
||||||
|
set(MINIZ_DIR ${CMAKE_SOURCE_DIR}/libs/miniz)
|
||||||
|
set(MINIZ_SOURCES
|
||||||
|
${MINIZ_DIR}/miniz.c
|
||||||
|
${MINIZ_DIR}/miniz_tdef.c
|
||||||
|
${MINIZ_DIR}/miniz_tinfl.c
|
||||||
|
${MINIZ_DIR}/miniz_zip.c
|
||||||
|
)
|
||||||
|
|
||||||
|
# GLAD - bundled OpenGL loader (Linux/macOS — Windows uses DX11)
|
||||||
|
set(GLAD_DIR ${CMAKE_SOURCE_DIR}/libs/glad)
|
||||||
|
if(NOT WIN32)
|
||||||
|
set(GLAD_SOURCES ${GLAD_DIR}/src/gl.c)
|
||||||
|
else()
|
||||||
|
set(GLAD_SOURCES "")
|
||||||
|
endif()
|
||||||
|
set(GLAD_INCLUDE ${GLAD_DIR}/include)
|
||||||
|
message(STATUS "Using bundled GLAD for OpenGL loading")
|
||||||
|
|
||||||
|
# SDL3 - try system first, then fetch
|
||||||
|
if(DRAGONX_USE_SYSTEM_SDL3)
|
||||||
|
find_package(SDL3 QUIET)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT SDL3_FOUND)
|
||||||
|
message(STATUS "SDL3 not found, will fetch from source...")
|
||||||
|
include(FetchContent)
|
||||||
|
FetchContent_Declare(
|
||||||
|
SDL3
|
||||||
|
GIT_REPOSITORY https://github.com/libsdl-org/SDL.git
|
||||||
|
GIT_TAG 267e681a
|
||||||
|
GIT_SHALLOW FALSE
|
||||||
|
)
|
||||||
|
set(SDL_SHARED OFF CACHE BOOL "" FORCE)
|
||||||
|
set(SDL_STATIC ON CACHE BOOL "" FORCE)
|
||||||
|
FetchContent_MakeAvailable(SDL3)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# nlohmann/json (header-only) — used for RPC, language files, and legacy theme formats
|
||||||
|
include(FetchContent)
|
||||||
|
FetchContent_Declare(
|
||||||
|
json
|
||||||
|
GIT_REPOSITORY https://github.com/nlohmann/json.git
|
||||||
|
GIT_TAG v3.11.3
|
||||||
|
GIT_SHALLOW TRUE
|
||||||
|
)
|
||||||
|
FetchContent_MakeAvailable(json)
|
||||||
|
|
||||||
|
# toml++ (header-only) — used for UI schema / theme configuration files
|
||||||
|
FetchContent_Declare(
|
||||||
|
tomlplusplus
|
||||||
|
GIT_REPOSITORY https://github.com/marzer/tomlplusplus.git
|
||||||
|
GIT_TAG v3.4.0
|
||||||
|
GIT_SHALLOW TRUE
|
||||||
|
)
|
||||||
|
FetchContent_MakeAvailable(tomlplusplus)
|
||||||
|
|
||||||
|
# libcurl for HTTPS RPC connections (more reliable than cpp-httplib with OpenSSL 3.x)
|
||||||
|
if(WIN32)
|
||||||
|
# For Windows cross-compilation, fetch and build libcurl statically
|
||||||
|
message(STATUS "Fetching libcurl for Windows build...")
|
||||||
|
FetchContent_Declare(
|
||||||
|
curl
|
||||||
|
URL https://github.com/curl/curl/releases/download/curl-8_5_0/curl-8.5.0.tar.gz
|
||||||
|
URL_HASH SHA256=05fc17ff25b793a437a0906e0484b82172a9f4de02be5ed447e0cab8c3475add
|
||||||
|
)
|
||||||
|
set(BUILD_CURL_EXE OFF CACHE BOOL "" FORCE)
|
||||||
|
set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE)
|
||||||
|
set(CURL_STATICLIB ON CACHE BOOL "" FORCE)
|
||||||
|
set(BUILD_TESTING OFF CACHE BOOL "" FORCE)
|
||||||
|
set(CURL_DISABLE_LDAP ON CACHE BOOL "" FORCE)
|
||||||
|
set(CURL_DISABLE_LDAPS ON CACHE BOOL "" FORCE)
|
||||||
|
set(CURL_USE_SCHANNEL ON CACHE BOOL "" FORCE) # Use Windows native SSL
|
||||||
|
set(CURL_USE_OPENSSL OFF CACHE BOOL "" FORCE)
|
||||||
|
set(CURL_USE_LIBSSH2 OFF CACHE BOOL "" FORCE)
|
||||||
|
set(CURL_ZLIB OFF CACHE BOOL "" FORCE)
|
||||||
|
set(HTTP_ONLY ON CACHE BOOL "" FORCE)
|
||||||
|
FetchContent_MakeAvailable(curl)
|
||||||
|
set(CURL_LIBRARIES libcurl_static)
|
||||||
|
set(CURL_INCLUDE_DIRS ${curl_SOURCE_DIR}/include ${curl_BINARY_DIR}/lib/curl)
|
||||||
|
else()
|
||||||
|
find_package(CURL REQUIRED)
|
||||||
|
set(CURL_LIBRARIES CURL::libcurl)
|
||||||
|
set(CURL_INCLUDE_DIRS ${CURL_INCLUDE_DIR})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# libsodium - platform-specific
|
||||||
|
# Search order per platform:
|
||||||
|
# 1. Local pre-built in libs/libsodium{-mac,-win}/ (downloaded by scripts/fetch-libsodium.sh)
|
||||||
|
# 2. System libsodium via pkg-config
|
||||||
|
# 3. Auto-download from source (requires curl + C compiler for target)
|
||||||
|
set(SODIUM_LIBRARY "")
|
||||||
|
set(SODIUM_INCLUDE_DIR "")
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
# Windows (MinGW cross-compile) — no pkg-config fallback; host pkg-config
|
||||||
|
# returns Linux paths that can't be used by MinGW.
|
||||||
|
if(EXISTS ${CMAKE_SOURCE_DIR}/libs/libsodium-win/lib/libsodium.a)
|
||||||
|
set(SODIUM_LIBRARY ${CMAKE_SOURCE_DIR}/libs/libsodium-win/lib/libsodium.a)
|
||||||
|
set(SODIUM_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/libs/libsodium-win/include)
|
||||||
|
elseif(EXISTS ${CMAKE_SOURCE_DIR}/libs/libsodium/lib/libsodium.a)
|
||||||
|
set(SODIUM_LIBRARY ${CMAKE_SOURCE_DIR}/libs/libsodium/lib/libsodium.a)
|
||||||
|
set(SODIUM_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/libs/libsodium/include)
|
||||||
|
endif()
|
||||||
|
elseif(APPLE)
|
||||||
|
# macOS (native or osxcross cross-compile) — use local pre-built only;
|
||||||
|
# when cross-compiling, host pkg-config returns wrong paths.
|
||||||
|
if(EXISTS ${CMAKE_SOURCE_DIR}/libs/libsodium-mac/lib/libsodium.a)
|
||||||
|
set(SODIUM_LIBRARY ${CMAKE_SOURCE_DIR}/libs/libsodium-mac/lib/libsodium.a)
|
||||||
|
set(SODIUM_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/libs/libsodium-mac/include)
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
# Linux: prefer system libsodium, fall back to local build
|
||||||
|
find_package(PkgConfig QUIET)
|
||||||
|
if(PKG_CONFIG_FOUND)
|
||||||
|
pkg_check_modules(SODIUM QUIET libsodium)
|
||||||
|
endif()
|
||||||
|
if(NOT SODIUM_FOUND AND EXISTS ${CMAKE_SOURCE_DIR}/libs/libsodium/lib/libsodium.a)
|
||||||
|
set(SODIUM_LIBRARY ${CMAKE_SOURCE_DIR}/libs/libsodium/lib/libsodium.a)
|
||||||
|
set(SODIUM_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/libs/libsodium/include)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Bridge pkg-config variables to the ones used in target_link/include
|
||||||
|
if(SODIUM_FOUND AND NOT SODIUM_LIBRARY)
|
||||||
|
set(SODIUM_LIBRARY ${SODIUM_LIBRARIES})
|
||||||
|
set(SODIUM_INCLUDE_DIR ${SODIUM_INCLUDE_DIRS})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Final check: if still not found, tell the user how to get it
|
||||||
|
if(NOT SODIUM_LIBRARY AND NOT SODIUM_FOUND)
|
||||||
|
message(WARNING
|
||||||
|
"libsodium not found. Encryption features require libsodium.\n"
|
||||||
|
" Linux: sudo apt install libsodium-dev (or equivalent)\n"
|
||||||
|
" macOS: ./scripts/fetch-libsodium.sh --mac\n"
|
||||||
|
" Windows: ./scripts/fetch-libsodium.sh --win")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
message(STATUS "Sodium lib: ${SODIUM_LIBRARY}")
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# ImGui
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
set(IMGUI_DIR ${CMAKE_SOURCE_DIR}/libs/imgui)
|
||||||
|
|
||||||
|
set(IMGUI_SOURCES
|
||||||
|
${IMGUI_DIR}/imgui.cpp
|
||||||
|
${IMGUI_DIR}/imgui_draw.cpp
|
||||||
|
${IMGUI_DIR}/imgui_tables.cpp
|
||||||
|
${IMGUI_DIR}/imgui_widgets.cpp
|
||||||
|
${IMGUI_DIR}/imgui_demo.cpp
|
||||||
|
${IMGUI_DIR}/backends/imgui_impl_sdl3.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
set(IMGUI_HEADERS
|
||||||
|
${IMGUI_DIR}/imgui.h
|
||||||
|
${IMGUI_DIR}/imconfig.h
|
||||||
|
${IMGUI_DIR}/imgui_internal.h
|
||||||
|
${IMGUI_DIR}/backends/imgui_impl_sdl3.h
|
||||||
|
)
|
||||||
|
|
||||||
|
# Platform-specific ImGui backend
|
||||||
|
if(WIN32)
|
||||||
|
list(APPEND IMGUI_SOURCES ${IMGUI_DIR}/backends/imgui_impl_dx11.cpp)
|
||||||
|
list(APPEND IMGUI_HEADERS ${IMGUI_DIR}/backends/imgui_impl_dx11.h)
|
||||||
|
else()
|
||||||
|
list(APPEND IMGUI_SOURCES ${IMGUI_DIR}/backends/imgui_impl_opengl3.cpp)
|
||||||
|
list(APPEND IMGUI_HEADERS ${IMGUI_DIR}/backends/imgui_impl_opengl3.h)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# QR Code library (bundled)
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
set(QRCODE_DIR ${CMAKE_SOURCE_DIR}/libs/qrcode)
|
||||||
|
|
||||||
|
set(QRCODE_SOURCES
|
||||||
|
${QRCODE_DIR}/BitBuffer.cpp
|
||||||
|
${QRCODE_DIR}/QrCode.cpp
|
||||||
|
${QRCODE_DIR}/QrSegment.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Application Sources
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
set(APP_SOURCES
|
||||||
|
src/main.cpp
|
||||||
|
src/app.cpp
|
||||||
|
src/app_network.cpp
|
||||||
|
src/app_security.cpp
|
||||||
|
src/app_wizard.cpp
|
||||||
|
src/data/wallet_state.cpp
|
||||||
|
src/ui/theme.cpp
|
||||||
|
src/ui/theme_loader.cpp
|
||||||
|
src/ui/material/color_theme.cpp
|
||||||
|
src/ui/material/typography.cpp
|
||||||
|
src/ui/notifications.cpp
|
||||||
|
src/ui/windows/main_window.cpp
|
||||||
|
src/ui/windows/balance_tab.cpp
|
||||||
|
src/ui/windows/send_tab.cpp
|
||||||
|
src/ui/windows/receive_tab.cpp
|
||||||
|
src/ui/windows/transactions_tab.cpp
|
||||||
|
src/ui/windows/mining_tab.cpp
|
||||||
|
src/ui/windows/peers_tab.cpp
|
||||||
|
src/ui/windows/market_tab.cpp
|
||||||
|
src/ui/windows/console_tab.cpp
|
||||||
|
src/ui/windows/settings_window.cpp
|
||||||
|
src/ui/pages/settings_page.cpp
|
||||||
|
src/ui/windows/about_dialog.cpp
|
||||||
|
src/ui/windows/key_export_dialog.cpp
|
||||||
|
src/ui/windows/transaction_details_dialog.cpp
|
||||||
|
src/ui/windows/qr_popup_dialog.cpp
|
||||||
|
src/ui/windows/validate_address_dialog.cpp
|
||||||
|
src/ui/windows/address_book_dialog.cpp
|
||||||
|
src/ui/windows/shield_dialog.cpp
|
||||||
|
src/ui/windows/request_payment_dialog.cpp
|
||||||
|
src/ui/windows/block_info_dialog.cpp
|
||||||
|
src/ui/windows/import_key_dialog.cpp
|
||||||
|
src/ui/windows/export_all_keys_dialog.cpp
|
||||||
|
src/ui/windows/export_transactions_dialog.cpp
|
||||||
|
src/ui/windows/backup_wallet_dialog.cpp
|
||||||
|
src/ui/widgets/qr_code.cpp
|
||||||
|
src/rpc/rpc_client.cpp
|
||||||
|
src/rpc/rpc_worker.cpp
|
||||||
|
src/rpc/connection.cpp
|
||||||
|
src/config/settings.cpp
|
||||||
|
src/data/address_book.cpp
|
||||||
|
src/data/exchange_info.cpp
|
||||||
|
src/util/logger.cpp
|
||||||
|
src/util/base64.cpp
|
||||||
|
src/util/single_instance.cpp
|
||||||
|
src/util/i18n.cpp
|
||||||
|
src/util/platform.cpp
|
||||||
|
src/util/payment_uri.cpp
|
||||||
|
src/util/texture_loader.cpp
|
||||||
|
src/util/noise_texture.cpp
|
||||||
|
src/daemon/embedded_daemon.cpp
|
||||||
|
src/daemon/xmrig_manager.cpp
|
||||||
|
src/util/bootstrap.cpp
|
||||||
|
src/util/secure_vault.cpp
|
||||||
|
src/ui/effects/framebuffer.cpp
|
||||||
|
src/ui/effects/blur_shader.cpp
|
||||||
|
src/ui/effects/noise_texture.cpp
|
||||||
|
src/ui/effects/acrylic.cpp
|
||||||
|
src/ui/effects/imgui_acrylic.cpp
|
||||||
|
src/ui/effects/theme_effects.cpp
|
||||||
|
src/ui/effects/low_spec.cpp
|
||||||
|
src/ui/schema/color_var_resolver.cpp
|
||||||
|
src/ui/schema/element_styles.cpp
|
||||||
|
src/ui/schema/ui_schema.cpp
|
||||||
|
src/ui/schema/skin_manager.cpp
|
||||||
|
src/resources/embedded_resources.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
# Note: The old -O0 workaround for embedded_resources.cpp is no longer needed.
|
||||||
|
# With INCBIN (.incbin assembler directive), the compiler never parses the
|
||||||
|
# binary data — the assembler streams it directly into the object file,
|
||||||
|
# using near-zero compile-time RAM instead of 12 GB+.
|
||||||
|
|
||||||
|
# Platform-specific sources
|
||||||
|
if(WIN32)
|
||||||
|
list(APPEND APP_SOURCES
|
||||||
|
src/platform/windows_backdrop.cpp
|
||||||
|
src/platform/dx11_context.cpp
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(APP_HEADERS
|
||||||
|
src/app.h
|
||||||
|
src/config/version.h
|
||||||
|
src/data/wallet_state.h
|
||||||
|
src/ui/theme.h
|
||||||
|
src/ui/theme_loader.h
|
||||||
|
src/ui/notifications.h
|
||||||
|
src/ui/windows/main_window.h
|
||||||
|
src/ui/windows/balance_tab.h
|
||||||
|
src/ui/windows/send_tab.h
|
||||||
|
src/ui/windows/receive_tab.h
|
||||||
|
src/ui/windows/transactions_tab.h
|
||||||
|
src/ui/windows/mining_tab.h
|
||||||
|
src/ui/windows/peers_tab.h
|
||||||
|
src/ui/windows/market_tab.h
|
||||||
|
src/ui/windows/settings_window.h
|
||||||
|
src/ui/windows/about_dialog.h
|
||||||
|
src/ui/windows/key_export_dialog.h
|
||||||
|
src/ui/windows/transaction_details_dialog.h
|
||||||
|
src/ui/windows/qr_popup_dialog.h
|
||||||
|
src/ui/windows/validate_address_dialog.h
|
||||||
|
src/ui/windows/address_book_dialog.h
|
||||||
|
src/ui/windows/shield_dialog.h
|
||||||
|
src/ui/windows/request_payment_dialog.h
|
||||||
|
src/ui/windows/block_info_dialog.h
|
||||||
|
src/ui/windows/import_key_dialog.h
|
||||||
|
src/ui/windows/export_all_keys_dialog.h
|
||||||
|
src/ui/windows/export_transactions_dialog.h
|
||||||
|
src/ui/windows/backup_wallet_dialog.h
|
||||||
|
src/ui/widgets/qr_code.h
|
||||||
|
src/rpc/rpc_client.h
|
||||||
|
src/rpc/rpc_worker.h
|
||||||
|
src/rpc/connection.h
|
||||||
|
src/rpc/types.h
|
||||||
|
src/config/settings.h
|
||||||
|
src/data/address_book.h
|
||||||
|
src/data/exchange_info.h
|
||||||
|
src/util/logger.h
|
||||||
|
src/util/base64.h
|
||||||
|
src/util/single_instance.h
|
||||||
|
src/util/i18n.h
|
||||||
|
src/util/platform.h
|
||||||
|
src/util/payment_uri.h
|
||||||
|
src/util/secure_vault.h
|
||||||
|
src/daemon/embedded_daemon.h
|
||||||
|
src/daemon/xmrig_manager.h
|
||||||
|
src/ui/effects/framebuffer.h
|
||||||
|
src/ui/effects/blur_shader.h
|
||||||
|
src/ui/effects/noise_texture.h
|
||||||
|
src/ui/effects/acrylic.h
|
||||||
|
)
|
||||||
|
|
||||||
|
# Platform-specific headers
|
||||||
|
if(WIN32)
|
||||||
|
list(APPEND APP_HEADERS
|
||||||
|
src/platform/windows_backdrop.h
|
||||||
|
src/platform/dx11_context.h
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Executable
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Windows application icon + VERSIONINFO (.rc -> .res -> linked into .exe)
|
||||||
|
if(WIN32)
|
||||||
|
set(OBSIDIAN_ICO_PATH "${CMAKE_SOURCE_DIR}/res/img/ObsidianDragon.ico")
|
||||||
|
# Version numbers for the VERSIONINFO resource block
|
||||||
|
set(DRAGONX_VER_MAJOR 1)
|
||||||
|
set(DRAGONX_VER_MINOR 0)
|
||||||
|
set(DRAGONX_VER_PATCH 0)
|
||||||
|
set(DRAGONX_VERSION "1.0.0")
|
||||||
|
configure_file(
|
||||||
|
${CMAKE_SOURCE_DIR}/res/ObsidianDragon.rc
|
||||||
|
${CMAKE_BINARY_DIR}/generated/ObsidianDragon.rc
|
||||||
|
@ONLY
|
||||||
|
)
|
||||||
|
set(WIN_RC_FILE ${CMAKE_BINARY_DIR}/generated/ObsidianDragon.rc)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Generate INCBIN font embedding source with absolute paths to .ttf files
|
||||||
|
configure_file(
|
||||||
|
${CMAKE_SOURCE_DIR}/src/embedded/embedded_fonts.cpp.in
|
||||||
|
${CMAKE_BINARY_DIR}/generated/embedded_fonts.cpp
|
||||||
|
@ONLY
|
||||||
|
)
|
||||||
|
|
||||||
|
add_executable(ObsidianDragon
|
||||||
|
${APP_SOURCES}
|
||||||
|
${CMAKE_BINARY_DIR}/generated/embedded_fonts.cpp
|
||||||
|
${IMGUI_SOURCES}
|
||||||
|
${QRCODE_SOURCES}
|
||||||
|
${GLAD_SOURCES}
|
||||||
|
${MINIZ_SOURCES}
|
||||||
|
${WIN_RC_FILE}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(ObsidianDragon PRIVATE
|
||||||
|
${CMAKE_SOURCE_DIR}/src
|
||||||
|
${CMAKE_SOURCE_DIR}/src/embedded
|
||||||
|
${CMAKE_SOURCE_DIR}/src/resources
|
||||||
|
${CMAKE_SOURCE_DIR}/libs
|
||||||
|
${CMAKE_BINARY_DIR}/generated
|
||||||
|
${IMGUI_DIR}
|
||||||
|
${IMGUI_DIR}/backends
|
||||||
|
${QRCODE_DIR}
|
||||||
|
${SODIUM_INCLUDE_DIR}
|
||||||
|
${GLAD_INCLUDE}
|
||||||
|
${CURL_INCLUDE_DIRS}
|
||||||
|
${MINIZ_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(ObsidianDragon PRIVATE
|
||||||
|
SDL3::SDL3
|
||||||
|
nlohmann_json::nlohmann_json
|
||||||
|
tomlplusplus::tomlplusplus
|
||||||
|
${CURL_LIBRARIES}
|
||||||
|
${SODIUM_LIBRARY}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Platform-specific settings
|
||||||
|
if(WIN32)
|
||||||
|
target_link_libraries(ObsidianDragon PRIVATE ws2_32 winmm imm32 version setupapi dwmapi crypt32 wldap32 psapi d3d11 dxgi d3dcompiler dcomp)
|
||||||
|
# Hide console window in release builds
|
||||||
|
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||||
|
set_target_properties(ObsidianDragon PROPERTIES WIN32_EXECUTABLE TRUE)
|
||||||
|
endif()
|
||||||
|
elseif(APPLE)
|
||||||
|
target_link_libraries(ObsidianDragon PRIVATE "-framework Cocoa" "-framework IOKit" "-framework CoreVideo" "-framework OpenGL")
|
||||||
|
# When cross-compiling with osxcross, link the compiler-rt builtins (provides ___isPlatformVersionAtLeast etc.)
|
||||||
|
if(CMAKE_CROSSCOMPILING AND DEFINED OSXCROSS_COMPILER_RT)
|
||||||
|
target_link_libraries(ObsidianDragon PRIVATE "${OSXCROSS_COMPILER_RT}")
|
||||||
|
endif()
|
||||||
|
elseif(UNIX)
|
||||||
|
find_package(Threads REQUIRED)
|
||||||
|
target_link_libraries(ObsidianDragon PRIVATE OpenGL::GL Threads::Threads ${CMAKE_DL_LIBS})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Compiler warnings
|
||||||
|
if(MSVC)
|
||||||
|
target_compile_options(ObsidianDragon PRIVATE /W4)
|
||||||
|
else()
|
||||||
|
target_compile_options(ObsidianDragon PRIVATE -Wall -Wextra -Wpedantic)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Compile definitions
|
||||||
|
target_compile_definitions(ObsidianDragon PRIVATE
|
||||||
|
$<$<CONFIG:Debug>:DRAGONX_DEBUG>
|
||||||
|
)
|
||||||
|
if(WIN32)
|
||||||
|
target_compile_definitions(ObsidianDragon PRIVATE DRAGONX_USE_DX11)
|
||||||
|
else()
|
||||||
|
target_compile_definitions(ObsidianDragon PRIVATE DRAGONX_HAS_GLAD)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Copy resources
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Copy font file - try local first, then SilentDragonX
|
||||||
|
if(EXISTS ${CMAKE_SOURCE_DIR}/res/fonts/Ubuntu-R.ttf)
|
||||||
|
configure_file(
|
||||||
|
${CMAKE_SOURCE_DIR}/res/fonts/Ubuntu-R.ttf
|
||||||
|
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/res/fonts/Ubuntu-R.ttf
|
||||||
|
COPYONLY
|
||||||
|
)
|
||||||
|
elseif(EXISTS ${CMAKE_SOURCE_DIR}/../SilentDragonX/res/Ubuntu-R.ttf)
|
||||||
|
configure_file(
|
||||||
|
${CMAKE_SOURCE_DIR}/../SilentDragonX/res/Ubuntu-R.ttf
|
||||||
|
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/res/fonts/Ubuntu-R.ttf
|
||||||
|
COPYONLY
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Copy language files
|
||||||
|
file(GLOB LANG_FILES ${CMAKE_SOURCE_DIR}/res/lang/*.json)
|
||||||
|
if(LANG_FILES)
|
||||||
|
foreach(LANG_FILE ${LANG_FILES})
|
||||||
|
get_filename_component(LANG_FILENAME ${LANG_FILE} NAME)
|
||||||
|
configure_file(
|
||||||
|
${LANG_FILE}
|
||||||
|
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/res/lang/${LANG_FILENAME}
|
||||||
|
COPYONLY
|
||||||
|
)
|
||||||
|
endforeach()
|
||||||
|
message(STATUS " Language files: ${LANG_FILES}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Embed ui.toml into the binary so it's always available at runtime
|
||||||
|
include(${CMAKE_SOURCE_DIR}/cmake/EmbedResources.cmake)
|
||||||
|
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/generated)
|
||||||
|
embed_resource(
|
||||||
|
${CMAKE_SOURCE_DIR}/res/themes/ui.toml
|
||||||
|
${CMAKE_BINARY_DIR}/generated/ui_toml_embedded.h
|
||||||
|
ui_toml
|
||||||
|
)
|
||||||
|
|
||||||
|
# Note: xmrig is embedded via build.sh (embedded_data.h) for Windows builds,
|
||||||
|
# following the same pattern as daemon embedding.
|
||||||
|
|
||||||
|
# Copy theme files at BUILD time (not just cmake configure time)
|
||||||
|
# so edits to res/themes/*.toml are picked up by 'make' without re-running cmake.
|
||||||
|
file(GLOB THEME_FILES ${CMAKE_SOURCE_DIR}/res/themes/*.toml)
|
||||||
|
if(THEME_FILES)
|
||||||
|
foreach(THEME_FILE ${THEME_FILES})
|
||||||
|
get_filename_component(THEME_FILENAME ${THEME_FILE} NAME)
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/res/themes/${THEME_FILENAME}
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||||
|
${THEME_FILE}
|
||||||
|
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/res/themes/${THEME_FILENAME}
|
||||||
|
DEPENDS ${THEME_FILE}
|
||||||
|
COMMENT "Copying ${THEME_FILENAME}"
|
||||||
|
)
|
||||||
|
list(APPEND THEME_OUTPUTS ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/res/themes/${THEME_FILENAME})
|
||||||
|
endforeach()
|
||||||
|
add_custom_target(copy_themes ALL DEPENDS ${THEME_OUTPUTS})
|
||||||
|
add_dependencies(ObsidianDragon copy_themes)
|
||||||
|
message(STATUS " Theme files: ${THEME_FILES}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Copy image files (including backgrounds/ subdirectories and logos/)
|
||||||
|
file(GLOB IMG_ROOT_FILES ${CMAKE_SOURCE_DIR}/res/img/*.png ${CMAKE_SOURCE_DIR}/res/img/*.jpg ${CMAKE_SOURCE_DIR}/res/img/*.ico)
|
||||||
|
file(GLOB IMG_BG_TEXTURE_FILES ${CMAKE_SOURCE_DIR}/res/img/backgrounds/texture/*.png ${CMAKE_SOURCE_DIR}/res/img/backgrounds/texture/*.jpg)
|
||||||
|
file(GLOB IMG_BG_GRADIENT_FILES ${CMAKE_SOURCE_DIR}/res/img/backgrounds/gradient/*.png ${CMAKE_SOURCE_DIR}/res/img/backgrounds/gradient/*.jpg)
|
||||||
|
file(GLOB IMG_LOGO_FILES ${CMAKE_SOURCE_DIR}/res/img/logos/*.png ${CMAKE_SOURCE_DIR}/res/img/logos/*.jpg)
|
||||||
|
foreach(IMG_FILE ${IMG_ROOT_FILES})
|
||||||
|
get_filename_component(IMG_FILENAME ${IMG_FILE} NAME)
|
||||||
|
configure_file(${IMG_FILE} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/res/img/${IMG_FILENAME} COPYONLY)
|
||||||
|
endforeach()
|
||||||
|
foreach(IMG_FILE ${IMG_BG_TEXTURE_FILES})
|
||||||
|
get_filename_component(IMG_FILENAME ${IMG_FILE} NAME)
|
||||||
|
configure_file(${IMG_FILE} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/res/img/backgrounds/texture/${IMG_FILENAME} COPYONLY)
|
||||||
|
endforeach()
|
||||||
|
foreach(IMG_FILE ${IMG_BG_GRADIENT_FILES})
|
||||||
|
get_filename_component(IMG_FILENAME ${IMG_FILE} NAME)
|
||||||
|
configure_file(${IMG_FILE} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/res/img/backgrounds/gradient/${IMG_FILENAME} COPYONLY)
|
||||||
|
endforeach()
|
||||||
|
foreach(IMG_FILE ${IMG_LOGO_FILES})
|
||||||
|
get_filename_component(IMG_FILENAME ${IMG_FILE} NAME)
|
||||||
|
configure_file(${IMG_FILE} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/res/img/logos/${IMG_FILENAME} COPYONLY)
|
||||||
|
endforeach()
|
||||||
|
message(STATUS " Image files: ${IMG_ROOT_FILES} ${IMG_BG_TEXTURE_FILES} ${IMG_BG_GRADIENT_FILES} ${IMG_LOGO_FILES}")
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Install
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
install(TARGETS ObsidianDragon
|
||||||
|
RUNTIME DESTINATION bin
|
||||||
|
)
|
||||||
|
|
||||||
|
install(DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/res
|
||||||
|
DESTINATION share/ObsidianDragon
|
||||||
|
OPTIONAL
|
||||||
|
)
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Summary
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
message(STATUS "")
|
||||||
|
message(STATUS "DragonX ImGui Wallet Configuration:")
|
||||||
|
message(STATUS " Version: ${PROJECT_VERSION}")
|
||||||
|
message(STATUS " Build type: ${CMAKE_BUILD_TYPE}")
|
||||||
|
message(STATUS " C++ Standard: ${CMAKE_CXX_STANDARD}")
|
||||||
|
message(STATUS " ImGui dir: ${IMGUI_DIR}")
|
||||||
|
message(STATUS " SDL3 found: ${SDL3_FOUND}")
|
||||||
|
message(STATUS " Sodium lib: ${SODIUM_LIBRARY}")
|
||||||
|
message(STATUS "")
|
||||||
39
CODE_OF_CONDUCT.md
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
# Code of Conduct
|
||||||
|
|
||||||
|
## Our Pledge
|
||||||
|
|
||||||
|
We are committed to making participation in this project a welcoming experience for everyone, regardless of background or identity.
|
||||||
|
|
||||||
|
## Our Standards
|
||||||
|
|
||||||
|
**Positive behaviour includes:**
|
||||||
|
|
||||||
|
- Being respectful and constructive in discussions
|
||||||
|
- Accepting feedback gracefully
|
||||||
|
- Focusing on what is best for the project and community
|
||||||
|
- Showing empathy towards other community members
|
||||||
|
|
||||||
|
**Unacceptable behaviour includes:**
|
||||||
|
|
||||||
|
- Harassment, insults, or derogatory comments
|
||||||
|
- Personal or political attacks
|
||||||
|
- Publishing others' private information without consent
|
||||||
|
- Other conduct which could reasonably be considered inappropriate
|
||||||
|
|
||||||
|
## Enforcement
|
||||||
|
|
||||||
|
Project maintainers are responsible for clarifying standards and will take appropriate corrective action in response to unacceptable behaviour.
|
||||||
|
|
||||||
|
Maintainers have the right to remove, edit, or reject comments, commits, issues, and other contributions that violate this Code of Conduct.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
This Code of Conduct applies within all project spaces — issues, pull requests, discussions, and community channels.
|
||||||
|
|
||||||
|
## Reporting
|
||||||
|
|
||||||
|
Instances of unacceptable behaviour may be reported to the project maintainers. All complaints will be reviewed and responded to appropriately.
|
||||||
|
|
||||||
|
## Attribution
|
||||||
|
|
||||||
|
This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org/), version 2.1.
|
||||||
76
CONTRIBUTING.md
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
# Contributing to ObsidianDragon
|
||||||
|
|
||||||
|
Thank you for your interest in contributing! This guide will help you get started.
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
1. Fork the repository
|
||||||
|
2. Clone your fork and create a branch:
|
||||||
|
```bash
|
||||||
|
git clone https://git.hush.is/<your-username>/ObsidianDragon.git
|
||||||
|
cd ObsidianDragon
|
||||||
|
git checkout -b my-feature
|
||||||
|
```
|
||||||
|
3. Install dependencies:
|
||||||
|
```bash
|
||||||
|
./scripts/setup.sh
|
||||||
|
```
|
||||||
|
4. Build:
|
||||||
|
```bash
|
||||||
|
./build.sh --linux-release # or --win-release, --mac-release
|
||||||
|
```
|
||||||
|
|
||||||
|
## Development Workflow
|
||||||
|
|
||||||
|
### Code Style
|
||||||
|
|
||||||
|
- C++17 standard
|
||||||
|
- Use the Material Design icon font (`ICON_MD_*` defines) — never raw Unicode symbols
|
||||||
|
- UI layout values go in `res/themes/ui.toml`, read via `schema::UI()` — never hardcode pixel sizes
|
||||||
|
- Use the `RPCWorker` for all RPC calls — never block the main thread with synchronous curl
|
||||||
|
|
||||||
|
See `.github/copilot-instructions.md` for detailed coding standards.
|
||||||
|
|
||||||
|
### Building
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Linux debug build (fastest iteration)
|
||||||
|
cd build && make -j$(nproc)
|
||||||
|
|
||||||
|
# Full release builds
|
||||||
|
./build.sh --linux-release
|
||||||
|
./build.sh --win-release
|
||||||
|
./build.sh --mac-release
|
||||||
|
```
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
|
||||||
|
Run the wallet and verify:
|
||||||
|
- Daemon connection and sync
|
||||||
|
- Lock screen / PIN unlock
|
||||||
|
- Send and receive transactions
|
||||||
|
- All tabs render correctly
|
||||||
|
|
||||||
|
## Submitting Changes
|
||||||
|
|
||||||
|
1. Commit with clear, descriptive messages
|
||||||
|
2. Push to your fork
|
||||||
|
3. Open a Pull Request against `main`
|
||||||
|
4. Describe what changed and why
|
||||||
|
|
||||||
|
### Pull Request Guidelines
|
||||||
|
|
||||||
|
- Keep PRs focused — one feature or fix per PR
|
||||||
|
- Ensure the project builds on Linux (`make -j$(nproc)`)
|
||||||
|
- Test cross-compilation if touching platform-specific code (`./build.sh --win-release`)
|
||||||
|
- Update `res/themes/ui.toml` if adding new UI layout values
|
||||||
|
|
||||||
|
## Reporting Issues
|
||||||
|
|
||||||
|
- Use the [issue tracker](https://git.hush.is/dragonx/ObsidianDragon/issues)
|
||||||
|
- Include: OS, wallet version, steps to reproduce, expected vs actual behaviour
|
||||||
|
- For crashes: include any terminal output
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
By contributing, you agree that your contributions will be licensed under the GPLv3.
|
||||||
674
LICENSE
Normal file
@@ -0,0 +1,674 @@
|
|||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 3, 29 June 2007
|
||||||
|
|
||||||
|
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The GNU General Public License is a free, copyleft license for
|
||||||
|
software and other kinds of works.
|
||||||
|
|
||||||
|
The licenses for most software and other practical works are designed
|
||||||
|
to take away your freedom to share and change the works. By contrast,
|
||||||
|
the GNU General Public License is intended to guarantee your freedom to
|
||||||
|
share and change all versions of a program--to make sure it remains free
|
||||||
|
software for all its users. We, the Free Software Foundation, use the
|
||||||
|
GNU General Public License for most of our software; it applies also to
|
||||||
|
any other work released this way by its authors. You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
them if you wish), that you receive source code or can get it if you
|
||||||
|
want it, that you can change the software or use pieces of it in new
|
||||||
|
free programs, and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to prevent others from denying you
|
||||||
|
these rights or asking you to surrender the rights. Therefore, you have
|
||||||
|
certain responsibilities if you distribute copies of the software, or if
|
||||||
|
you modify it: responsibilities to respect the freedom of others.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must pass on to the recipients the same
|
||||||
|
freedoms that you received. You must make sure that they, too, receive
|
||||||
|
or can get the source code. And you must show them these terms so they
|
||||||
|
know their rights.
|
||||||
|
|
||||||
|
Developers that use the GNU GPL protect your rights with two steps:
|
||||||
|
(1) assert copyright on the software, and (2) offer you this License
|
||||||
|
giving you legal permission to copy, distribute and/or modify it.
|
||||||
|
|
||||||
|
For the developers' and authors' protection, the GPL clearly explains
|
||||||
|
that there is no warranty for this free software. For both users' and
|
||||||
|
authors' sake, the GPL requires that modified versions be marked as
|
||||||
|
changed, so that their problems will not be attributed erroneously to
|
||||||
|
authors of previous versions.
|
||||||
|
|
||||||
|
Some devices are designed to deny users access to install or run
|
||||||
|
modified versions of the software inside them, although the manufacturer
|
||||||
|
can do so. This is fundamentally incompatible with the aim of
|
||||||
|
protecting users' freedom to change the software. The systematic
|
||||||
|
pattern of such abuse occurs in the area of products for individuals to
|
||||||
|
use, which is precisely where it is most unacceptable. Therefore, we
|
||||||
|
have designed this version of the GPL to prohibit the practice for those
|
||||||
|
products. If such problems arise substantially in other domains, we
|
||||||
|
stand ready to extend this provision to those domains in future versions
|
||||||
|
of the GPL, as needed to protect the freedom of users.
|
||||||
|
|
||||||
|
Finally, every program is threatened constantly by software patents.
|
||||||
|
States should not allow patents to restrict development and use of
|
||||||
|
software on general-purpose computers, but in those that do, we wish to
|
||||||
|
avoid the special danger that patents applied to a free program could
|
||||||
|
make it effectively proprietary. To prevent this, the GPL assures that
|
||||||
|
patents cannot be used to render the program non-free.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
0. Definitions.
|
||||||
|
|
||||||
|
"This License" refers to version 3 of the GNU General Public License.
|
||||||
|
|
||||||
|
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||||
|
works, such as semiconductor masks.
|
||||||
|
|
||||||
|
"The Program" refers to any copyrightable work licensed under this
|
||||||
|
License. Each licensee is addressed as "you". "Licensees" and
|
||||||
|
"recipients" may be individuals or organizations.
|
||||||
|
|
||||||
|
To "modify" a work means to copy from or adapt all or part of the work
|
||||||
|
in a fashion requiring copyright permission, other than the making of an
|
||||||
|
exact copy. The resulting work is called a "modified version" of the
|
||||||
|
earlier work or a work "based on" the earlier work.
|
||||||
|
|
||||||
|
A "covered work" means either the unmodified Program or a work based
|
||||||
|
on the Program.
|
||||||
|
|
||||||
|
To "propagate" a work means to do anything with it that, without
|
||||||
|
permission, would make you directly or secondarily liable for
|
||||||
|
infringement under applicable copyright law, except executing it on a
|
||||||
|
computer or modifying a private copy. Propagation includes copying,
|
||||||
|
distribution (with or without modification), making available to the
|
||||||
|
public, and in some countries other activities as well.
|
||||||
|
|
||||||
|
To "convey" a work means any kind of propagation that enables other
|
||||||
|
parties to make or receive copies. Mere interaction with a user through
|
||||||
|
a computer network, with no transfer of a copy, is not conveying.
|
||||||
|
|
||||||
|
An interactive user interface displays "Appropriate Legal Notices"
|
||||||
|
to the extent that it includes a convenient and prominently visible
|
||||||
|
feature that (1) displays an appropriate copyright notice, and (2)
|
||||||
|
tells the user that there is no warranty for the work (except to the
|
||||||
|
extent that warranties are provided), that licensees may convey the
|
||||||
|
work under this License, and how to view a copy of this License. If
|
||||||
|
the interface presents a list of user commands or options, such as a
|
||||||
|
menu, a prominent item in the list meets this criterion.
|
||||||
|
|
||||||
|
1. Source Code.
|
||||||
|
|
||||||
|
The "source code" for a work means the preferred form of the work
|
||||||
|
for making modifications to it. "Object code" means any non-source
|
||||||
|
form of a work.
|
||||||
|
|
||||||
|
A "Standard Interface" means an interface that either is an official
|
||||||
|
standard defined by a recognized standards body, or, in the case of
|
||||||
|
interfaces specified for a particular programming language, one that
|
||||||
|
is widely used among developers working in that language.
|
||||||
|
|
||||||
|
The "System Libraries" of an executable work include anything, other
|
||||||
|
than the work as a whole, that (a) is included in the normal form of
|
||||||
|
packaging a Major Component, but which is not part of that Major
|
||||||
|
Component, and (b) serves only to enable use of the work with that
|
||||||
|
Major Component, or to implement a Standard Interface for which an
|
||||||
|
implementation is available to the public in source code form. A
|
||||||
|
"Major Component", in this context, means a major essential component
|
||||||
|
(kernel, window system, and so on) of the specific operating system
|
||||||
|
(if any) on which the executable work runs, or a compiler used to
|
||||||
|
produce the work, or an object code interpreter used to run it.
|
||||||
|
|
||||||
|
The "Corresponding Source" for a work in object code form means all
|
||||||
|
the source code needed to generate, install, and (for an executable
|
||||||
|
work) run the object code and to modify the work, including scripts to
|
||||||
|
control those activities. However, it does not include the work's
|
||||||
|
System Libraries, or general-purpose tools or generally available free
|
||||||
|
programs which are used unmodified in performing those activities but
|
||||||
|
which are not part of the work. For example, Corresponding Source
|
||||||
|
includes interface definition files associated with source files for
|
||||||
|
the work, and the source code for shared libraries and dynamically
|
||||||
|
linked subprograms that the work is specifically designed to require,
|
||||||
|
such as by intimate data communication or control flow between those
|
||||||
|
subprograms and other parts of the work.
|
||||||
|
|
||||||
|
The Corresponding Source need not include anything that users
|
||||||
|
can regenerate automatically from other parts of the Corresponding
|
||||||
|
Source.
|
||||||
|
|
||||||
|
The Corresponding Source for a work in source code form is that
|
||||||
|
same work.
|
||||||
|
|
||||||
|
2. Basic Permissions.
|
||||||
|
|
||||||
|
All rights granted under this License are granted for the term of
|
||||||
|
copyright on the Program, and are irrevocable provided the stated
|
||||||
|
conditions are met. This License explicitly affirms your unlimited
|
||||||
|
permission to run the unmodified Program. The output from running a
|
||||||
|
covered work is covered by this License only if the output, given its
|
||||||
|
content, constitutes a covered work. This License acknowledges your
|
||||||
|
rights of fair use or other equivalent, as provided by copyright law.
|
||||||
|
|
||||||
|
You may make, run and propagate covered works that you do not
|
||||||
|
convey, without conditions so long as your license otherwise remains
|
||||||
|
in force. You may convey covered works to others for the sole purpose
|
||||||
|
of having them make modifications exclusively for you, or provide you
|
||||||
|
with facilities for running those works, provided that you comply with
|
||||||
|
the terms of this License in conveying all material for which you do
|
||||||
|
not control copyright. Those thus making or running the covered works
|
||||||
|
for you must do so exclusively on your behalf, under your direction
|
||||||
|
and control, on terms that prohibit them from making any copies of
|
||||||
|
your copyrighted material outside their relationship with you.
|
||||||
|
|
||||||
|
Conveying under any other circumstances is permitted solely under
|
||||||
|
the conditions stated below. Sublicensing is not allowed; section 10
|
||||||
|
makes it unnecessary.
|
||||||
|
|
||||||
|
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||||
|
|
||||||
|
No covered work shall be deemed part of an effective technological
|
||||||
|
measure under any applicable law fulfilling obligations under article
|
||||||
|
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||||
|
similar laws prohibiting or restricting circumvention of such
|
||||||
|
measures.
|
||||||
|
|
||||||
|
When you convey a covered work, you waive any legal power to forbid
|
||||||
|
circumvention of technological measures to the extent such circumvention
|
||||||
|
is effected by exercising rights under this License with respect to
|
||||||
|
the covered work, and you disclaim any intention to limit operation or
|
||||||
|
modification of the work as a means of enforcing, against the work's
|
||||||
|
users, your or third parties' legal rights to forbid circumvention of
|
||||||
|
technological measures.
|
||||||
|
|
||||||
|
4. Conveying Verbatim Copies.
|
||||||
|
|
||||||
|
You may convey verbatim copies of the Program's source code as you
|
||||||
|
receive it, in any medium, provided that you conspicuously and
|
||||||
|
appropriately publish on each copy an appropriate copyright notice;
|
||||||
|
keep intact all notices stating that this License and any
|
||||||
|
non-permissive terms added in accord with section 7 apply to the code;
|
||||||
|
keep intact all notices of the absence of any warranty; and give all
|
||||||
|
recipients a copy of this License along with the Program.
|
||||||
|
|
||||||
|
You may charge any price or no price for each copy that you convey,
|
||||||
|
and you may offer support or warranty protection for a fee.
|
||||||
|
|
||||||
|
5. Conveying Modified Source Versions.
|
||||||
|
|
||||||
|
You may convey a work based on the Program, or the modifications to
|
||||||
|
produce it from the Program, in the form of source code under the
|
||||||
|
terms of section 4, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The work must carry prominent notices stating that you modified
|
||||||
|
it, and giving a relevant date.
|
||||||
|
|
||||||
|
b) The work must carry prominent notices stating that it is
|
||||||
|
released under this License and any conditions added under section
|
||||||
|
7. This requirement modifies the requirement in section 4 to
|
||||||
|
"keep intact all notices".
|
||||||
|
|
||||||
|
c) You must license the entire work, as a whole, under this
|
||||||
|
License to anyone who comes into possession of a copy. This
|
||||||
|
License will therefore apply, along with any applicable section 7
|
||||||
|
additional terms, to the whole of the work, and all its parts,
|
||||||
|
regardless of how they are packaged. This License gives no
|
||||||
|
permission to license the work in any other way, but it does not
|
||||||
|
invalidate such permission if you have separately received it.
|
||||||
|
|
||||||
|
d) If the work has interactive user interfaces, each must display
|
||||||
|
Appropriate Legal Notices; however, if the Program has interactive
|
||||||
|
interfaces that do not display Appropriate Legal Notices, your
|
||||||
|
work need not make them do so.
|
||||||
|
|
||||||
|
A compilation of a covered work with other separate and independent
|
||||||
|
works, which are not by their nature extensions of the covered work,
|
||||||
|
and which are not combined with it such as to form a larger program,
|
||||||
|
in or on a volume of a storage or distribution medium, is called an
|
||||||
|
"aggregate" if the compilation and its resulting copyright are not
|
||||||
|
used to limit the access or legal rights of the compilation's users
|
||||||
|
beyond what the individual works permit. Inclusion of a covered work
|
||||||
|
in an aggregate does not cause this License to apply to the other
|
||||||
|
parts of the aggregate.
|
||||||
|
|
||||||
|
6. Conveying Non-Source Forms.
|
||||||
|
|
||||||
|
You may convey a covered work in object code form under the terms
|
||||||
|
of sections 4 and 5, provided that you also convey the
|
||||||
|
machine-readable Corresponding Source under the terms of this License,
|
||||||
|
in one of these ways:
|
||||||
|
|
||||||
|
a) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by the
|
||||||
|
Corresponding Source fixed on a durable physical medium
|
||||||
|
customarily used for software interchange.
|
||||||
|
|
||||||
|
b) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by a
|
||||||
|
written offer, valid for at least three years and valid for as
|
||||||
|
long as you offer spare parts or customer support for that product
|
||||||
|
model, to give anyone who possesses the object code either (1) a
|
||||||
|
copy of the Corresponding Source for all the software in the
|
||||||
|
product that is covered by this License, on a durable physical
|
||||||
|
medium customarily used for software interchange, for a price no
|
||||||
|
more than your reasonable cost of physically performing this
|
||||||
|
conveying of source, or (2) access to copy the
|
||||||
|
Corresponding Source from a network server at no charge.
|
||||||
|
|
||||||
|
c) Convey individual copies of the object code with a copy of the
|
||||||
|
written offer to provide the Corresponding Source. This
|
||||||
|
alternative is allowed only occasionally and noncommercially, and
|
||||||
|
only if you received the object code with such an offer, in accord
|
||||||
|
with subsection 6b.
|
||||||
|
|
||||||
|
d) Convey the object code by offering access from a designated
|
||||||
|
place (gratis or for a charge), and offer equivalent access to the
|
||||||
|
Corresponding Source in the same way through the same place at no
|
||||||
|
further charge. You need not require recipients to copy the
|
||||||
|
Corresponding Source along with the object code. If the place to
|
||||||
|
copy the object code is a network server, the Corresponding Source
|
||||||
|
may be on a different server (operated by you or a third party)
|
||||||
|
that supports equivalent copying facilities, provided you maintain
|
||||||
|
clear directions next to the object code saying where to find the
|
||||||
|
Corresponding Source. Regardless of what server hosts the
|
||||||
|
Corresponding Source, you remain obligated to ensure that it is
|
||||||
|
available for as long as needed to satisfy these requirements.
|
||||||
|
|
||||||
|
e) Convey the object code using peer-to-peer transmission, provided
|
||||||
|
you inform other peers where the object code and Corresponding
|
||||||
|
Source of the work are being offered to the general public at no
|
||||||
|
charge under subsection 6d.
|
||||||
|
|
||||||
|
A separable portion of the object code, whose source code is excluded
|
||||||
|
from the Corresponding Source as a System Library, need not be
|
||||||
|
included in conveying the object code work.
|
||||||
|
|
||||||
|
A "User Product" is either (1) a "consumer product", which means any
|
||||||
|
tangible personal property which is normally used for personal, family,
|
||||||
|
or household purposes, or (2) anything designed or sold for incorporation
|
||||||
|
into a dwelling. In determining whether a product is a consumer product,
|
||||||
|
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||||
|
product received by a particular user, "normally used" refers to a
|
||||||
|
typical or common use of that class of product, regardless of the status
|
||||||
|
of the particular user or of the way in which the particular user
|
||||||
|
actually uses, or expects or is expected to use, the product. A product
|
||||||
|
is a consumer product regardless of whether the product has substantial
|
||||||
|
commercial, industrial or non-consumer uses, unless such uses represent
|
||||||
|
the only significant mode of use of the product.
|
||||||
|
|
||||||
|
"Installation Information" for a User Product means any methods,
|
||||||
|
procedures, authorization keys, or other information required to install
|
||||||
|
and execute modified versions of a covered work in that User Product from
|
||||||
|
a modified version of its Corresponding Source. The information must
|
||||||
|
suffice to ensure that the continued functioning of the modified object
|
||||||
|
code is in no case prevented or interfered with solely because
|
||||||
|
modification has been made.
|
||||||
|
|
||||||
|
If you convey an object code work under this section in, or with, or
|
||||||
|
specifically for use in, a User Product, and the conveying occurs as
|
||||||
|
part of a transaction in which the right of possession and use of the
|
||||||
|
User Product is transferred to the recipient in perpetuity or for a
|
||||||
|
fixed term (regardless of how the transaction is characterized), the
|
||||||
|
Corresponding Source conveyed under this section must be accompanied
|
||||||
|
by the Installation Information. But this requirement does not apply
|
||||||
|
if neither you nor any third party retains the ability to install
|
||||||
|
modified object code on the User Product (for example, the work has
|
||||||
|
been installed in ROM).
|
||||||
|
|
||||||
|
The requirement to provide Installation Information does not include a
|
||||||
|
requirement to continue to provide support service, warranty, or updates
|
||||||
|
for a work that has been modified or installed by the recipient, or for
|
||||||
|
the User Product in which it has been modified or installed. Access to a
|
||||||
|
network may be denied when the modification itself materially and
|
||||||
|
adversely affects the operation of the network or violates the rules and
|
||||||
|
protocols for communication across the network.
|
||||||
|
|
||||||
|
Corresponding Source conveyed, and Installation Information provided,
|
||||||
|
in accord with this section must be in a format that is publicly
|
||||||
|
documented (and with an implementation available to the public in
|
||||||
|
source code form), and must require no special password or key for
|
||||||
|
unpacking, reading or copying.
|
||||||
|
|
||||||
|
7. Additional Terms.
|
||||||
|
|
||||||
|
"Additional permissions" are terms that supplement the terms of this
|
||||||
|
License by making exceptions from one or more of its conditions.
|
||||||
|
Additional permissions that are applicable to the entire Program shall
|
||||||
|
be treated as though they were included in this License, to the extent
|
||||||
|
that they are valid under applicable law. If additional permissions
|
||||||
|
apply only to part of the Program, that part may be used separately
|
||||||
|
under those permissions, but the entire Program remains governed by
|
||||||
|
this License without regard to the additional permissions.
|
||||||
|
|
||||||
|
When you convey a copy of a covered work, you may at your option
|
||||||
|
remove any additional permissions from that copy, or from any part of
|
||||||
|
it. (Additional permissions may be written to require their own
|
||||||
|
removal in certain cases when you modify the work.) You may place
|
||||||
|
additional permissions on material, added by you to a covered work,
|
||||||
|
for which you have or can give appropriate copyright permission.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, for material you
|
||||||
|
add to a covered work, you may (if authorized by the copyright holders of
|
||||||
|
that material) supplement the terms of this License with terms:
|
||||||
|
|
||||||
|
a) Disclaiming warranty or limiting liability differently from the
|
||||||
|
terms of sections 15 and 16 of this License; or
|
||||||
|
|
||||||
|
b) Requiring preservation of specified reasonable legal notices or
|
||||||
|
author attributions in that material or in the Appropriate Legal
|
||||||
|
Notices displayed by works containing it; or
|
||||||
|
|
||||||
|
c) Prohibiting misrepresentation of the origin of that material, or
|
||||||
|
requiring that modified versions of such material be marked in
|
||||||
|
reasonable ways as different from the original version; or
|
||||||
|
|
||||||
|
d) Limiting the use for publicity purposes of names of licensors or
|
||||||
|
authors of the material; or
|
||||||
|
|
||||||
|
e) Declining to grant rights under trademark law for use of some
|
||||||
|
trade names, trademarks, or service marks; or
|
||||||
|
|
||||||
|
f) Requiring indemnification of licensors and authors of that
|
||||||
|
material by anyone who conveys the material (or modified versions of
|
||||||
|
it) with contractual assumptions of liability to the recipient, for
|
||||||
|
any liability that these contractual assumptions directly impose on
|
||||||
|
those licensors and authors.
|
||||||
|
|
||||||
|
All other non-permissive additional terms are considered "further
|
||||||
|
restrictions" within the meaning of section 10. If the Program as you
|
||||||
|
received it, or any part of it, contains a notice stating that it is
|
||||||
|
governed by this License along with a term that is a further
|
||||||
|
restriction, you may remove that term. If a license document contains
|
||||||
|
a further restriction but permits relicensing or conveying under this
|
||||||
|
License, you may add to a covered work material governed by the terms
|
||||||
|
of that license document, provided that the further restriction does
|
||||||
|
not survive such relicensing or conveying.
|
||||||
|
|
||||||
|
If you add terms to a covered work in accord with this section, you
|
||||||
|
must place, in the relevant source files, a statement of the
|
||||||
|
additional terms that apply to those files, or a notice indicating
|
||||||
|
where to find the applicable terms.
|
||||||
|
|
||||||
|
Additional terms, permissive or non-permissive, may be stated in the
|
||||||
|
form of a separately written license, or stated as exceptions;
|
||||||
|
the above requirements apply either way.
|
||||||
|
|
||||||
|
8. Termination.
|
||||||
|
|
||||||
|
You may not propagate or modify a covered work except as expressly
|
||||||
|
provided under this License. Any attempt otherwise to propagate or
|
||||||
|
modify it is void, and will automatically terminate your rights under
|
||||||
|
this License (including any patent licenses granted under the third
|
||||||
|
paragraph of section 11).
|
||||||
|
|
||||||
|
However, if you cease all violation of this License, then your
|
||||||
|
license from a particular copyright holder is reinstated (a)
|
||||||
|
provisionally, unless and until the copyright holder explicitly and
|
||||||
|
finally terminates your license, and (b) permanently, if the copyright
|
||||||
|
holder fails to notify you of the violation by some reasonable means
|
||||||
|
prior to 60 days after the cessation.
|
||||||
|
|
||||||
|
Moreover, your license from a particular copyright holder is
|
||||||
|
reinstated permanently if the copyright holder notifies you of the
|
||||||
|
violation by some reasonable means, this is the first time you have
|
||||||
|
received notice of violation of this License (for any work) from that
|
||||||
|
copyright holder, and you cure the violation prior to 30 days after
|
||||||
|
your receipt of the notice.
|
||||||
|
|
||||||
|
Termination of your rights under this section does not terminate the
|
||||||
|
licenses of parties who have received copies or rights from you under
|
||||||
|
this License. If your rights have been terminated and not permanently
|
||||||
|
reinstated, you do not qualify to receive new licenses for the same
|
||||||
|
material under section 10.
|
||||||
|
|
||||||
|
9. Acceptance Not Required for Having Copies.
|
||||||
|
|
||||||
|
You are not required to accept this License in order to receive or
|
||||||
|
run a copy of the Program. Ancillary propagation of a covered work
|
||||||
|
occurring solely as a consequence of using peer-to-peer transmission
|
||||||
|
to receive a copy likewise does not require acceptance. However,
|
||||||
|
nothing other than this License grants you permission to propagate or
|
||||||
|
modify any covered work. These actions infringe copyright if you do
|
||||||
|
not accept this License. Therefore, by modifying or propagating a
|
||||||
|
covered work, you indicate your acceptance of this License to do so.
|
||||||
|
|
||||||
|
10. Automatic Licensing of Downstream Recipients.
|
||||||
|
|
||||||
|
Each time you convey a covered work, the recipient automatically
|
||||||
|
receives a license from the original licensors, to run, modify and
|
||||||
|
propagate that work, subject to this License. You are not responsible
|
||||||
|
for enforcing compliance by third parties with this License.
|
||||||
|
|
||||||
|
An "entity transaction" is a transaction transferring control of an
|
||||||
|
organization, or substantially all assets of one, or subdividing an
|
||||||
|
organization, or merging organizations. If propagation of a covered
|
||||||
|
work results from an entity transaction, each party to that
|
||||||
|
transaction who receives a copy of the work also receives whatever
|
||||||
|
licenses to the work the party's predecessor in interest had or could
|
||||||
|
give under the previous paragraph, plus a right to possession of the
|
||||||
|
Corresponding Source of the work from the predecessor in interest, if
|
||||||
|
the predecessor has it or can get it with reasonable efforts.
|
||||||
|
|
||||||
|
You may not impose any further restrictions on the exercise of the
|
||||||
|
rights granted or affirmed under this License. For example, you may
|
||||||
|
not impose a license fee, royalty, or other charge for exercise of
|
||||||
|
rights granted under this License, and you may not initiate litigation
|
||||||
|
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||||
|
any patent claim is infringed by making, using, selling, offering for
|
||||||
|
sale, or importing the Program or any portion of it.
|
||||||
|
|
||||||
|
11. Patents.
|
||||||
|
|
||||||
|
A "contributor" is a copyright holder who authorizes use under this
|
||||||
|
License of the Program or a work on which the Program is based. The
|
||||||
|
work thus licensed is called the contributor's "contributor version".
|
||||||
|
|
||||||
|
A contributor's "essential patent claims" are all patent claims
|
||||||
|
owned or controlled by the contributor, whether already acquired or
|
||||||
|
hereafter acquired, that would be infringed by some manner, permitted
|
||||||
|
by this License, of making, using, or selling its contributor version,
|
||||||
|
but do not include claims that would be infringed only as a
|
||||||
|
consequence of further modification of the contributor version. For
|
||||||
|
purposes of this definition, "control" includes the right to grant
|
||||||
|
patent sublicenses in a manner consistent with the requirements of
|
||||||
|
this License.
|
||||||
|
|
||||||
|
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||||
|
patent license under the contributor's essential patent claims, to
|
||||||
|
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||||
|
propagate the contents of its contributor version.
|
||||||
|
|
||||||
|
In the following three paragraphs, a "patent license" is any express
|
||||||
|
agreement or commitment, however denominated, not to enforce a patent
|
||||||
|
(such as an express permission to practice a patent or covenant not to
|
||||||
|
sue for patent infringement). To "grant" such a patent license to a
|
||||||
|
party means to make such an agreement or commitment not to enforce a
|
||||||
|
patent against the party.
|
||||||
|
|
||||||
|
If you convey a covered work, knowingly relying on a patent license,
|
||||||
|
and the Corresponding Source of the work is not available for anyone
|
||||||
|
to copy, free of charge and under the terms of this License, through a
|
||||||
|
publicly available network server or other readily accessible means,
|
||||||
|
then you must either (1) cause the Corresponding Source to be so
|
||||||
|
available, or (2) arrange to deprive yourself of the benefit of the
|
||||||
|
patent license for this particular work, or (3) arrange, in a manner
|
||||||
|
consistent with the requirements of this License, to extend the patent
|
||||||
|
license to downstream recipients. "Knowingly relying" means you have
|
||||||
|
actual knowledge that, but for the patent license, your conveying the
|
||||||
|
covered work in a country, or your recipient's use of the covered work
|
||||||
|
in a country, would infringe one or more identifiable patents in that
|
||||||
|
country that you have reason to believe are valid.
|
||||||
|
|
||||||
|
If, pursuant to or in connection with a single transaction or
|
||||||
|
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||||
|
covered work, and grant a patent license to some of the parties
|
||||||
|
receiving the covered work authorizing them to use, propagate, modify
|
||||||
|
or convey a specific copy of the covered work, then the patent license
|
||||||
|
you grant is automatically extended to all recipients of the covered
|
||||||
|
work and works based on it.
|
||||||
|
|
||||||
|
A patent license is "discriminatory" if it does not include within
|
||||||
|
the scope of its coverage, prohibits the exercise of, or is
|
||||||
|
conditioned on the non-exercise of one or more of the rights that are
|
||||||
|
specifically granted under this License. You may not convey a covered
|
||||||
|
work if you are a party to an arrangement with a third party that is
|
||||||
|
in the business of distributing software, under which you make payment
|
||||||
|
to the third party based on the extent of your activity of conveying
|
||||||
|
the work, and under which the third party grants, to any of the
|
||||||
|
parties who would receive the covered work from you, a discriminatory
|
||||||
|
patent license (a) in connection with copies of the covered work
|
||||||
|
conveyed by you (or copies made from those copies), or (b) primarily
|
||||||
|
for and in connection with specific products or compilations that
|
||||||
|
contain the covered work, unless you entered into that arrangement,
|
||||||
|
or that patent license was granted, prior to 28 March 2007.
|
||||||
|
|
||||||
|
Nothing in this License shall be construed as excluding or limiting
|
||||||
|
any implied license or other defenses to infringement that may
|
||||||
|
otherwise be available to you under applicable patent law.
|
||||||
|
|
||||||
|
12. No Surrender of Others' Freedom.
|
||||||
|
|
||||||
|
If conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot convey a
|
||||||
|
covered work so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you may
|
||||||
|
not convey it at all. For example, if you agree to terms that obligate you
|
||||||
|
to collect a royalty for further conveying from those to whom you convey
|
||||||
|
the Program, the only way you could satisfy both those terms and this
|
||||||
|
License would be to refrain entirely from conveying the Program.
|
||||||
|
|
||||||
|
13. Use with the GNU Affero General Public License.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, you have
|
||||||
|
permission to link or combine any covered work with a work licensed
|
||||||
|
under version 3 of the GNU Affero General Public License into a single
|
||||||
|
combined work, and to convey the resulting work. The terms of this
|
||||||
|
License will continue to apply to the part which is the covered work,
|
||||||
|
but the special requirements of the GNU Affero General Public License,
|
||||||
|
section 13, concerning interaction through a network will apply to the
|
||||||
|
combination as such.
|
||||||
|
|
||||||
|
14. Revised Versions of this License.
|
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions of
|
||||||
|
the GNU General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the
|
||||||
|
Program specifies that a certain numbered version of the GNU General
|
||||||
|
Public License "or any later version" applies to it, you have the
|
||||||
|
option of following the terms and conditions either of that numbered
|
||||||
|
version or of any later version published by the Free Software
|
||||||
|
Foundation. If the Program does not specify a version number of the
|
||||||
|
GNU General Public License, you may choose any version ever published
|
||||||
|
by the Free Software Foundation.
|
||||||
|
|
||||||
|
If the Program specifies that a proxy can decide which future
|
||||||
|
versions of the GNU General Public License can be used, that proxy's
|
||||||
|
public statement of acceptance of a version permanently authorizes you
|
||||||
|
to choose that version for the Program.
|
||||||
|
|
||||||
|
Later license versions may give you additional or different
|
||||||
|
permissions. However, no additional obligations are imposed on any
|
||||||
|
author or copyright holder as a result of your choosing to follow a
|
||||||
|
later version.
|
||||||
|
|
||||||
|
15. Disclaimer of Warranty.
|
||||||
|
|
||||||
|
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||||
|
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||||
|
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||||
|
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||||
|
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||||
|
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. Limitation of Liability.
|
||||||
|
|
||||||
|
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||||
|
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||||
|
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||||
|
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||||
|
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||||
|
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||||
|
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGES.
|
||||||
|
|
||||||
|
17. Interpretation of Sections 15 and 16.
|
||||||
|
|
||||||
|
If the disclaimer of warranty and limitation of liability provided
|
||||||
|
above cannot be given local legal effect according to their terms,
|
||||||
|
reviewing courts shall apply local law that most closely approximates
|
||||||
|
an absolute waiver of all civil liability in connection with the
|
||||||
|
Program, unless a warranty or assumption of liability accompanies a
|
||||||
|
copy of the Program in return for a fee.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
state the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program does terminal interaction, make it output a short
|
||||||
|
notice like this when it starts in an interactive mode:
|
||||||
|
|
||||||
|
<program> Copyright (C) <year> <name of author>
|
||||||
|
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, your program's commands
|
||||||
|
might be different; for a GUI interface, you would use an "about box".
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or school,
|
||||||
|
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||||
|
For more information on this, and how to apply and follow the GNU GPL, see
|
||||||
|
<https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
The GNU General Public License does not permit incorporating your program
|
||||||
|
into proprietary programs. If your program is a subroutine library, you
|
||||||
|
may consider it more useful to permit linking proprietary applications with
|
||||||
|
the library. If this is what you want to do, use the GNU Lesser General
|
||||||
|
Public License instead of this License. But first, please read
|
||||||
|
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
||||||
226
README.md
Normal file
@@ -0,0 +1,226 @@
|
|||||||
|
# DragonX Wallet - ImGui Edition
|
||||||
|
|
||||||
|
A lightweight, portable cryptocurrency wallet for DragonX (DRGX), built with Dear ImGui.
|
||||||
|
|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- **Full Node Support**: Connects to dragonxd for complete blockchain verification
|
||||||
|
- **Shielded Transactions**: Full z-address support with encrypted memos
|
||||||
|
- **Integrated Mining**: CPU mining controls with hashrate monitoring
|
||||||
|
- **Market Data**: Real-time price charts from CoinGecko
|
||||||
|
- **QR Codes**: Generate and display QR codes for receiving addresses
|
||||||
|
- **Multi-language**: i18n support (English, Spanish, more coming)
|
||||||
|
- **Lightweight**: ~5-10MB binary vs ~50MB+ for Qt version
|
||||||
|
- **Fast Builds**: Compiles in seconds, not minutes
|
||||||
|
|
||||||
|
## Screenshots
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<img src="docs/screenshots/1.webp" width="32%" /> <img src="docs/screenshots/2.webp" width="32%" /> <img src="docs/screenshots/3.webp" width="32%" />
|
||||||
|
<br/>
|
||||||
|
<img src="docs/screenshots/4.webp" width="32%" /> <img src="docs/screenshots/5.webp" width="32%" /> <img src="docs/screenshots/6.webp" width="32%" />
|
||||||
|
<br/>
|
||||||
|
<img src="docs/screenshots/7.webp" width="32%" /> <img src="docs/screenshots/8.webp" width="32%" /> <img src="docs/screenshots/9.webp" width="32%" />
|
||||||
|
</p>
|
||||||
|
|
||||||
|
## Building
|
||||||
|
|
||||||
|
### Quick Setup
|
||||||
|
|
||||||
|
The setup script detects your OS, installs all build dependencies, and validates your environment:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./scripts/setup.sh # Install core build deps (interactive)
|
||||||
|
./scripts/setup.sh --check # Just report what's missing
|
||||||
|
./scripts/setup.sh --all # Core + Windows/macOS cross-compile + Sapling params
|
||||||
|
./scripts/setup.sh --win # Also install mingw-w64 + libsodium-win
|
||||||
|
```
|
||||||
|
|
||||||
|
### Manual Prerequisites
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Click to expand manual install commands</summary>
|
||||||
|
|
||||||
|
**Linux (Ubuntu/Debian):**
|
||||||
|
```
|
||||||
|
sudo apt install build-essential cmake git pkg-config
|
||||||
|
sudo apt install libgl1-mesa-dev libx11-dev libxcursor-dev libxrandr-dev libxinerama-dev libxi-dev
|
||||||
|
sudo apt install libsodium-dev libcurl4-openssl-dev
|
||||||
|
```
|
||||||
|
|
||||||
|
**Linux (Arch):**
|
||||||
|
```
|
||||||
|
sudo pacman -S base-devel cmake git pkg-config mesa libx11 libxcursor libxrandr libxinerama libxi libsodium curl
|
||||||
|
```
|
||||||
|
|
||||||
|
**macOS:**
|
||||||
|
```
|
||||||
|
xcode-select --install
|
||||||
|
brew install cmake
|
||||||
|
```
|
||||||
|
|
||||||
|
**Windows:**
|
||||||
|
- Visual Studio 2019+ with C++ workload
|
||||||
|
- CMake 3.20+
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
### Binaries
|
||||||
|
Download linux and windows binaries of latest releases and place in binary directories:
|
||||||
|
|
||||||
|
**DragonX daemon** (https://git.hush.is/hush/hush3):
|
||||||
|
- prebuilt-binaries/dragonxd-linux/
|
||||||
|
- prebuilt-binaries/dragonxd-win/
|
||||||
|
- prebuilt-binaries/dragonxd-mac/
|
||||||
|
|
||||||
|
**xmrig HAC fork** (https://git.hush.is/dragonx/xmrig-hac):
|
||||||
|
- prebuilt-binaries/xmrig-hac/
|
||||||
|
|
||||||
|
|
||||||
|
## Build Steps
|
||||||
|
|
||||||
|
```
|
||||||
|
### Clone repository (if not already)
|
||||||
|
git clone https://git.hush.is/dragonx/ObsidianDragon.git
|
||||||
|
cd ObsidianDragon/
|
||||||
|
```
|
||||||
|
|
||||||
|
### Windows Build
|
||||||
|
|
||||||
|
```
|
||||||
|
./build.sh --win-release
|
||||||
|
```
|
||||||
|
|
||||||
|
### Release Build
|
||||||
|
|
||||||
|
```
|
||||||
|
./build.sh --linux-release # Linux release + AppImage
|
||||||
|
./build.sh --win-release # Windows cross-compile
|
||||||
|
./build.sh --mac-release # macOS .app bundle + DMG
|
||||||
|
./build.sh --clean --linux-release # Clean + Release
|
||||||
|
```
|
||||||
|
|
||||||
|
## Running
|
||||||
|
|
||||||
|
1. **Start dragonxd** (if not using embedded daemon):
|
||||||
|
```
|
||||||
|
dragonxd -daemon
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Run the wallet**:
|
||||||
|
```
|
||||||
|
cd build/bin
|
||||||
|
./ObsidianDragon
|
||||||
|
```
|
||||||
|
|
||||||
|
The wallet will automatically connect to the daemon using credentials from \`~/.hush/DRAGONX/DRAGONX.conf\`.
|
||||||
|
### Using Custom Node Binaries
|
||||||
|
|
||||||
|
The wallet checks its **own directory first** when looking for DragonX node binaries. This means you can test new or different branch builds of `hush-arrakis-chain`/`hushd` without waiting for a new wallet release:
|
||||||
|
|
||||||
|
1. Build or download the node binaries you want to test
|
||||||
|
2. Place them in the same directory as the wallet executable (e.g. `build/bin/`)
|
||||||
|
3. Launch the wallet — it will use the local binaries instead of the bundled ones
|
||||||
|
|
||||||
|
**Search order:**
|
||||||
|
1. Wallet executable directory (highest priority)
|
||||||
|
2. Embedded/extracted daemon (app data directory)
|
||||||
|
3. System-wide locations (`/usr/local/bin`, `~/hush3/src`, etc.)
|
||||||
|
|
||||||
|
This is useful for testing new branches or hotfixes to the node software before they are bundled into a wallet release.
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
Configuration is stored in \`~/.hush/DRAGONX/DRAGONX.conf\`:
|
||||||
|
|
||||||
|
```
|
||||||
|
rpcuser=your_rpc_user
|
||||||
|
rpcpassword=your_rpc_password
|
||||||
|
rpcport=21769
|
||||||
|
```
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
\`\`\`
|
||||||
|
ObsidianDragon/
|
||||||
|
├── src/
|
||||||
|
│ ├── main.cpp # Entry point, SDL/ImGui setup
|
||||||
|
│ ├── app.cpp/h # Main application class
|
||||||
|
│ ├── wallet_state.h # Wallet data structures
|
||||||
|
│ ├── version.h # Version definitions
|
||||||
|
│ ├── ui/
|
||||||
|
│ │ ├── theme.cpp/h # DragonX theme
|
||||||
|
│ │ └── windows/ # UI tabs and dialogs
|
||||||
|
│ ├── rpc/
|
||||||
|
│ │ ├── rpc_client.cpp # JSON-RPC client
|
||||||
|
│ │ └── connection.cpp # Daemon connection
|
||||||
|
│ ├── config/
|
||||||
|
│ │ └── settings.cpp # Settings persistence
|
||||||
|
│ ├── util/
|
||||||
|
│ │ ├── i18n.cpp # Internationalization
|
||||||
|
│ │ └── ...
|
||||||
|
│ └── daemon/
|
||||||
|
│ └── embedded_daemon.cpp
|
||||||
|
├── res/
|
||||||
|
│ ├── fonts/ # Ubuntu font
|
||||||
|
│ └── lang/ # Translation files
|
||||||
|
├── libs/
|
||||||
|
│ └── qrcode/ # QR code generation
|
||||||
|
├── CMakeLists.txt
|
||||||
|
├── build-release.sh # Build script
|
||||||
|
└── create-appimage.sh # AppImage packaging
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
Fetched automatically by CMake (no manual install needed):
|
||||||
|
|
||||||
|
- **[SDL3](https://github.com/libsdl-org/SDL)** — Cross-platform windowing/input
|
||||||
|
- **[nlohmann/json](https://github.com/nlohmann/json)** — JSON parsing
|
||||||
|
- **[toml++](https://github.com/marzer/tomlplusplus)** — TOML parsing (UI schema/themes)
|
||||||
|
- **[libcurl](https://curl.se/libcurl/)** — HTTPS RPC transport (system on Linux, fetched on Windows)
|
||||||
|
|
||||||
|
Bundled in `libs/`:
|
||||||
|
|
||||||
|
- **[Dear ImGui](https://github.com/ocornut/imgui)** — Immediate mode GUI
|
||||||
|
- **[libsodium](https://libsodium.org)** — Cryptographic operations (fetched by `scripts/fetch-libsodium.sh`)
|
||||||
|
- **[QR-Code-generator](https://github.com/nayuki/QR-Code-generator)** — QR code rendering
|
||||||
|
- **[miniz](https://github.com/richgel999/miniz)** — ZIP compression
|
||||||
|
- **[GLAD](https://glad.dav1d.de/)** — OpenGL loader (Linux/macOS)
|
||||||
|
- **[stb_image](https://github.com/nothings/stb)** — Image loading
|
||||||
|
- **[incbin](https://github.com/graphitemaster/incbin)** — Binary resource embedding (Windows builds)
|
||||||
|
|
||||||
|
## Keyboard Shortcuts
|
||||||
|
|
||||||
|
| Shortcut | Action |
|
||||||
|
|----------|--------|
|
||||||
|
| Ctrl+, | Settings |
|
||||||
|
| F5 | Refresh |
|
||||||
|
| Alt+F4 | Exit |
|
||||||
|
|
||||||
|
## Translation
|
||||||
|
|
||||||
|
To add a new language:
|
||||||
|
|
||||||
|
1. Copy \`res/lang/es.json\` to \`res/lang/<code>.json\`
|
||||||
|
2. Translate all strings
|
||||||
|
3. The language will appear in Settings automatically
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
This project is licensed under the GNU General Public License v3 (GPLv3).
|
||||||
|
|
||||||
|
## Credits
|
||||||
|
|
||||||
|
- The Hush Developers
|
||||||
|
- DragonX Community
|
||||||
|
- [Dear ImGui](https://github.com/ocornut/imgui) by Omar Cornut
|
||||||
|
- [SDL](https://libsdl.org/) by Sam Lantinga
|
||||||
|
|
||||||
|
## Links
|
||||||
|
|
||||||
|
- Website: https://dragonx.is
|
||||||
|
- Explorer: https://explorer.dragonx.is
|
||||||
|
- Source: https://git.hush.is/dragonx/ObsidianDragon
|
||||||
53
SECURITY.md
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
# Security Policy
|
||||||
|
|
||||||
|
## Reporting a Vulnerability
|
||||||
|
|
||||||
|
ObsidianDragon is a cryptocurrency wallet that handles private keys and funds. We take security seriously.
|
||||||
|
|
||||||
|
**Do NOT report security vulnerabilities through public issues.**
|
||||||
|
|
||||||
|
Instead, please report them privately:
|
||||||
|
|
||||||
|
- Email: security@dragonx.is
|
||||||
|
- Or contact the maintainers directly through the DragonX community channels
|
||||||
|
|
||||||
|
### What to Include
|
||||||
|
|
||||||
|
- Description of the vulnerability
|
||||||
|
- Steps to reproduce
|
||||||
|
- Potential impact
|
||||||
|
- Suggested fix (if any)
|
||||||
|
|
||||||
|
### Response Timeline
|
||||||
|
|
||||||
|
- **Acknowledgement**: Within 48 hours
|
||||||
|
- **Assessment**: Within 1 week
|
||||||
|
- **Fix**: As soon as possible, depending on severity
|
||||||
|
|
||||||
|
### Scope
|
||||||
|
|
||||||
|
The following are in scope:
|
||||||
|
- Private key exposure or theft
|
||||||
|
- Wallet passphrase/PIN bypass
|
||||||
|
- RPC credential leakage
|
||||||
|
- Remote code execution
|
||||||
|
- Fund loss or misdirection
|
||||||
|
- Daemon communication interception
|
||||||
|
|
||||||
|
### Recognition
|
||||||
|
|
||||||
|
We appreciate responsible disclosure and will credit reporters in release notes (unless anonymity is preferred).
|
||||||
|
|
||||||
|
## Supported Versions
|
||||||
|
|
||||||
|
| Version | Supported |
|
||||||
|
|---------|-----------|
|
||||||
|
| Latest release | Yes |
|
||||||
|
| Older releases | Best effort |
|
||||||
|
|
||||||
|
## Security Best Practices for Users
|
||||||
|
|
||||||
|
- Always verify downloads against published checksums
|
||||||
|
- Use a strong passphrase or PIN to encrypt your wallet
|
||||||
|
- Keep your system and wallet software up to date
|
||||||
|
- Back up your wallet regularly
|
||||||
401
THIRD_PARTY_LICENSES
Normal file
@@ -0,0 +1,401 @@
|
|||||||
|
# Third-Party Licenses
|
||||||
|
|
||||||
|
This file documents all third-party libraries used in ObsidianDragon,
|
||||||
|
their versions, authors, and license texts.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Dear ImGui — v1.92.6 WIP
|
||||||
|
|
||||||
|
- **Source:** https://github.com/ocornut/imgui
|
||||||
|
- **Copyright:** (c) 2014-2026 Omar Cornut
|
||||||
|
- **License:** MIT
|
||||||
|
|
||||||
|
```
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2014-2026 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.
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. SDL3 — v3.5.0 (267e681a)
|
||||||
|
|
||||||
|
- **Source:** https://github.com/libsdl-org/SDL
|
||||||
|
- **Copyright:** (c) 1997-2026 Sam Lantinga
|
||||||
|
- **License:** zlib
|
||||||
|
|
||||||
|
```
|
||||||
|
Copyright (C) 1997-2026 Sam Lantinga <slouken@libsdl.org>
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original software. If you use this software
|
||||||
|
in a product, an acknowledgment in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original software.
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. nlohmann/json — v3.11.3
|
||||||
|
|
||||||
|
- **Source:** https://github.com/nlohmann/json
|
||||||
|
- **Copyright:** (c) 2013-2022 Niels Lohmann
|
||||||
|
- **License:** MIT
|
||||||
|
|
||||||
|
```
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2013-2022 Niels Lohmann
|
||||||
|
|
||||||
|
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.
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. toml++ — v3.4.0
|
||||||
|
|
||||||
|
- **Source:** https://github.com/marzer/tomlplusplus
|
||||||
|
- **Copyright:** (c) Mark Gillard
|
||||||
|
- **License:** MIT
|
||||||
|
|
||||||
|
```
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) Mark Gillard <mark.gillard@outlook.com.au>
|
||||||
|
|
||||||
|
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.
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. stb_image — v2.30
|
||||||
|
|
||||||
|
- **Location:** `libs/stb_image.h`
|
||||||
|
- **Source:** https://github.com/nothings/stb
|
||||||
|
- **Copyright:** (c) 2017 Sean Barrett
|
||||||
|
- **License:** MIT or Public Domain (dual-licensed, choose either)
|
||||||
|
|
||||||
|
```
|
||||||
|
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.
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. miniz — v3.1.0
|
||||||
|
|
||||||
|
- **Location:** `libs/miniz/`
|
||||||
|
- **Source:** https://github.com/richgel999/miniz
|
||||||
|
- **Copyright:** Rich Geldreich
|
||||||
|
- **License:** Unlicense (Public Domain)
|
||||||
|
|
||||||
|
```
|
||||||
|
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/>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. QR Code generator library (C++)
|
||||||
|
|
||||||
|
- **Location:** `libs/qrcode/`
|
||||||
|
- **Source:** https://www.nayuki.io/page/qr-code-generator-library
|
||||||
|
- **Copyright:** (c) Project Nayuki
|
||||||
|
- **License:** MIT
|
||||||
|
|
||||||
|
```
|
||||||
|
Copyright (c) Project Nayuki. (MIT License)
|
||||||
|
https://www.nayuki.io/page/qr-code-generator-library
|
||||||
|
|
||||||
|
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.
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. GLAD (OpenGL Loader)
|
||||||
|
|
||||||
|
- **Location:** `libs/glad/`
|
||||||
|
- **Source:** https://glad.dav1d.de (generator) / https://github.com/Dav1dde/glad
|
||||||
|
- **License:** Public Domain / MIT
|
||||||
|
|
||||||
|
Generated code from the GLAD loader generator is in the public domain.
|
||||||
|
The GLAD generator itself is MIT-licensed. The OpenGL specifications
|
||||||
|
used to generate the loader are copyright The Khronos Group Inc. under
|
||||||
|
the Apache License 2.0:
|
||||||
|
|
||||||
|
```
|
||||||
|
Copyright (c) 2013-2020 The Khronos Group Inc.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. incbin
|
||||||
|
|
||||||
|
- **Location:** `libs/incbin.h`
|
||||||
|
- **License:** Public Domain
|
||||||
|
|
||||||
|
Based on the public-domain incbin technique. Adapted for DragonX Wallet
|
||||||
|
by The Hush Developers, 2024-2026.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10. libsodium — v1.0.18 (macOS pre-built)
|
||||||
|
|
||||||
|
- **Location:** `libs/libsodium-mac/`
|
||||||
|
- **Source:** https://github.com/jedisct1/libsodium
|
||||||
|
- **Copyright:** (c) 2013-2020 Frank Denis
|
||||||
|
- **License:** ISC
|
||||||
|
|
||||||
|
```
|
||||||
|
ISC License
|
||||||
|
|
||||||
|
Copyright (c) 2013-2020
|
||||||
|
Frank Denis <j at pureftpd dot org>
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 11. libcurl — v8.5.0 (Windows cross-compile only)
|
||||||
|
|
||||||
|
- **Source:** https://github.com/curl/curl
|
||||||
|
- **Copyright:** (c) 1996-2024 Daniel Stenberg
|
||||||
|
- **License:** curl (MIT-style)
|
||||||
|
|
||||||
|
```
|
||||||
|
COPYRIGHT AND PERMISSION NOTICE
|
||||||
|
|
||||||
|
Copyright (c) 1996 - 2024, Daniel Stenberg, <daniel@haxx.se>, and many
|
||||||
|
contributors, see the THANKS file.
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and distribute this software for any purpose
|
||||||
|
with or without fee is hereby granted, provided that the above copyright
|
||||||
|
notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
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 OF THIRD PARTY RIGHTS. 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.
|
||||||
|
|
||||||
|
Except as contained in this notice, the name of a copyright holder shall not
|
||||||
|
be used in advertising or otherwise to promote the sale, use or other dealings
|
||||||
|
in this Software without prior written authorization of the copyright holder.
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 12. Material Design Icons Font
|
||||||
|
|
||||||
|
- **Location:** `res/fonts/MaterialIcons-Regular.ttf`
|
||||||
|
- **Source:** https://github.com/google/material-design-icons
|
||||||
|
- **Copyright:** (c) Google Inc.
|
||||||
|
- **License:** Apache License 2.0
|
||||||
|
|
||||||
|
The full text of the Apache License 2.0 is available at:
|
||||||
|
https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 13. IconFontCppHeaders
|
||||||
|
|
||||||
|
- **Location:** `src/embedded/IconsMaterialDesign.h`
|
||||||
|
- **Source:** https://github.com/juliettef/IconFontCppHeaders
|
||||||
|
- **Copyright:** (c) 2017 Juliette Foucaut and Doug Binks
|
||||||
|
- **License:** zlib
|
||||||
|
|
||||||
|
```
|
||||||
|
Copyright (c) 2017 Juliette Foucaut and Doug Binks
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original software. If you use this software
|
||||||
|
in a product, an acknowledgment in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original software.
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 14. Ubuntu Font Family
|
||||||
|
|
||||||
|
- **Location:** `res/fonts/Ubuntu-Light.ttf`, `Ubuntu-Medium.ttf`, `Ubuntu-R.ttf`
|
||||||
|
- **Source:** https://design.ubuntu.com/font
|
||||||
|
- **Copyright:** (c) 2010-2011 Canonical Ltd.
|
||||||
|
- **License:** Ubuntu Font Licence v1.0
|
||||||
|
|
||||||
|
The full text of the Ubuntu Font Licence v1.0 is available at:
|
||||||
|
https://ubuntu.com/legal/font-licence
|
||||||
42
cmake/EmbedResources.cmake
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
# CMake script to embed binary files as C arrays
|
||||||
|
|
||||||
|
function(embed_resource RESOURCE_FILE OUTPUT_FILE VAR_NAME)
|
||||||
|
file(READ "${RESOURCE_FILE}" HEX_CONTENT HEX)
|
||||||
|
|
||||||
|
# Convert hex to C array format
|
||||||
|
string(LENGTH "${HEX_CONTENT}" HEX_LENGTH)
|
||||||
|
math(EXPR BYTE_COUNT "${HEX_LENGTH} / 2")
|
||||||
|
|
||||||
|
set(ARRAY_CONTENT "")
|
||||||
|
set(INDEX 0)
|
||||||
|
while(INDEX LESS HEX_LENGTH)
|
||||||
|
string(SUBSTRING "${HEX_CONTENT}" ${INDEX} 2 BYTE)
|
||||||
|
string(APPEND ARRAY_CONTENT "0x${BYTE},")
|
||||||
|
math(EXPR INDEX "${INDEX} + 2")
|
||||||
|
math(EXPR BYTE_NUM "${INDEX} / 2")
|
||||||
|
math(EXPR MOD "${BYTE_NUM} % 16")
|
||||||
|
if(MOD EQUAL 0)
|
||||||
|
string(APPEND ARRAY_CONTENT "\n ")
|
||||||
|
endif()
|
||||||
|
endwhile()
|
||||||
|
|
||||||
|
# Generate header file
|
||||||
|
set(HEADER_CONTENT "// Auto-generated embedded resource - DO NOT EDIT
|
||||||
|
#pragma once
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace embedded {
|
||||||
|
|
||||||
|
inline constexpr unsigned char ${VAR_NAME}_data[] = {
|
||||||
|
${ARRAY_CONTENT}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline constexpr size_t ${VAR_NAME}_size = ${BYTE_COUNT};
|
||||||
|
|
||||||
|
} // namespace embedded
|
||||||
|
")
|
||||||
|
|
||||||
|
file(WRITE "${OUTPUT_FILE}" "${HEADER_CONTENT}")
|
||||||
|
message(STATUS "Embedded ${RESOURCE_FILE} -> ${OUTPUT_FILE} (${BYTE_COUNT} bytes)")
|
||||||
|
endfunction()
|
||||||
BIN
docs/screenshots/1.webp
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
docs/screenshots/2.webp
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
docs/screenshots/3.webp
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
docs/screenshots/4.webp
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
docs/screenshots/5.webp
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
docs/screenshots/6.webp
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
docs/screenshots/7.webp
Normal file
|
After Width: | Height: | Size: 55 KiB |
BIN
docs/screenshots/8.webp
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
docs/screenshots/9.webp
Normal file
|
After Width: | Height: | Size: 24 KiB |
244
libs/glad/include/KHR/khrplatform.h
Normal file
@@ -0,0 +1,244 @@
|
|||||||
|
#ifndef __khrplatform_h_
|
||||||
|
#define __khrplatform_h_
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Copyright (c) 2008-2018 The Khronos Group Inc.
|
||||||
|
**
|
||||||
|
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
** copy of this software and/or associated documentation files (the
|
||||||
|
** "Materials"), to deal in the Materials without restriction, including
|
||||||
|
** without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||||
|
** permit persons to whom the Materials are 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 Materials.
|
||||||
|
**
|
||||||
|
** THE MATERIALS ARE 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
|
||||||
|
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Khronos platform-specific types and definitions.
|
||||||
|
*
|
||||||
|
* The master copy of khrplatform.h is maintained in the Khronos EGL
|
||||||
|
* Registry repository at https://github.com/KhronosGroup/EGL-Registry
|
||||||
|
* The last semantic modification to khrplatform.h was at commit ID:
|
||||||
|
* 67a3e0864c2d75a5cc215f570d5d8e5d8b24db93
|
||||||
|
*
|
||||||
|
* Adopters may modify this file to suit their platform., please
|
||||||
|
* send a copy of any modifications to the Khronos Registrar
|
||||||
|
* (Khronos Registrar <khronos-registry AT khronos DOT org>).
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC)
|
||||||
|
# define KHRONOS_STATIC 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
* Definition of KHRONOS_APICALL
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
* This precedes the return type of the function in the function prototype.
|
||||||
|
*/
|
||||||
|
#if defined(KHRONOS_STATIC)
|
||||||
|
/* If the preprocessor constant KHRONOS_STATIC is defined, make the
|
||||||
|
* header compatible with static linking. */
|
||||||
|
# define KHRONOS_APICALL
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
# define KHRONOS_APICALL __declspec(dllimport)
|
||||||
|
#elif defined (__SYMBIAN32__)
|
||||||
|
# define KHRONOS_APICALL IMPORT_C
|
||||||
|
#elif defined(__ANDROID__)
|
||||||
|
# define KHRONOS_APICALL __attribute__((visibility("default")))
|
||||||
|
#else
|
||||||
|
# define KHRONOS_APICALL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
* Definition of KHRONOS_APIENTRY
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
* This follows the return type of the function and precedes the function
|
||||||
|
* name in the function prototype.
|
||||||
|
*/
|
||||||
|
#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__)
|
||||||
|
/* Win32 but not WinCE */
|
||||||
|
# define KHRONOS_APIENTRY __stdcall
|
||||||
|
#else
|
||||||
|
# define KHRONOS_APIENTRY
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
* Definition of KHRONOS_APIATTRIBUTES
|
||||||
|
*-------------------------------------------------------------------------
|
||||||
|
* This follows the closing parenthesis of the function prototype arguments.
|
||||||
|
*/
|
||||||
|
#if defined (__ARMCC_2__)
|
||||||
|
#define KHRONOS_APIATTRIBUTES __softfp
|
||||||
|
#else
|
||||||
|
#define KHRONOS_APIATTRIBUTES
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
* basic type definitions
|
||||||
|
*-----------------------------------------------------------------------*/
|
||||||
|
#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__)
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Using <stdint.h>
|
||||||
|
*/
|
||||||
|
#include <stdint.h>
|
||||||
|
typedef int32_t khronos_int32_t;
|
||||||
|
typedef uint32_t khronos_uint32_t;
|
||||||
|
typedef int64_t khronos_int64_t;
|
||||||
|
typedef uint64_t khronos_uint64_t;
|
||||||
|
#define KHRONOS_SUPPORT_INT64 1
|
||||||
|
#define KHRONOS_SUPPORT_FLOAT 1
|
||||||
|
/*
|
||||||
|
* To support platform where these types are not defined.
|
||||||
|
*/
|
||||||
|
typedef signed char khronos_int8_t;
|
||||||
|
typedef unsigned char khronos_uint8_t;
|
||||||
|
typedef signed short int khronos_int16_t;
|
||||||
|
typedef unsigned short int khronos_uint16_t;
|
||||||
|
|
||||||
|
#elif defined(__VMS ) || defined(__sgi)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Using <inttypes.h>
|
||||||
|
*/
|
||||||
|
#include <inttypes.h>
|
||||||
|
typedef int32_t khronos_int32_t;
|
||||||
|
typedef uint32_t khronos_uint32_t;
|
||||||
|
typedef int64_t khronos_int64_t;
|
||||||
|
typedef uint64_t khronos_uint64_t;
|
||||||
|
#define KHRONOS_SUPPORT_INT64 1
|
||||||
|
#define KHRONOS_SUPPORT_FLOAT 1
|
||||||
|
|
||||||
|
#elif defined(_WIN32) && !defined(__SCITECH_SNAP__)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Win32
|
||||||
|
*/
|
||||||
|
typedef __int32 khronos_int32_t;
|
||||||
|
typedef unsigned __int32 khronos_uint32_t;
|
||||||
|
typedef __int64 khronos_int64_t;
|
||||||
|
typedef unsigned __int64 khronos_uint64_t;
|
||||||
|
#define KHRONOS_SUPPORT_INT64 1
|
||||||
|
#define KHRONOS_SUPPORT_FLOAT 1
|
||||||
|
|
||||||
|
#elif defined(__sun__) || defined(__digital__)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sun or Digital
|
||||||
|
*/
|
||||||
|
typedef int khronos_int32_t;
|
||||||
|
typedef unsigned int khronos_uint32_t;
|
||||||
|
#if defined(__arch64__) || defined(_LP64)
|
||||||
|
typedef long int khronos_int64_t;
|
||||||
|
typedef unsigned long int khronos_uint64_t;
|
||||||
|
#else
|
||||||
|
typedef long long int khronos_int64_t;
|
||||||
|
typedef unsigned long long int khronos_uint64_t;
|
||||||
|
#endif /* __arch64__ */
|
||||||
|
#define KHRONOS_SUPPORT_INT64 1
|
||||||
|
#define KHRONOS_SUPPORT_FLOAT 1
|
||||||
|
|
||||||
|
#elif 0
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hypothetical platform with no float or int64 support
|
||||||
|
*/
|
||||||
|
typedef int khronos_int32_t;
|
||||||
|
typedef unsigned int khronos_uint32_t;
|
||||||
|
#define KHRONOS_SUPPORT_INT64 0
|
||||||
|
#define KHRONOS_SUPPORT_FLOAT 0
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Generic fallback
|
||||||
|
*/
|
||||||
|
#include <stdint.h>
|
||||||
|
typedef int32_t khronos_int32_t;
|
||||||
|
typedef uint32_t khronos_uint32_t;
|
||||||
|
typedef int64_t khronos_int64_t;
|
||||||
|
typedef uint64_t khronos_uint64_t;
|
||||||
|
#define KHRONOS_SUPPORT_INT64 1
|
||||||
|
#define KHRONOS_SUPPORT_FLOAT 1
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Types that are (so far) the same on all platforms
|
||||||
|
*/
|
||||||
|
typedef signed char khronos_int8_t;
|
||||||
|
typedef unsigned char khronos_uint8_t;
|
||||||
|
typedef signed short int khronos_int16_t;
|
||||||
|
typedef unsigned short int khronos_uint16_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Types that differ between LLP64 and LP64 architectures - in LLP64,
|
||||||
|
* pointers are 64 bits, but 'long' is still 32 bits. Win64 appears
|
||||||
|
* to be the only LLP64 architecture in current use.
|
||||||
|
*/
|
||||||
|
#ifdef _WIN64
|
||||||
|
typedef signed long long int khronos_intptr_t;
|
||||||
|
typedef unsigned long long int khronos_uintptr_t;
|
||||||
|
typedef signed long long int khronos_ssize_t;
|
||||||
|
typedef unsigned long long int khronos_usize_t;
|
||||||
|
#else
|
||||||
|
typedef signed long int khronos_intptr_t;
|
||||||
|
typedef unsigned long int khronos_uintptr_t;
|
||||||
|
typedef signed long int khronos_ssize_t;
|
||||||
|
typedef unsigned long int khronos_usize_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if KHRONOS_SUPPORT_FLOAT
|
||||||
|
/*
|
||||||
|
* Float type
|
||||||
|
*/
|
||||||
|
typedef float khronos_float_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if KHRONOS_SUPPORT_INT64
|
||||||
|
/* Time types
|
||||||
|
*
|
||||||
|
* These types can be used to represent a time interval in nanoseconds or
|
||||||
|
* an absolute Unadjusted System Time. Unadjusted System Time is the number
|
||||||
|
* of nanoseconds since some arbitrary system event (e.g. since the last
|
||||||
|
* time the system booted). The Unadjusted System Time is an unsigned
|
||||||
|
* 64 bit value that wraps back to 0 every 584 years. Time intervals
|
||||||
|
* may be either signed or unsigned.
|
||||||
|
*/
|
||||||
|
typedef khronos_uint64_t khronos_utime_nanoseconds_t;
|
||||||
|
typedef khronos_int64_t khronos_stime_nanoseconds_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Dummy value used to pad enum types to 32 bits.
|
||||||
|
*/
|
||||||
|
#ifndef KHRONOS_MAX_ENUM
|
||||||
|
#define KHRONOS_MAX_ENUM 0x7FFFFFFF
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enumerated boolean type
|
||||||
|
*
|
||||||
|
* Values other than zero should be considered to be true. Therefore
|
||||||
|
* comparisons should not be made against KHRONOS_TRUE.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
KHRONOS_FALSE = 0,
|
||||||
|
KHRONOS_TRUE = 1,
|
||||||
|
KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM
|
||||||
|
} khronos_boolean_enum_t;
|
||||||
|
|
||||||
|
#endif /* __khrplatform_h_ */
|
||||||
379
libs/glad/include/glad/gl.h
Normal file
@@ -0,0 +1,379 @@
|
|||||||
|
/**
|
||||||
|
* GLAD - OpenGL Loader Generator
|
||||||
|
* Generated for OpenGL 3.3 Core Profile
|
||||||
|
*
|
||||||
|
* This is a minimal GLAD loader for OpenGL 3.3 Core with the extensions
|
||||||
|
* needed for framebuffer operations in the DragonX acrylic effects system.
|
||||||
|
*
|
||||||
|
* Generated from glad.dav1d.de with settings:
|
||||||
|
* - Language: C/C++
|
||||||
|
* - Specification: OpenGL
|
||||||
|
* - API: gl 3.3
|
||||||
|
* - Profile: Core
|
||||||
|
* - Extensions: None (core only)
|
||||||
|
* - Options: Loader enabled
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GLAD_GL_H_
|
||||||
|
#define GLAD_GL_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <KHR/khrplatform.h>
|
||||||
|
|
||||||
|
/* Type definitions */
|
||||||
|
typedef void (*GLADloadproc)(void);
|
||||||
|
typedef void (*GLADapiproc)(void);
|
||||||
|
|
||||||
|
/* GLAD API */
|
||||||
|
#define GLAD_VERSION_MAJOR(version) (version / 10000)
|
||||||
|
#define GLAD_VERSION_MINOR(version) (version % 10000)
|
||||||
|
|
||||||
|
/* Function pointer loader type */
|
||||||
|
typedef GLADapiproc (*GLADloadfunc)(const char *name);
|
||||||
|
|
||||||
|
/* Initialize GLAD loader - returns version (major * 10000 + minor) or 0 on failure */
|
||||||
|
int gladLoadGL(GLADloadfunc load);
|
||||||
|
|
||||||
|
/* SDL3 specific loader helper */
|
||||||
|
#ifdef SDL_VERSION_ATLEAST
|
||||||
|
#include <SDL3/SDL.h>
|
||||||
|
static inline GLADapiproc glad_sdl_get_proc(const char* name) {
|
||||||
|
return (GLADapiproc)SDL_GL_GetProcAddress(name);
|
||||||
|
}
|
||||||
|
#define gladLoadGL_SDL() gladLoadGL(glad_sdl_get_proc)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Feature flags */
|
||||||
|
extern int GLAD_GL_VERSION_1_0;
|
||||||
|
extern int GLAD_GL_VERSION_1_1;
|
||||||
|
extern int GLAD_GL_VERSION_1_2;
|
||||||
|
extern int GLAD_GL_VERSION_1_3;
|
||||||
|
extern int GLAD_GL_VERSION_1_4;
|
||||||
|
extern int GLAD_GL_VERSION_1_5;
|
||||||
|
extern int GLAD_GL_VERSION_2_0;
|
||||||
|
extern int GLAD_GL_VERSION_2_1;
|
||||||
|
extern int GLAD_GL_VERSION_3_0;
|
||||||
|
extern int GLAD_GL_VERSION_3_1;
|
||||||
|
extern int GLAD_GL_VERSION_3_2;
|
||||||
|
extern int GLAD_GL_VERSION_3_3;
|
||||||
|
|
||||||
|
/* OpenGL type definitions */
|
||||||
|
typedef unsigned int GLenum;
|
||||||
|
typedef unsigned char GLboolean;
|
||||||
|
typedef unsigned int GLbitfield;
|
||||||
|
typedef void GLvoid;
|
||||||
|
typedef khronos_int8_t GLbyte;
|
||||||
|
typedef khronos_uint8_t GLubyte;
|
||||||
|
typedef khronos_int16_t GLshort;
|
||||||
|
typedef khronos_uint16_t GLushort;
|
||||||
|
typedef int GLint;
|
||||||
|
typedef unsigned int GLuint;
|
||||||
|
typedef khronos_int32_t GLclampx;
|
||||||
|
typedef int GLsizei;
|
||||||
|
typedef khronos_float_t GLfloat;
|
||||||
|
typedef khronos_float_t GLclampf;
|
||||||
|
typedef double GLdouble;
|
||||||
|
typedef double GLclampd;
|
||||||
|
typedef void *GLeglClientBufferEXT;
|
||||||
|
typedef void *GLeglImageOES;
|
||||||
|
typedef char GLchar;
|
||||||
|
typedef char GLcharARB;
|
||||||
|
#ifdef __APPLE__
|
||||||
|
typedef void *GLhandleARB;
|
||||||
|
#else
|
||||||
|
typedef unsigned int GLhandleARB;
|
||||||
|
#endif
|
||||||
|
typedef khronos_uint16_t GLhalf;
|
||||||
|
typedef khronos_uint16_t GLhalfARB;
|
||||||
|
typedef khronos_int32_t GLfixed;
|
||||||
|
typedef khronos_intptr_t GLintptr;
|
||||||
|
typedef khronos_intptr_t GLintptrARB;
|
||||||
|
typedef khronos_ssize_t GLsizeiptr;
|
||||||
|
typedef khronos_ssize_t GLsizeiptrARB;
|
||||||
|
typedef khronos_int64_t GLint64;
|
||||||
|
typedef khronos_int64_t GLint64EXT;
|
||||||
|
typedef khronos_uint64_t GLuint64;
|
||||||
|
typedef khronos_uint64_t GLuint64EXT;
|
||||||
|
typedef struct __GLsync *GLsync;
|
||||||
|
|
||||||
|
/* OpenGL constants */
|
||||||
|
#define GL_FALSE 0
|
||||||
|
#define GL_TRUE 1
|
||||||
|
#define GL_NONE 0
|
||||||
|
#define GL_ZERO 0
|
||||||
|
#define GL_ONE 1
|
||||||
|
|
||||||
|
/* Depth buffer */
|
||||||
|
#define GL_DEPTH_BUFFER_BIT 0x00000100
|
||||||
|
#define GL_STENCIL_BUFFER_BIT 0x00000400
|
||||||
|
#define GL_COLOR_BUFFER_BIT 0x00004000
|
||||||
|
#define GL_DEPTH_TEST 0x0B71
|
||||||
|
|
||||||
|
/* Blending */
|
||||||
|
#define GL_BLEND 0x0BE2
|
||||||
|
#define GL_SRC_ALPHA 0x0302
|
||||||
|
#define GL_ONE_MINUS_SRC_ALPHA 0x0303
|
||||||
|
|
||||||
|
/* Texture */
|
||||||
|
#define GL_TEXTURE_2D 0x0DE1
|
||||||
|
#define GL_TEXTURE0 0x84C0
|
||||||
|
#define GL_TEXTURE_MAG_FILTER 0x2800
|
||||||
|
#define GL_TEXTURE_MIN_FILTER 0x2801
|
||||||
|
#define GL_TEXTURE_WRAP_S 0x2802
|
||||||
|
#define GL_TEXTURE_WRAP_T 0x2803
|
||||||
|
#define GL_LINEAR 0x2601
|
||||||
|
#define GL_NEAREST 0x2600
|
||||||
|
#define GL_LINEAR_MIPMAP_LINEAR 0x2703
|
||||||
|
#define GL_CLAMP_TO_EDGE 0x812F
|
||||||
|
#define GL_REPEAT 0x2901
|
||||||
|
#define GL_RGBA 0x1908
|
||||||
|
#define GL_RGBA8 0x8058
|
||||||
|
#define GL_UNSIGNED_BYTE 0x1401
|
||||||
|
|
||||||
|
/* Framebuffer */
|
||||||
|
#define GL_FRAMEBUFFER 0x8D40
|
||||||
|
#define GL_READ_FRAMEBUFFER 0x8CA8
|
||||||
|
#define GL_DRAW_FRAMEBUFFER 0x8CA9
|
||||||
|
#define GL_COLOR_ATTACHMENT0 0x8CE0
|
||||||
|
#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A
|
||||||
|
#define GL_DEPTH24_STENCIL8 0x88F0
|
||||||
|
#define GL_FRAMEBUFFER_COMPLETE 0x8CD5
|
||||||
|
#define GL_FRAMEBUFFER_UNDEFINED 0x8219
|
||||||
|
#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6
|
||||||
|
#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7
|
||||||
|
#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB
|
||||||
|
#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC
|
||||||
|
#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD
|
||||||
|
#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56
|
||||||
|
#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8
|
||||||
|
|
||||||
|
/* Renderbuffer */
|
||||||
|
#define GL_RENDERBUFFER 0x8D41
|
||||||
|
|
||||||
|
/* Shaders */
|
||||||
|
#define GL_FRAGMENT_SHADER 0x8B30
|
||||||
|
#define GL_VERTEX_SHADER 0x8B31
|
||||||
|
#define GL_COMPILE_STATUS 0x8B81
|
||||||
|
#define GL_LINK_STATUS 0x8B82
|
||||||
|
#define GL_INFO_LOG_LENGTH 0x8B84
|
||||||
|
#define GL_FLOAT 0x1406
|
||||||
|
|
||||||
|
/* Draw */
|
||||||
|
#define GL_TRIANGLES 0x0004
|
||||||
|
#define GL_ARRAY_BUFFER 0x8892
|
||||||
|
#define GL_STATIC_DRAW 0x88E4
|
||||||
|
|
||||||
|
/* -------------------- Function declarations -------------------- */
|
||||||
|
|
||||||
|
/* Core 1.0 */
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLCLEARPROC)(GLbitfield mask);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLCLEARCOLORPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLENABLEPROC)(GLenum cap);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLDISABLEPROC)(GLenum cap);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLVIEWPORTPROC)(GLint x, GLint y, GLsizei width, GLsizei height);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLTEXIMAGE2DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLTEXPARAMETERIPROC)(GLenum target, GLenum pname, GLint param);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLBINDTEXTUREPROC)(GLenum target, GLuint texture);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLDELETETEXTURESPROC)(GLsizei n, const GLuint *textures);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLGENTEXTURESPROC)(GLsizei n, GLuint *textures);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLDRAWARRAYSPROC)(GLenum mode, GLint first, GLsizei count);
|
||||||
|
typedef const GLubyte *(KHRONOS_APIENTRY *PFNGLGETSTRINGPROC)(GLenum name);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLGETINTEGERVPROC)(GLenum pname, GLint *data);
|
||||||
|
|
||||||
|
/* Core 1.3 */
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLACTIVETEXTUREPROC)(GLenum texture);
|
||||||
|
|
||||||
|
/* Core 1.5 */
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLGENBUFFERSPROC)(GLsizei n, GLuint *buffers);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLDELETEBUFFERSPROC)(GLsizei n, const GLuint *buffers);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLBINDBUFFERPROC)(GLenum target, GLuint buffer);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLBUFFERDATAPROC)(GLenum target, GLsizeiptr size, const void *data, GLenum usage);
|
||||||
|
|
||||||
|
/* Core 2.0 */
|
||||||
|
typedef GLuint (KHRONOS_APIENTRY *PFNGLCREATESHADERPROC)(GLenum type);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLDELETESHADERPROC)(GLuint shader);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLSHADERSOURCEPROC)(GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLCOMPILESHADERPROC)(GLuint shader);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLGETSHADERIVPROC)(GLuint shader, GLenum pname, GLint *params);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLGETSHADERINFOLOGPROC)(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
|
||||||
|
typedef GLuint (KHRONOS_APIENTRY *PFNGLCREATEPROGRAMPROC)(void);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLDELETEPROGRAMPROC)(GLuint program);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLATTACHSHADERPROC)(GLuint program, GLuint shader);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLLINKPROGRAMPROC)(GLuint program);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLGETPROGRAMIVPROC)(GLuint program, GLenum pname, GLint *params);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLGETPROGRAMINFOLOGPROC)(GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLUSEPROGRAMPROC)(GLuint program);
|
||||||
|
typedef GLint (KHRONOS_APIENTRY *PFNGLGETUNIFORMLOCATIONPROC)(GLuint program, const GLchar *name);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLUNIFORM1IPROC)(GLint location, GLint v0);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLUNIFORM1FPROC)(GLint location, GLfloat v0);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLUNIFORM2FPROC)(GLint location, GLfloat v0, GLfloat v1);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLUNIFORM4FPROC)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLUNIFORMMATRIX4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLBINDATTRIBLOCATIONPROC)(GLuint program, GLuint index, const GLchar *name);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLDETACHSHADERPROC)(GLuint program, GLuint shader);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLVERTEXATTRIBPOINTERPROC)(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLENABLEVERTEXATTRIBARRAYPROC)(GLuint index);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLDISABLEVERTEXATTRIBARRAYPROC)(GLuint index);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLBLENDFUNCPROC)(GLenum sfactor, GLenum dfactor);
|
||||||
|
|
||||||
|
/* Core 3.0 - Framebuffer */
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLGENFRAMEBUFFERSPROC)(GLsizei n, GLuint *framebuffers);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLDELETEFRAMEBUFFERSPROC)(GLsizei n, const GLuint *framebuffers);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLBINDFRAMEBUFFERPROC)(GLenum target, GLuint framebuffer);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLFRAMEBUFFERTEXTURE2DPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
|
||||||
|
typedef GLenum (KHRONOS_APIENTRY *PFNGLCHECKFRAMEBUFFERSTATUSPROC)(GLenum target);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLGENRENDERBUFFERSPROC)(GLsizei n, GLuint *renderbuffers);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLDELETERENDERBUFFERSPROC)(GLsizei n, const GLuint *renderbuffers);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLBINDRENDERBUFFERPROC)(GLenum target, GLuint renderbuffer);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLRENDERBUFFERSTORAGEPROC)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLFRAMEBUFFERRENDERBUFFERPROC)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLBLITFRAMEBUFFERPROC)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
|
||||||
|
|
||||||
|
/* Core 3.0 - Mipmap */
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLGENERATEMIPMAPPROC)(GLenum target);
|
||||||
|
|
||||||
|
/* Core 3.0 - VAO */
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLGENVERTEXARRAYSPROC)(GLsizei n, GLuint *arrays);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLDELETEVERTEXARRAYSPROC)(GLsizei n, const GLuint *arrays);
|
||||||
|
typedef void (KHRONOS_APIENTRY *PFNGLBINDVERTEXARRAYPROC)(GLuint array);
|
||||||
|
|
||||||
|
/* -------------------- Function pointers -------------------- */
|
||||||
|
|
||||||
|
/* Core 1.0 */
|
||||||
|
extern PFNGLCLEARPROC glad_glClear;
|
||||||
|
#define glClear glad_glClear
|
||||||
|
extern PFNGLCLEARCOLORPROC glad_glClearColor;
|
||||||
|
#define glClearColor glad_glClearColor
|
||||||
|
extern PFNGLENABLEPROC glad_glEnable;
|
||||||
|
#define glEnable glad_glEnable
|
||||||
|
extern PFNGLDISABLEPROC glad_glDisable;
|
||||||
|
#define glDisable glad_glDisable
|
||||||
|
extern PFNGLVIEWPORTPROC glad_glViewport;
|
||||||
|
#define glViewport glad_glViewport
|
||||||
|
extern PFNGLTEXIMAGE2DPROC glad_glTexImage2D;
|
||||||
|
#define glTexImage2D glad_glTexImage2D
|
||||||
|
extern PFNGLTEXPARAMETERIPROC glad_glTexParameteri;
|
||||||
|
#define glTexParameteri glad_glTexParameteri
|
||||||
|
extern PFNGLBINDTEXTUREPROC glad_glBindTexture;
|
||||||
|
#define glBindTexture glad_glBindTexture
|
||||||
|
extern PFNGLDELETETEXTURESPROC glad_glDeleteTextures;
|
||||||
|
#define glDeleteTextures glad_glDeleteTextures
|
||||||
|
extern PFNGLGENTEXTURESPROC glad_glGenTextures;
|
||||||
|
#define glGenTextures glad_glGenTextures
|
||||||
|
extern PFNGLDRAWARRAYSPROC glad_glDrawArrays;
|
||||||
|
#define glDrawArrays glad_glDrawArrays
|
||||||
|
extern PFNGLGETSTRINGPROC glad_glGetString;
|
||||||
|
#define glGetString glad_glGetString
|
||||||
|
extern PFNGLGETINTEGERVPROC glad_glGetIntegerv;
|
||||||
|
#define glGetIntegerv glad_glGetIntegerv
|
||||||
|
extern PFNGLBLENDFUNCPROC glad_glBlendFunc;
|
||||||
|
#define glBlendFunc glad_glBlendFunc
|
||||||
|
|
||||||
|
/* Core 1.3 */
|
||||||
|
extern PFNGLACTIVETEXTUREPROC glad_glActiveTexture;
|
||||||
|
#define glActiveTexture glad_glActiveTexture
|
||||||
|
|
||||||
|
/* Core 1.5 */
|
||||||
|
extern PFNGLGENBUFFERSPROC glad_glGenBuffers;
|
||||||
|
#define glGenBuffers glad_glGenBuffers
|
||||||
|
extern PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers;
|
||||||
|
#define glDeleteBuffers glad_glDeleteBuffers
|
||||||
|
extern PFNGLBINDBUFFERPROC glad_glBindBuffer;
|
||||||
|
#define glBindBuffer glad_glBindBuffer
|
||||||
|
extern PFNGLBUFFERDATAPROC glad_glBufferData;
|
||||||
|
#define glBufferData glad_glBufferData
|
||||||
|
|
||||||
|
/* Core 2.0 */
|
||||||
|
extern PFNGLCREATESHADERPROC glad_glCreateShader;
|
||||||
|
#define glCreateShader glad_glCreateShader
|
||||||
|
extern PFNGLDELETESHADERPROC glad_glDeleteShader;
|
||||||
|
#define glDeleteShader glad_glDeleteShader
|
||||||
|
extern PFNGLSHADERSOURCEPROC glad_glShaderSource;
|
||||||
|
#define glShaderSource glad_glShaderSource
|
||||||
|
extern PFNGLCOMPILESHADERPROC glad_glCompileShader;
|
||||||
|
#define glCompileShader glad_glCompileShader
|
||||||
|
extern PFNGLGETSHADERIVPROC glad_glGetShaderiv;
|
||||||
|
#define glGetShaderiv glad_glGetShaderiv
|
||||||
|
extern PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog;
|
||||||
|
#define glGetShaderInfoLog glad_glGetShaderInfoLog
|
||||||
|
extern PFNGLCREATEPROGRAMPROC glad_glCreateProgram;
|
||||||
|
#define glCreateProgram glad_glCreateProgram
|
||||||
|
extern PFNGLDELETEPROGRAMPROC glad_glDeleteProgram;
|
||||||
|
#define glDeleteProgram glad_glDeleteProgram
|
||||||
|
extern PFNGLATTACHSHADERPROC glad_glAttachShader;
|
||||||
|
#define glAttachShader glad_glAttachShader
|
||||||
|
extern PFNGLLINKPROGRAMPROC glad_glLinkProgram;
|
||||||
|
#define glLinkProgram glad_glLinkProgram
|
||||||
|
extern PFNGLGETPROGRAMIVPROC glad_glGetProgramiv;
|
||||||
|
#define glGetProgramiv glad_glGetProgramiv
|
||||||
|
extern PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog;
|
||||||
|
#define glGetProgramInfoLog glad_glGetProgramInfoLog
|
||||||
|
extern PFNGLUSEPROGRAMPROC glad_glUseProgram;
|
||||||
|
#define glUseProgram glad_glUseProgram
|
||||||
|
extern PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation;
|
||||||
|
#define glGetUniformLocation glad_glGetUniformLocation
|
||||||
|
extern PFNGLUNIFORM1IPROC glad_glUniform1i;
|
||||||
|
#define glUniform1i glad_glUniform1i
|
||||||
|
extern PFNGLUNIFORM1FPROC glad_glUniform1f;
|
||||||
|
#define glUniform1f glad_glUniform1f
|
||||||
|
extern PFNGLUNIFORM2FPROC glad_glUniform2f;
|
||||||
|
#define glUniform2f glad_glUniform2f
|
||||||
|
extern PFNGLUNIFORM4FPROC glad_glUniform4f;
|
||||||
|
#define glUniform4f glad_glUniform4f
|
||||||
|
extern PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv;
|
||||||
|
#define glUniformMatrix4fv glad_glUniformMatrix4fv
|
||||||
|
extern PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation;
|
||||||
|
#define glBindAttribLocation glad_glBindAttribLocation
|
||||||
|
extern PFNGLDETACHSHADERPROC glad_glDetachShader;
|
||||||
|
#define glDetachShader glad_glDetachShader
|
||||||
|
extern PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer;
|
||||||
|
#define glVertexAttribPointer glad_glVertexAttribPointer
|
||||||
|
extern PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray;
|
||||||
|
#define glEnableVertexAttribArray glad_glEnableVertexAttribArray
|
||||||
|
extern PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray;
|
||||||
|
#define glDisableVertexAttribArray glad_glDisableVertexAttribArray
|
||||||
|
|
||||||
|
/* Core 3.0 - Framebuffer */
|
||||||
|
extern PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers;
|
||||||
|
#define glGenFramebuffers glad_glGenFramebuffers
|
||||||
|
extern PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers;
|
||||||
|
#define glDeleteFramebuffers glad_glDeleteFramebuffers
|
||||||
|
extern PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer;
|
||||||
|
#define glBindFramebuffer glad_glBindFramebuffer
|
||||||
|
extern PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D;
|
||||||
|
#define glFramebufferTexture2D glad_glFramebufferTexture2D
|
||||||
|
extern PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus;
|
||||||
|
#define glCheckFramebufferStatus glad_glCheckFramebufferStatus
|
||||||
|
extern PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers;
|
||||||
|
#define glGenRenderbuffers glad_glGenRenderbuffers
|
||||||
|
extern PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers;
|
||||||
|
#define glDeleteRenderbuffers glad_glDeleteRenderbuffers
|
||||||
|
extern PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer;
|
||||||
|
#define glBindRenderbuffer glad_glBindRenderbuffer
|
||||||
|
extern PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage;
|
||||||
|
#define glRenderbufferStorage glad_glRenderbufferStorage
|
||||||
|
extern PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer;
|
||||||
|
#define glFramebufferRenderbuffer glad_glFramebufferRenderbuffer
|
||||||
|
extern PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer;
|
||||||
|
#define glBlitFramebuffer glad_glBlitFramebuffer
|
||||||
|
|
||||||
|
/* Core 3.0 - Mipmap */
|
||||||
|
extern PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap;
|
||||||
|
#define glGenerateMipmap glad_glGenerateMipmap
|
||||||
|
|
||||||
|
/* Core 3.0 - VAO */
|
||||||
|
extern PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays;
|
||||||
|
#define glGenVertexArrays glad_glGenVertexArrays
|
||||||
|
extern PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays;
|
||||||
|
#define glDeleteVertexArrays glad_glDeleteVertexArrays
|
||||||
|
extern PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray;
|
||||||
|
#define glBindVertexArray glad_glBindVertexArray
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* GLAD_GL_H_ */
|
||||||
290
libs/glad/src/gl.c
Normal file
@@ -0,0 +1,290 @@
|
|||||||
|
/**
|
||||||
|
* GLAD - OpenGL Loader Generator
|
||||||
|
* Generated for OpenGL 3.3 Core Profile
|
||||||
|
*
|
||||||
|
* This file implements the OpenGL function loader for the acrylic effects system.
|
||||||
|
* It loads function pointers at runtime, making the binary self-contained.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <glad/gl.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/* Feature flags */
|
||||||
|
int GLAD_GL_VERSION_1_0 = 0;
|
||||||
|
int GLAD_GL_VERSION_1_1 = 0;
|
||||||
|
int GLAD_GL_VERSION_1_2 = 0;
|
||||||
|
int GLAD_GL_VERSION_1_3 = 0;
|
||||||
|
int GLAD_GL_VERSION_1_4 = 0;
|
||||||
|
int GLAD_GL_VERSION_1_5 = 0;
|
||||||
|
int GLAD_GL_VERSION_2_0 = 0;
|
||||||
|
int GLAD_GL_VERSION_2_1 = 0;
|
||||||
|
int GLAD_GL_VERSION_3_0 = 0;
|
||||||
|
int GLAD_GL_VERSION_3_1 = 0;
|
||||||
|
int GLAD_GL_VERSION_3_2 = 0;
|
||||||
|
int GLAD_GL_VERSION_3_3 = 0;
|
||||||
|
|
||||||
|
/* Function pointers - Core 1.0 */
|
||||||
|
PFNGLCLEARPROC glad_glClear = NULL;
|
||||||
|
PFNGLCLEARCOLORPROC glad_glClearColor = NULL;
|
||||||
|
PFNGLENABLEPROC glad_glEnable = NULL;
|
||||||
|
PFNGLDISABLEPROC glad_glDisable = NULL;
|
||||||
|
PFNGLVIEWPORTPROC glad_glViewport = NULL;
|
||||||
|
PFNGLTEXIMAGE2DPROC glad_glTexImage2D = NULL;
|
||||||
|
PFNGLTEXPARAMETERIPROC glad_glTexParameteri = NULL;
|
||||||
|
PFNGLBINDTEXTUREPROC glad_glBindTexture = NULL;
|
||||||
|
PFNGLDELETETEXTURESPROC glad_glDeleteTextures = NULL;
|
||||||
|
PFNGLGENTEXTURESPROC glad_glGenTextures = NULL;
|
||||||
|
PFNGLDRAWARRAYSPROC glad_glDrawArrays = NULL;
|
||||||
|
PFNGLGETSTRINGPROC glad_glGetString = NULL;
|
||||||
|
PFNGLGETINTEGERVPROC glad_glGetIntegerv = NULL;
|
||||||
|
PFNGLBLENDFUNCPROC glad_glBlendFunc = NULL;
|
||||||
|
|
||||||
|
/* Function pointers - Core 1.3 */
|
||||||
|
PFNGLACTIVETEXTUREPROC glad_glActiveTexture = NULL;
|
||||||
|
|
||||||
|
/* Function pointers - Core 1.5 */
|
||||||
|
PFNGLGENBUFFERSPROC glad_glGenBuffers = NULL;
|
||||||
|
PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers = NULL;
|
||||||
|
PFNGLBINDBUFFERPROC glad_glBindBuffer = NULL;
|
||||||
|
PFNGLBUFFERDATAPROC glad_glBufferData = NULL;
|
||||||
|
|
||||||
|
/* Function pointers - Core 2.0 */
|
||||||
|
PFNGLCREATESHADERPROC glad_glCreateShader = NULL;
|
||||||
|
PFNGLDELETESHADERPROC glad_glDeleteShader = NULL;
|
||||||
|
PFNGLSHADERSOURCEPROC glad_glShaderSource = NULL;
|
||||||
|
PFNGLCOMPILESHADERPROC glad_glCompileShader = NULL;
|
||||||
|
PFNGLGETSHADERIVPROC glad_glGetShaderiv = NULL;
|
||||||
|
PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog = NULL;
|
||||||
|
PFNGLCREATEPROGRAMPROC glad_glCreateProgram = NULL;
|
||||||
|
PFNGLDELETEPROGRAMPROC glad_glDeleteProgram = NULL;
|
||||||
|
PFNGLATTACHSHADERPROC glad_glAttachShader = NULL;
|
||||||
|
PFNGLLINKPROGRAMPROC glad_glLinkProgram = NULL;
|
||||||
|
PFNGLGETPROGRAMIVPROC glad_glGetProgramiv = NULL;
|
||||||
|
PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog = NULL;
|
||||||
|
PFNGLUSEPROGRAMPROC glad_glUseProgram = NULL;
|
||||||
|
PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation = NULL;
|
||||||
|
PFNGLUNIFORM1IPROC glad_glUniform1i = NULL;
|
||||||
|
PFNGLUNIFORM1FPROC glad_glUniform1f = NULL;
|
||||||
|
PFNGLUNIFORM2FPROC glad_glUniform2f = NULL;
|
||||||
|
PFNGLUNIFORM4FPROC glad_glUniform4f = NULL;
|
||||||
|
PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv = NULL;
|
||||||
|
PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation = NULL;
|
||||||
|
PFNGLDETACHSHADERPROC glad_glDetachShader = NULL;
|
||||||
|
PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer = NULL;
|
||||||
|
PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray = NULL;
|
||||||
|
PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray = NULL;
|
||||||
|
|
||||||
|
/* Function pointers - Core 3.0 Framebuffer */
|
||||||
|
PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers = NULL;
|
||||||
|
PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers = NULL;
|
||||||
|
PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer = NULL;
|
||||||
|
PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D = NULL;
|
||||||
|
PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus = NULL;
|
||||||
|
PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers = NULL;
|
||||||
|
PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers = NULL;
|
||||||
|
PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer = NULL;
|
||||||
|
PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage = NULL;
|
||||||
|
PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer = NULL;
|
||||||
|
PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer = NULL;
|
||||||
|
|
||||||
|
/* Function pointers - Core 3.0 Mipmap */
|
||||||
|
PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap = NULL;
|
||||||
|
|
||||||
|
/* Function pointers - Core 3.0 VAO */
|
||||||
|
PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays = NULL;
|
||||||
|
PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays = NULL;
|
||||||
|
PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray = NULL;
|
||||||
|
|
||||||
|
/* Parse GL version string to extract major.minor */
|
||||||
|
static void glad_parse_version(const char* version, int* major, int* minor) {
|
||||||
|
const char* p = version;
|
||||||
|
|
||||||
|
/* Skip "OpenGL ES " prefix if present */
|
||||||
|
if (version[0] == 'O') {
|
||||||
|
while (*p && *p != ' ') p++;
|
||||||
|
if (*p == ' ') p++;
|
||||||
|
if (*p == 'E') {
|
||||||
|
while (*p && *p != ' ') p++;
|
||||||
|
if (*p == ' ') p++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*major = 0;
|
||||||
|
*minor = 0;
|
||||||
|
|
||||||
|
/* Parse major version */
|
||||||
|
while (*p >= '0' && *p <= '9') {
|
||||||
|
*major = *major * 10 + (*p - '0');
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Skip dot */
|
||||||
|
if (*p == '.') p++;
|
||||||
|
|
||||||
|
/* Parse minor version */
|
||||||
|
while (*p >= '0' && *p <= '9') {
|
||||||
|
*minor = *minor * 10 + (*p - '0');
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load Core 1.0 functions */
|
||||||
|
static int glad_load_gl_1_0(GLADloadfunc load) {
|
||||||
|
glad_glClear = (PFNGLCLEARPROC)load("glClear");
|
||||||
|
glad_glClearColor = (PFNGLCLEARCOLORPROC)load("glClearColor");
|
||||||
|
glad_glEnable = (PFNGLENABLEPROC)load("glEnable");
|
||||||
|
glad_glDisable = (PFNGLDISABLEPROC)load("glDisable");
|
||||||
|
glad_glViewport = (PFNGLVIEWPORTPROC)load("glViewport");
|
||||||
|
glad_glTexImage2D = (PFNGLTEXIMAGE2DPROC)load("glTexImage2D");
|
||||||
|
glad_glTexParameteri = (PFNGLTEXPARAMETERIPROC)load("glTexParameteri");
|
||||||
|
glad_glBindTexture = (PFNGLBINDTEXTUREPROC)load("glBindTexture");
|
||||||
|
glad_glDeleteTextures = (PFNGLDELETETEXTURESPROC)load("glDeleteTextures");
|
||||||
|
glad_glGenTextures = (PFNGLGENTEXTURESPROC)load("glGenTextures");
|
||||||
|
glad_glDrawArrays = (PFNGLDRAWARRAYSPROC)load("glDrawArrays");
|
||||||
|
glad_glGetString = (PFNGLGETSTRINGPROC)load("glGetString");
|
||||||
|
glad_glGetIntegerv = (PFNGLGETINTEGERVPROC)load("glGetIntegerv");
|
||||||
|
glad_glBlendFunc = (PFNGLBLENDFUNCPROC)load("glBlendFunc");
|
||||||
|
|
||||||
|
return glad_glClear && glad_glClearColor && glad_glEnable && glad_glDisable &&
|
||||||
|
glad_glViewport && glad_glTexImage2D && glad_glTexParameteri &&
|
||||||
|
glad_glBindTexture && glad_glDeleteTextures && glad_glGenTextures &&
|
||||||
|
glad_glDrawArrays && glad_glGetString && glad_glGetIntegerv && glad_glBlendFunc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load Core 1.3 functions */
|
||||||
|
static int glad_load_gl_1_3(GLADloadfunc load) {
|
||||||
|
glad_glActiveTexture = (PFNGLACTIVETEXTUREPROC)load("glActiveTexture");
|
||||||
|
return glad_glActiveTexture != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load Core 1.5 functions */
|
||||||
|
static int glad_load_gl_1_5(GLADloadfunc load) {
|
||||||
|
glad_glGenBuffers = (PFNGLGENBUFFERSPROC)load("glGenBuffers");
|
||||||
|
glad_glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)load("glDeleteBuffers");
|
||||||
|
glad_glBindBuffer = (PFNGLBINDBUFFERPROC)load("glBindBuffer");
|
||||||
|
glad_glBufferData = (PFNGLBUFFERDATAPROC)load("glBufferData");
|
||||||
|
|
||||||
|
return glad_glGenBuffers && glad_glDeleteBuffers &&
|
||||||
|
glad_glBindBuffer && glad_glBufferData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load Core 2.0 functions */
|
||||||
|
static int glad_load_gl_2_0(GLADloadfunc load) {
|
||||||
|
glad_glCreateShader = (PFNGLCREATESHADERPROC)load("glCreateShader");
|
||||||
|
glad_glDeleteShader = (PFNGLDELETESHADERPROC)load("glDeleteShader");
|
||||||
|
glad_glShaderSource = (PFNGLSHADERSOURCEPROC)load("glShaderSource");
|
||||||
|
glad_glCompileShader = (PFNGLCOMPILESHADERPROC)load("glCompileShader");
|
||||||
|
glad_glGetShaderiv = (PFNGLGETSHADERIVPROC)load("glGetShaderiv");
|
||||||
|
glad_glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)load("glGetShaderInfoLog");
|
||||||
|
glad_glCreateProgram = (PFNGLCREATEPROGRAMPROC)load("glCreateProgram");
|
||||||
|
glad_glDeleteProgram = (PFNGLDELETEPROGRAMPROC)load("glDeleteProgram");
|
||||||
|
glad_glAttachShader = (PFNGLATTACHSHADERPROC)load("glAttachShader");
|
||||||
|
glad_glLinkProgram = (PFNGLLINKPROGRAMPROC)load("glLinkProgram");
|
||||||
|
glad_glGetProgramiv = (PFNGLGETPROGRAMIVPROC)load("glGetProgramiv");
|
||||||
|
glad_glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)load("glGetProgramInfoLog");
|
||||||
|
glad_glUseProgram = (PFNGLUSEPROGRAMPROC)load("glUseProgram");
|
||||||
|
glad_glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)load("glGetUniformLocation");
|
||||||
|
glad_glUniform1i = (PFNGLUNIFORM1IPROC)load("glUniform1i");
|
||||||
|
glad_glUniform1f = (PFNGLUNIFORM1FPROC)load("glUniform1f");
|
||||||
|
glad_glUniform2f = (PFNGLUNIFORM2FPROC)load("glUniform2f");
|
||||||
|
glad_glUniform4f = (PFNGLUNIFORM4FPROC)load("glUniform4f");
|
||||||
|
glad_glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)load("glUniformMatrix4fv");
|
||||||
|
glad_glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC)load("glBindAttribLocation");
|
||||||
|
glad_glDetachShader = (PFNGLDETACHSHADERPROC)load("glDetachShader");
|
||||||
|
glad_glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)load("glVertexAttribPointer");
|
||||||
|
glad_glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)load("glEnableVertexAttribArray");
|
||||||
|
glad_glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)load("glDisableVertexAttribArray");
|
||||||
|
|
||||||
|
return glad_glCreateShader && glad_glDeleteShader && glad_glShaderSource &&
|
||||||
|
glad_glCompileShader && glad_glGetShaderiv && glad_glGetShaderInfoLog &&
|
||||||
|
glad_glCreateProgram && glad_glDeleteProgram && glad_glAttachShader &&
|
||||||
|
glad_glLinkProgram && glad_glGetProgramiv && glad_glGetProgramInfoLog &&
|
||||||
|
glad_glUseProgram && glad_glGetUniformLocation && glad_glUniform1i &&
|
||||||
|
glad_glUniform1f && glad_glUniform2f && glad_glUniform4f &&
|
||||||
|
glad_glUniformMatrix4fv && glad_glBindAttribLocation && glad_glDetachShader &&
|
||||||
|
glad_glVertexAttribPointer && glad_glEnableVertexAttribArray &&
|
||||||
|
glad_glDisableVertexAttribArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load Core 3.0 functions (framebuffer and VAO) */
|
||||||
|
static int glad_load_gl_3_0(GLADloadfunc load) {
|
||||||
|
/* Framebuffer functions */
|
||||||
|
glad_glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)load("glGenFramebuffers");
|
||||||
|
glad_glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)load("glDeleteFramebuffers");
|
||||||
|
glad_glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)load("glBindFramebuffer");
|
||||||
|
glad_glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)load("glFramebufferTexture2D");
|
||||||
|
glad_glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)load("glCheckFramebufferStatus");
|
||||||
|
glad_glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)load("glGenRenderbuffers");
|
||||||
|
glad_glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)load("glDeleteRenderbuffers");
|
||||||
|
glad_glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)load("glBindRenderbuffer");
|
||||||
|
glad_glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)load("glRenderbufferStorage");
|
||||||
|
glad_glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)load("glFramebufferRenderbuffer");
|
||||||
|
glad_glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC)load("glBlitFramebuffer");
|
||||||
|
|
||||||
|
/* Mipmap */
|
||||||
|
glad_glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC)load("glGenerateMipmap");
|
||||||
|
|
||||||
|
/* VAO functions */
|
||||||
|
glad_glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)load("glGenVertexArrays");
|
||||||
|
glad_glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC)load("glDeleteVertexArrays");
|
||||||
|
glad_glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)load("glBindVertexArray");
|
||||||
|
|
||||||
|
return glad_glGenFramebuffers && glad_glDeleteFramebuffers &&
|
||||||
|
glad_glBindFramebuffer && glad_glFramebufferTexture2D &&
|
||||||
|
glad_glCheckFramebufferStatus && glad_glGenRenderbuffers &&
|
||||||
|
glad_glDeleteRenderbuffers && glad_glBindRenderbuffer &&
|
||||||
|
glad_glRenderbufferStorage && glad_glFramebufferRenderbuffer &&
|
||||||
|
glad_glBlitFramebuffer && glad_glGenVertexArrays &&
|
||||||
|
glad_glDeleteVertexArrays && glad_glBindVertexArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize GLAD loader
|
||||||
|
*
|
||||||
|
* @param load Function pointer to load GL function pointers (e.g., SDL_GL_GetProcAddress)
|
||||||
|
* @return GL version (major * 10000 + minor), or 0 on failure
|
||||||
|
*/
|
||||||
|
int gladLoadGL(GLADloadfunc load) {
|
||||||
|
int major = 0, minor = 0;
|
||||||
|
const char* version;
|
||||||
|
|
||||||
|
if (load == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* First, we need glGetString to get the version */
|
||||||
|
glad_glGetString = (PFNGLGETSTRINGPROC)load("glGetString");
|
||||||
|
if (glad_glGetString == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
version = (const char*)glad_glGetString(0x1F02); /* GL_VERSION */
|
||||||
|
if (version == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
glad_parse_version(version, &major, &minor);
|
||||||
|
|
||||||
|
/* Set version flags */
|
||||||
|
GLAD_GL_VERSION_1_0 = (major > 1 || (major == 1 && minor >= 0));
|
||||||
|
GLAD_GL_VERSION_1_1 = (major > 1 || (major == 1 && minor >= 1));
|
||||||
|
GLAD_GL_VERSION_1_2 = (major > 1 || (major == 1 && minor >= 2));
|
||||||
|
GLAD_GL_VERSION_1_3 = (major > 1 || (major == 1 && minor >= 3));
|
||||||
|
GLAD_GL_VERSION_1_4 = (major > 1 || (major == 1 && minor >= 4));
|
||||||
|
GLAD_GL_VERSION_1_5 = (major > 1 || (major == 1 && minor >= 5));
|
||||||
|
GLAD_GL_VERSION_2_0 = (major > 2 || (major == 2 && minor >= 0));
|
||||||
|
GLAD_GL_VERSION_2_1 = (major > 2 || (major == 2 && minor >= 1));
|
||||||
|
GLAD_GL_VERSION_3_0 = (major > 3 || (major == 3 && minor >= 0));
|
||||||
|
GLAD_GL_VERSION_3_1 = (major > 3 || (major == 3 && minor >= 1));
|
||||||
|
GLAD_GL_VERSION_3_2 = (major > 3 || (major == 3 && minor >= 2));
|
||||||
|
GLAD_GL_VERSION_3_3 = (major > 3 || (major == 3 && minor >= 3));
|
||||||
|
|
||||||
|
/* Load functions by version */
|
||||||
|
if (GLAD_GL_VERSION_1_0 && !glad_load_gl_1_0(load)) return 0;
|
||||||
|
if (GLAD_GL_VERSION_1_3 && !glad_load_gl_1_3(load)) return 0;
|
||||||
|
if (GLAD_GL_VERSION_1_5 && !glad_load_gl_1_5(load)) return 0;
|
||||||
|
if (GLAD_GL_VERSION_2_0 && !glad_load_gl_2_0(load)) return 0;
|
||||||
|
if (GLAD_GL_VERSION_3_0 && !glad_load_gl_3_0(load)) return 0;
|
||||||
|
|
||||||
|
return major * 10000 + minor;
|
||||||
|
}
|
||||||
21
libs/imgui/LICENSE.txt
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2014-2026 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.
|
||||||
843
libs/imgui/backends/imgui_impl_dx11.cpp
Normal file
@@ -0,0 +1,843 @@
|
|||||||
|
// dear imgui: Renderer Backend for DirectX11
|
||||||
|
// This needs to be used along with a Platform Backend (e.g. Win32)
|
||||||
|
|
||||||
|
// Implemented features:
|
||||||
|
// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
||||||
|
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||||
|
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||||
|
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||||
|
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||||
|
|
||||||
|
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||||
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
|
// Learn about Dear ImGui:
|
||||||
|
// - FAQ https://dearimgui.com/faq
|
||||||
|
// - Getting Started https://dearimgui.com/getting-started
|
||||||
|
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||||
|
// - Introduction, links and more at the top of imgui.cpp
|
||||||
|
|
||||||
|
// CHANGELOG
|
||||||
|
// (minor and older changes stripped away, please see git history for details)
|
||||||
|
// 2026-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||||
|
// 2026-01-19: DirectX11: Added 'SamplerNearest' in ImGui_ImplDX11_RenderState. Renamed 'SamplerDefault' to 'SamplerLinear'.
|
||||||
|
// 2025-09-18: Call platform_io.ClearRendererHandlers() on shutdown.
|
||||||
|
// 2025-06-11: DirectX11: Added support for ImGuiBackendFlags_RendererHasTextures, for dynamic font atlas.
|
||||||
|
// 2025-05-07: DirectX11: Honor draw_data->FramebufferScale to allow for custom backends and experiment using it (consistently with other renderer backends, even though in normal condition it is not set under Windows).
|
||||||
|
// 2025-02-24: [Docking] Added undocumented ImGui_ImplDX11_SetSwapChainDescs() to configure swap chain creation for secondary viewports.
|
||||||
|
// 2025-01-06: DirectX11: Expose VertexConstantBuffer in ImGui_ImplDX11_RenderState. Reset projection matrix in ImDrawCallback_ResetRenderState handler.
|
||||||
|
// 2024-10-07: DirectX11: Changed default texture sampler to Clamp instead of Repeat/Wrap.
|
||||||
|
// 2024-10-07: DirectX11: Expose selected render state in ImGui_ImplDX11_RenderState, which you can access in 'void* platform_io.Renderer_RenderState' during draw callbacks.
|
||||||
|
// 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11.
|
||||||
|
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
||||||
|
// 2021-05-19: DirectX11: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
||||||
|
// 2021-02-18: DirectX11: Change blending equation to preserve alpha in output buffer.
|
||||||
|
// 2019-08-01: DirectX11: Fixed code querying the Geometry Shader state (would generally error with Debug layer enabled).
|
||||||
|
// 2019-07-21: DirectX11: Backup, clear and restore Geometry Shader is any is bound when calling ImGui_ImplDX11_RenderDrawData. Clearing Hull/Domain/Compute shaders without backup/restore.
|
||||||
|
// 2019-05-29: DirectX11: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag.
|
||||||
|
// 2019-04-30: DirectX11: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
|
||||||
|
// 2018-12-03: Misc: Added #pragma comment statement to automatically link with d3dcompiler.lib when using D3DCompile().
|
||||||
|
// 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window.
|
||||||
|
// 2018-08-01: DirectX11: Querying for IDXGIFactory instead of IDXGIFactory1 to increase compatibility.
|
||||||
|
// 2018-07-13: DirectX11: Fixed unreleased resources in Init and Shutdown functions.
|
||||||
|
// 2018-06-08: Misc: Extracted imgui_impl_dx11.cpp/.h away from the old combined DX11+Win32 example.
|
||||||
|
// 2018-06-08: DirectX11: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and clipping rectangle.
|
||||||
|
// 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplDX11_RenderDrawData() in the .h file so you can call it yourself.
|
||||||
|
// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
|
||||||
|
// 2016-05-07: DirectX11: Disabling depth-write.
|
||||||
|
|
||||||
|
#include "imgui.h"
|
||||||
|
#ifndef IMGUI_DISABLE
|
||||||
|
#include "imgui_impl_dx11.h"
|
||||||
|
|
||||||
|
// DirectX
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <d3d11.h>
|
||||||
|
#include <d3dcompiler.h>
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma comment(lib, "d3dcompiler") // Automatically link with d3dcompiler.lib as we are using D3DCompile() below.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Clang/GCC warnings with -Weverything
|
||||||
|
#if defined(__clang__)
|
||||||
|
#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast // yes, they are more terse.
|
||||||
|
#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// DirectX11 data
|
||||||
|
struct ImGui_ImplDX11_Texture
|
||||||
|
{
|
||||||
|
ID3D11Texture2D* pTexture;
|
||||||
|
ID3D11ShaderResourceView* pTextureView;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ImGui_ImplDX11_Data
|
||||||
|
{
|
||||||
|
ID3D11Device* pd3dDevice;
|
||||||
|
ID3D11DeviceContext* pd3dDeviceContext;
|
||||||
|
IDXGIFactory* pFactory;
|
||||||
|
ID3D11Buffer* pVB;
|
||||||
|
ID3D11Buffer* pIB;
|
||||||
|
ID3D11VertexShader* pVertexShader;
|
||||||
|
ID3D11InputLayout* pInputLayout;
|
||||||
|
ID3D11Buffer* pVertexConstantBuffer;
|
||||||
|
ID3D11PixelShader* pPixelShader;
|
||||||
|
ID3D11SamplerState* pTexSamplerLinear;
|
||||||
|
ID3D11SamplerState* pTexSamplerNearest;
|
||||||
|
ID3D11RasterizerState* pRasterizerState;
|
||||||
|
ID3D11BlendState* pBlendState;
|
||||||
|
ID3D11DepthStencilState* pDepthStencilState;
|
||||||
|
int VertexBufferSize;
|
||||||
|
int IndexBufferSize;
|
||||||
|
ImVector<DXGI_SWAP_CHAIN_DESC> SwapChainDescsForViewports;
|
||||||
|
|
||||||
|
ImGui_ImplDX11_Data() { memset((void*)this, 0, sizeof(*this)); VertexBufferSize = 5000; IndexBufferSize = 10000; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VERTEX_CONSTANT_BUFFER_DX11
|
||||||
|
{
|
||||||
|
float mvp[4][4];
|
||||||
|
};
|
||||||
|
|
||||||
|
// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts
|
||||||
|
// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
|
||||||
|
static ImGui_ImplDX11_Data* ImGui_ImplDX11_GetBackendData()
|
||||||
|
{
|
||||||
|
return ImGui::GetCurrentContext() ? (ImGui_ImplDX11_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Forward Declarations
|
||||||
|
static void ImGui_ImplDX11_InitMultiViewportSupport();
|
||||||
|
static void ImGui_ImplDX11_ShutdownMultiViewportSupport();
|
||||||
|
|
||||||
|
// Functions
|
||||||
|
static void ImGui_ImplDX11_SetupRenderState(const ImDrawData* draw_data, ID3D11DeviceContext* device_ctx)
|
||||||
|
{
|
||||||
|
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||||
|
|
||||||
|
// Setup viewport
|
||||||
|
D3D11_VIEWPORT vp = {};
|
||||||
|
vp.Width = draw_data->DisplaySize.x * draw_data->FramebufferScale.x;
|
||||||
|
vp.Height = draw_data->DisplaySize.y * draw_data->FramebufferScale.y;
|
||||||
|
vp.MinDepth = 0.0f;
|
||||||
|
vp.MaxDepth = 1.0f;
|
||||||
|
vp.TopLeftX = vp.TopLeftY = 0;
|
||||||
|
device_ctx->RSSetViewports(1, &vp);
|
||||||
|
|
||||||
|
// Setup orthographic projection matrix into our constant buffer
|
||||||
|
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
|
||||||
|
D3D11_MAPPED_SUBRESOURCE mapped_resource;
|
||||||
|
if (device_ctx->Map(bd->pVertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_resource) == S_OK)
|
||||||
|
{
|
||||||
|
VERTEX_CONSTANT_BUFFER_DX11* constant_buffer = (VERTEX_CONSTANT_BUFFER_DX11*)mapped_resource.pData;
|
||||||
|
float L = draw_data->DisplayPos.x;
|
||||||
|
float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
|
||||||
|
float T = draw_data->DisplayPos.y;
|
||||||
|
float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y;
|
||||||
|
float mvp[4][4] =
|
||||||
|
{
|
||||||
|
{ 2.0f/(R-L), 0.0f, 0.0f, 0.0f },
|
||||||
|
{ 0.0f, 2.0f/(T-B), 0.0f, 0.0f },
|
||||||
|
{ 0.0f, 0.0f, 0.5f, 0.0f },
|
||||||
|
{ (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f },
|
||||||
|
};
|
||||||
|
memcpy(&constant_buffer->mvp, mvp, sizeof(mvp));
|
||||||
|
device_ctx->Unmap(bd->pVertexConstantBuffer, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup shader and vertex buffers
|
||||||
|
unsigned int stride = sizeof(ImDrawVert);
|
||||||
|
unsigned int offset = 0;
|
||||||
|
device_ctx->IASetInputLayout(bd->pInputLayout);
|
||||||
|
device_ctx->IASetVertexBuffers(0, 1, &bd->pVB, &stride, &offset);
|
||||||
|
device_ctx->IASetIndexBuffer(bd->pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0);
|
||||||
|
device_ctx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||||
|
device_ctx->VSSetShader(bd->pVertexShader, nullptr, 0);
|
||||||
|
device_ctx->VSSetConstantBuffers(0, 1, &bd->pVertexConstantBuffer);
|
||||||
|
device_ctx->PSSetShader(bd->pPixelShader, nullptr, 0);
|
||||||
|
device_ctx->PSSetSamplers(0, 1, &bd->pTexSamplerLinear);
|
||||||
|
device_ctx->GSSetShader(nullptr, nullptr, 0);
|
||||||
|
device_ctx->HSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
||||||
|
device_ctx->DSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
||||||
|
device_ctx->CSSetShader(nullptr, nullptr, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
||||||
|
|
||||||
|
// Setup render state
|
||||||
|
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
|
||||||
|
device_ctx->OMSetBlendState(bd->pBlendState, blend_factor, 0xffffffff);
|
||||||
|
device_ctx->OMSetDepthStencilState(bd->pDepthStencilState, 0);
|
||||||
|
device_ctx->RSSetState(bd->pRasterizerState);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render function
|
||||||
|
void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
|
||||||
|
{
|
||||||
|
// Avoid rendering when minimized
|
||||||
|
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||||
|
ID3D11DeviceContext* device = bd->pd3dDeviceContext;
|
||||||
|
|
||||||
|
// Catch up with texture updates. Most of the times, the list will have 1 element with an OK status, aka nothing to do.
|
||||||
|
// (This almost always points to ImGui::GetPlatformIO().Textures[] but is part of ImDrawData to allow overriding or disabling texture updates).
|
||||||
|
if (draw_data->Textures != nullptr)
|
||||||
|
for (ImTextureData* tex : *draw_data->Textures)
|
||||||
|
if (tex->Status != ImTextureStatus_OK)
|
||||||
|
ImGui_ImplDX11_UpdateTexture(tex);
|
||||||
|
|
||||||
|
// Create and grow vertex/index buffers if needed
|
||||||
|
if (!bd->pVB || bd->VertexBufferSize < draw_data->TotalVtxCount)
|
||||||
|
{
|
||||||
|
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
|
||||||
|
bd->VertexBufferSize = draw_data->TotalVtxCount + 5000;
|
||||||
|
D3D11_BUFFER_DESC desc = {};
|
||||||
|
desc.Usage = D3D11_USAGE_DYNAMIC;
|
||||||
|
desc.ByteWidth = bd->VertexBufferSize * sizeof(ImDrawVert);
|
||||||
|
desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
|
||||||
|
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||||
|
desc.MiscFlags = 0;
|
||||||
|
if (bd->pd3dDevice->CreateBuffer(&desc, nullptr, &bd->pVB) < 0)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!bd->pIB || bd->IndexBufferSize < draw_data->TotalIdxCount)
|
||||||
|
{
|
||||||
|
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
|
||||||
|
bd->IndexBufferSize = draw_data->TotalIdxCount + 10000;
|
||||||
|
D3D11_BUFFER_DESC desc = {};
|
||||||
|
desc.Usage = D3D11_USAGE_DYNAMIC;
|
||||||
|
desc.ByteWidth = bd->IndexBufferSize * sizeof(ImDrawIdx);
|
||||||
|
desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
|
||||||
|
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||||
|
if (bd->pd3dDevice->CreateBuffer(&desc, nullptr, &bd->pIB) < 0)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Upload vertex/index data into a single contiguous GPU buffer
|
||||||
|
D3D11_MAPPED_SUBRESOURCE vtx_resource, idx_resource;
|
||||||
|
if (device->Map(bd->pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &vtx_resource) != S_OK)
|
||||||
|
return;
|
||||||
|
if (device->Map(bd->pIB, 0, D3D11_MAP_WRITE_DISCARD, 0, &idx_resource) != S_OK)
|
||||||
|
return;
|
||||||
|
ImDrawVert* vtx_dst = (ImDrawVert*)vtx_resource.pData;
|
||||||
|
ImDrawIdx* idx_dst = (ImDrawIdx*)idx_resource.pData;
|
||||||
|
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||||
|
{
|
||||||
|
memcpy(vtx_dst, draw_list->VtxBuffer.Data, draw_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||||
|
memcpy(idx_dst, draw_list->IdxBuffer.Data, draw_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||||
|
vtx_dst += draw_list->VtxBuffer.Size;
|
||||||
|
idx_dst += draw_list->IdxBuffer.Size;
|
||||||
|
}
|
||||||
|
device->Unmap(bd->pVB, 0);
|
||||||
|
device->Unmap(bd->pIB, 0);
|
||||||
|
|
||||||
|
// Backup DX state that will be modified to restore it afterwards (unfortunately this is very ugly looking and verbose. Close your eyes!)
|
||||||
|
struct BACKUP_DX11_STATE
|
||||||
|
{
|
||||||
|
UINT ScissorRectsCount, ViewportsCount;
|
||||||
|
D3D11_RECT ScissorRects[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE];
|
||||||
|
D3D11_VIEWPORT Viewports[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE];
|
||||||
|
ID3D11RasterizerState* RS;
|
||||||
|
ID3D11BlendState* BlendState;
|
||||||
|
FLOAT BlendFactor[4];
|
||||||
|
UINT SampleMask;
|
||||||
|
UINT StencilRef;
|
||||||
|
ID3D11DepthStencilState* DepthStencilState;
|
||||||
|
ID3D11ShaderResourceView* PSShaderResource;
|
||||||
|
ID3D11SamplerState* PSSampler;
|
||||||
|
ID3D11PixelShader* PS;
|
||||||
|
ID3D11VertexShader* VS;
|
||||||
|
ID3D11GeometryShader* GS;
|
||||||
|
UINT PSInstancesCount, VSInstancesCount, GSInstancesCount;
|
||||||
|
ID3D11ClassInstance *PSInstances[256], *VSInstances[256], *GSInstances[256]; // 256 is max according to PSSetShader documentation
|
||||||
|
D3D11_PRIMITIVE_TOPOLOGY PrimitiveTopology;
|
||||||
|
ID3D11Buffer* IndexBuffer, *VertexBuffer, *VSConstantBuffer;
|
||||||
|
UINT IndexBufferOffset, VertexBufferStride, VertexBufferOffset;
|
||||||
|
DXGI_FORMAT IndexBufferFormat;
|
||||||
|
ID3D11InputLayout* InputLayout;
|
||||||
|
};
|
||||||
|
BACKUP_DX11_STATE old = {};
|
||||||
|
old.ScissorRectsCount = old.ViewportsCount = D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE;
|
||||||
|
device->RSGetScissorRects(&old.ScissorRectsCount, old.ScissorRects);
|
||||||
|
device->RSGetViewports(&old.ViewportsCount, old.Viewports);
|
||||||
|
device->RSGetState(&old.RS);
|
||||||
|
device->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
|
||||||
|
device->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
|
||||||
|
device->PSGetShaderResources(0, 1, &old.PSShaderResource);
|
||||||
|
device->PSGetSamplers(0, 1, &old.PSSampler);
|
||||||
|
old.PSInstancesCount = old.VSInstancesCount = old.GSInstancesCount = 256;
|
||||||
|
device->PSGetShader(&old.PS, old.PSInstances, &old.PSInstancesCount);
|
||||||
|
device->VSGetShader(&old.VS, old.VSInstances, &old.VSInstancesCount);
|
||||||
|
device->VSGetConstantBuffers(0, 1, &old.VSConstantBuffer);
|
||||||
|
device->GSGetShader(&old.GS, old.GSInstances, &old.GSInstancesCount);
|
||||||
|
|
||||||
|
device->IAGetPrimitiveTopology(&old.PrimitiveTopology);
|
||||||
|
device->IAGetIndexBuffer(&old.IndexBuffer, &old.IndexBufferFormat, &old.IndexBufferOffset);
|
||||||
|
device->IAGetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset);
|
||||||
|
device->IAGetInputLayout(&old.InputLayout);
|
||||||
|
|
||||||
|
// Setup desired DX state
|
||||||
|
ImGui_ImplDX11_SetupRenderState(draw_data, device);
|
||||||
|
|
||||||
|
// Setup render state structure (for callbacks and custom texture bindings)
|
||||||
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
|
ImGui_ImplDX11_RenderState render_state;
|
||||||
|
render_state.Device = bd->pd3dDevice;
|
||||||
|
render_state.DeviceContext = bd->pd3dDeviceContext;
|
||||||
|
render_state.SamplerLinear = bd->pTexSamplerLinear;
|
||||||
|
render_state.SamplerNearest = bd->pTexSamplerNearest;
|
||||||
|
render_state.VertexConstantBuffer = bd->pVertexConstantBuffer;
|
||||||
|
platform_io.Renderer_RenderState = &render_state;
|
||||||
|
|
||||||
|
// Render command lists
|
||||||
|
// (Because we merged all buffers into a single one, we maintain our own offset into them)
|
||||||
|
int global_idx_offset = 0;
|
||||||
|
int global_vtx_offset = 0;
|
||||||
|
ImVec2 clip_off = draw_data->DisplayPos;
|
||||||
|
ImVec2 clip_scale = draw_data->FramebufferScale;
|
||||||
|
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||||
|
{
|
||||||
|
for (int cmd_i = 0; cmd_i < draw_list->CmdBuffer.Size; cmd_i++)
|
||||||
|
{
|
||||||
|
const ImDrawCmd* pcmd = &draw_list->CmdBuffer[cmd_i];
|
||||||
|
if (pcmd->UserCallback != nullptr)
|
||||||
|
{
|
||||||
|
// User callback, registered via ImDrawList::AddCallback()
|
||||||
|
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
|
||||||
|
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||||
|
ImGui_ImplDX11_SetupRenderState(draw_data, device);
|
||||||
|
else
|
||||||
|
pcmd->UserCallback(draw_list, pcmd);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Project scissor/clipping rectangles into framebuffer space
|
||||||
|
ImVec2 clip_min((pcmd->ClipRect.x - clip_off.x) * clip_scale.x, (pcmd->ClipRect.y - clip_off.y) * clip_scale.y);
|
||||||
|
ImVec2 clip_max((pcmd->ClipRect.z - clip_off.x) * clip_scale.x, (pcmd->ClipRect.w - clip_off.y) * clip_scale.y);
|
||||||
|
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Apply scissor/clipping rectangle
|
||||||
|
const D3D11_RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y };
|
||||||
|
device->RSSetScissorRects(1, &r);
|
||||||
|
|
||||||
|
// Bind texture, Draw
|
||||||
|
ID3D11ShaderResourceView* texture_srv = (ID3D11ShaderResourceView*)pcmd->GetTexID();
|
||||||
|
device->PSSetShaderResources(0, 1, &texture_srv);
|
||||||
|
device->DrawIndexed(pcmd->ElemCount, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
global_idx_offset += draw_list->IdxBuffer.Size;
|
||||||
|
global_vtx_offset += draw_list->VtxBuffer.Size;
|
||||||
|
}
|
||||||
|
platform_io.Renderer_RenderState = nullptr;
|
||||||
|
|
||||||
|
// Restore modified DX state
|
||||||
|
device->RSSetScissorRects(old.ScissorRectsCount, old.ScissorRects);
|
||||||
|
device->RSSetViewports(old.ViewportsCount, old.Viewports);
|
||||||
|
device->RSSetState(old.RS); if (old.RS) old.RS->Release();
|
||||||
|
device->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
|
||||||
|
device->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
|
||||||
|
device->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
|
||||||
|
device->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
|
||||||
|
device->PSSetShader(old.PS, old.PSInstances, old.PSInstancesCount); if (old.PS) old.PS->Release();
|
||||||
|
for (UINT i = 0; i < old.PSInstancesCount; i++) if (old.PSInstances[i]) old.PSInstances[i]->Release();
|
||||||
|
device->VSSetShader(old.VS, old.VSInstances, old.VSInstancesCount); if (old.VS) old.VS->Release();
|
||||||
|
device->VSSetConstantBuffers(0, 1, &old.VSConstantBuffer); if (old.VSConstantBuffer) old.VSConstantBuffer->Release();
|
||||||
|
device->GSSetShader(old.GS, old.GSInstances, old.GSInstancesCount); if (old.GS) old.GS->Release();
|
||||||
|
for (UINT i = 0; i < old.VSInstancesCount; i++) if (old.VSInstances[i]) old.VSInstances[i]->Release();
|
||||||
|
device->IASetPrimitiveTopology(old.PrimitiveTopology);
|
||||||
|
device->IASetIndexBuffer(old.IndexBuffer, old.IndexBufferFormat, old.IndexBufferOffset); if (old.IndexBuffer) old.IndexBuffer->Release();
|
||||||
|
device->IASetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); if (old.VertexBuffer) old.VertexBuffer->Release();
|
||||||
|
device->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ImGui_ImplDX11_DestroyTexture(ImTextureData* tex)
|
||||||
|
{
|
||||||
|
if (ImGui_ImplDX11_Texture* backend_tex = (ImGui_ImplDX11_Texture*)tex->BackendUserData)
|
||||||
|
{
|
||||||
|
IM_ASSERT(backend_tex->pTextureView == (ID3D11ShaderResourceView*)(intptr_t)tex->TexID);
|
||||||
|
backend_tex->pTextureView->Release();
|
||||||
|
backend_tex->pTexture->Release();
|
||||||
|
IM_DELETE(backend_tex);
|
||||||
|
|
||||||
|
// Clear identifiers and mark as destroyed (in order to allow e.g. calling InvalidateDeviceObjects while running)
|
||||||
|
tex->SetTexID(ImTextureID_Invalid);
|
||||||
|
tex->BackendUserData = nullptr;
|
||||||
|
}
|
||||||
|
tex->SetStatus(ImTextureStatus_Destroyed);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplDX11_UpdateTexture(ImTextureData* tex)
|
||||||
|
{
|
||||||
|
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||||
|
if (tex->Status == ImTextureStatus_WantCreate)
|
||||||
|
{
|
||||||
|
// Create and upload new texture to graphics system
|
||||||
|
//IMGUI_DEBUG_LOG("UpdateTexture #%03d: WantCreate %dx%d\n", tex->UniqueID, tex->Width, tex->Height);
|
||||||
|
IM_ASSERT(tex->TexID == ImTextureID_Invalid && tex->BackendUserData == nullptr);
|
||||||
|
IM_ASSERT(tex->Format == ImTextureFormat_RGBA32);
|
||||||
|
unsigned int* pixels = (unsigned int*)tex->GetPixels();
|
||||||
|
ImGui_ImplDX11_Texture* backend_tex = IM_NEW(ImGui_ImplDX11_Texture)();
|
||||||
|
|
||||||
|
// Create texture
|
||||||
|
D3D11_TEXTURE2D_DESC desc;
|
||||||
|
ZeroMemory(&desc, sizeof(desc));
|
||||||
|
desc.Width = (UINT)tex->Width;
|
||||||
|
desc.Height = (UINT)tex->Height;
|
||||||
|
desc.MipLevels = 1;
|
||||||
|
desc.ArraySize = 1;
|
||||||
|
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
desc.SampleDesc.Count = 1;
|
||||||
|
desc.Usage = D3D11_USAGE_DEFAULT;
|
||||||
|
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||||
|
desc.CPUAccessFlags = 0;
|
||||||
|
D3D11_SUBRESOURCE_DATA subResource;
|
||||||
|
subResource.pSysMem = pixels;
|
||||||
|
subResource.SysMemPitch = desc.Width * 4;
|
||||||
|
subResource.SysMemSlicePitch = 0;
|
||||||
|
bd->pd3dDevice->CreateTexture2D(&desc, &subResource, &backend_tex->pTexture);
|
||||||
|
IM_ASSERT(backend_tex->pTexture != nullptr && "Backend failed to create texture!");
|
||||||
|
|
||||||
|
// Create texture view
|
||||||
|
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
|
||||||
|
ZeroMemory(&srvDesc, sizeof(srvDesc));
|
||||||
|
srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
||||||
|
srvDesc.Texture2D.MipLevels = desc.MipLevels;
|
||||||
|
srvDesc.Texture2D.MostDetailedMip = 0;
|
||||||
|
bd->pd3dDevice->CreateShaderResourceView(backend_tex->pTexture, &srvDesc, &backend_tex->pTextureView);
|
||||||
|
IM_ASSERT(backend_tex->pTextureView != nullptr && "Backend failed to create texture!");
|
||||||
|
|
||||||
|
// Store identifiers
|
||||||
|
tex->SetTexID((ImTextureID)(intptr_t)backend_tex->pTextureView);
|
||||||
|
tex->SetStatus(ImTextureStatus_OK);
|
||||||
|
tex->BackendUserData = backend_tex;
|
||||||
|
}
|
||||||
|
else if (tex->Status == ImTextureStatus_WantUpdates)
|
||||||
|
{
|
||||||
|
// Update selected blocks. We only ever write to textures regions which have never been used before!
|
||||||
|
// This backend choose to use tex->Updates[] but you can use tex->UpdateRect to upload a single region.
|
||||||
|
ImGui_ImplDX11_Texture* backend_tex = (ImGui_ImplDX11_Texture*)tex->BackendUserData;
|
||||||
|
IM_ASSERT(backend_tex->pTextureView == (ID3D11ShaderResourceView*)(intptr_t)tex->TexID);
|
||||||
|
for (ImTextureRect& r : tex->Updates)
|
||||||
|
{
|
||||||
|
D3D11_BOX box = { (UINT)r.x, (UINT)r.y, (UINT)0, (UINT)(r.x + r.w), (UINT)(r.y + r .h), (UINT)1 };
|
||||||
|
bd->pd3dDeviceContext->UpdateSubresource(backend_tex->pTexture, 0, &box, tex->GetPixelsAt(r.x, r.y), (UINT)tex->GetPitch(), 0);
|
||||||
|
}
|
||||||
|
tex->SetStatus(ImTextureStatus_OK);
|
||||||
|
}
|
||||||
|
if (tex->Status == ImTextureStatus_WantDestroy && tex->UnusedFrames > 0)
|
||||||
|
ImGui_ImplDX11_DestroyTexture(tex);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImGui_ImplDX11_CreateDeviceObjects()
|
||||||
|
{
|
||||||
|
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||||
|
if (!bd->pd3dDevice)
|
||||||
|
return false;
|
||||||
|
ImGui_ImplDX11_InvalidateDeviceObjects();
|
||||||
|
|
||||||
|
// By using D3DCompile() from <d3dcompiler.h> / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
|
||||||
|
// If you would like to use this DX11 sample code but remove this dependency you can:
|
||||||
|
// 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [preferred solution]
|
||||||
|
// 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
|
||||||
|
// See https://github.com/ocornut/imgui/pull/638 for sources and details.
|
||||||
|
|
||||||
|
// Create the vertex shader
|
||||||
|
{
|
||||||
|
static const char* vertexShader =
|
||||||
|
"cbuffer vertexBuffer : register(b0) \
|
||||||
|
{\
|
||||||
|
float4x4 ProjectionMatrix; \
|
||||||
|
};\
|
||||||
|
struct VS_INPUT\
|
||||||
|
{\
|
||||||
|
float2 pos : POSITION;\
|
||||||
|
float4 col : COLOR0;\
|
||||||
|
float2 uv : TEXCOORD0;\
|
||||||
|
};\
|
||||||
|
\
|
||||||
|
struct PS_INPUT\
|
||||||
|
{\
|
||||||
|
float4 pos : SV_POSITION;\
|
||||||
|
float4 col : COLOR0;\
|
||||||
|
float2 uv : TEXCOORD0;\
|
||||||
|
};\
|
||||||
|
\
|
||||||
|
PS_INPUT main(VS_INPUT input)\
|
||||||
|
{\
|
||||||
|
PS_INPUT output;\
|
||||||
|
output.pos = mul( ProjectionMatrix, float4(input.pos.xy, 0.f, 1.f));\
|
||||||
|
output.col = input.col;\
|
||||||
|
output.uv = input.uv;\
|
||||||
|
return output;\
|
||||||
|
}";
|
||||||
|
|
||||||
|
ID3DBlob* vertexShaderBlob;
|
||||||
|
if (FAILED(D3DCompile(vertexShader, strlen(vertexShader), nullptr, nullptr, nullptr, "main", "vs_4_0", 0, 0, &vertexShaderBlob, nullptr)))
|
||||||
|
return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
|
||||||
|
if (bd->pd3dDevice->CreateVertexShader(vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), nullptr, &bd->pVertexShader) != S_OK)
|
||||||
|
{
|
||||||
|
vertexShaderBlob->Release();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the input layout
|
||||||
|
D3D11_INPUT_ELEMENT_DESC local_layout[] =
|
||||||
|
{
|
||||||
|
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)offsetof(ImDrawVert, pos), D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||||
|
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)offsetof(ImDrawVert, uv), D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||||
|
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (UINT)offsetof(ImDrawVert, col), D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||||
|
};
|
||||||
|
if (bd->pd3dDevice->CreateInputLayout(local_layout, 3, vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), &bd->pInputLayout) != S_OK)
|
||||||
|
{
|
||||||
|
vertexShaderBlob->Release();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
vertexShaderBlob->Release();
|
||||||
|
|
||||||
|
// Create the constant buffer
|
||||||
|
{
|
||||||
|
D3D11_BUFFER_DESC desc = {};
|
||||||
|
desc.ByteWidth = sizeof(VERTEX_CONSTANT_BUFFER_DX11);
|
||||||
|
desc.Usage = D3D11_USAGE_DYNAMIC;
|
||||||
|
desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
|
||||||
|
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||||
|
desc.MiscFlags = 0;
|
||||||
|
bd->pd3dDevice->CreateBuffer(&desc, nullptr, &bd->pVertexConstantBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the pixel shader
|
||||||
|
{
|
||||||
|
static const char* pixelShader =
|
||||||
|
"struct PS_INPUT\
|
||||||
|
{\
|
||||||
|
float4 pos : SV_POSITION;\
|
||||||
|
float4 col : COLOR0;\
|
||||||
|
float2 uv : TEXCOORD0;\
|
||||||
|
};\
|
||||||
|
sampler sampler0;\
|
||||||
|
Texture2D texture0;\
|
||||||
|
\
|
||||||
|
float4 main(PS_INPUT input) : SV_Target\
|
||||||
|
{\
|
||||||
|
float4 out_col = input.col * texture0.Sample(sampler0, input.uv); \
|
||||||
|
return out_col; \
|
||||||
|
}";
|
||||||
|
|
||||||
|
ID3DBlob* pixelShaderBlob;
|
||||||
|
if (FAILED(D3DCompile(pixelShader, strlen(pixelShader), nullptr, nullptr, nullptr, "main", "ps_4_0", 0, 0, &pixelShaderBlob, nullptr)))
|
||||||
|
return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
|
||||||
|
if (bd->pd3dDevice->CreatePixelShader(pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize(), nullptr, &bd->pPixelShader) != S_OK)
|
||||||
|
{
|
||||||
|
pixelShaderBlob->Release();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
pixelShaderBlob->Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the blending setup
|
||||||
|
{
|
||||||
|
D3D11_BLEND_DESC desc;
|
||||||
|
ZeroMemory(&desc, sizeof(desc));
|
||||||
|
desc.AlphaToCoverageEnable = false;
|
||||||
|
desc.RenderTarget[0].BlendEnable = true;
|
||||||
|
desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
|
||||||
|
desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
|
||||||
|
desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
|
||||||
|
desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
|
||||||
|
desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;
|
||||||
|
desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
|
||||||
|
desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
|
||||||
|
bd->pd3dDevice->CreateBlendState(&desc, &bd->pBlendState);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the rasterizer state
|
||||||
|
{
|
||||||
|
D3D11_RASTERIZER_DESC desc;
|
||||||
|
ZeroMemory(&desc, sizeof(desc));
|
||||||
|
desc.FillMode = D3D11_FILL_SOLID;
|
||||||
|
desc.CullMode = D3D11_CULL_NONE;
|
||||||
|
desc.ScissorEnable = true;
|
||||||
|
desc.DepthClipEnable = true;
|
||||||
|
bd->pd3dDevice->CreateRasterizerState(&desc, &bd->pRasterizerState);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create depth-stencil State
|
||||||
|
{
|
||||||
|
D3D11_DEPTH_STENCIL_DESC desc;
|
||||||
|
ZeroMemory(&desc, sizeof(desc));
|
||||||
|
desc.DepthEnable = false;
|
||||||
|
desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
|
||||||
|
desc.DepthFunc = D3D11_COMPARISON_ALWAYS;
|
||||||
|
desc.StencilEnable = false;
|
||||||
|
desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
|
||||||
|
desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
|
||||||
|
desc.BackFace = desc.FrontFace;
|
||||||
|
bd->pd3dDevice->CreateDepthStencilState(&desc, &bd->pDepthStencilState);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create texture sampler
|
||||||
|
// (Bilinear sampling is required by default. Set 'io.Fonts->Flags |= ImFontAtlasFlags_NoBakedLines' or 'style.AntiAliasedLinesUseTex = false' to allow point/nearest sampling)
|
||||||
|
{
|
||||||
|
D3D11_SAMPLER_DESC desc;
|
||||||
|
ZeroMemory(&desc, sizeof(desc));
|
||||||
|
desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
|
||||||
|
desc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||||
|
desc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||||
|
desc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP;
|
||||||
|
desc.MipLODBias = 0.f;
|
||||||
|
desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
|
||||||
|
desc.MinLOD = 0.f;
|
||||||
|
desc.MaxLOD = 0.f;
|
||||||
|
bd->pd3dDevice->CreateSamplerState(&desc, &bd->pTexSamplerLinear);
|
||||||
|
desc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
|
||||||
|
bd->pd3dDevice->CreateSamplerState(&desc, &bd->pTexSamplerNearest);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplDX11_InvalidateDeviceObjects()
|
||||||
|
{
|
||||||
|
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||||
|
if (!bd->pd3dDevice)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Destroy all textures
|
||||||
|
for (ImTextureData* tex : ImGui::GetPlatformIO().Textures)
|
||||||
|
if (tex->RefCount == 1)
|
||||||
|
ImGui_ImplDX11_DestroyTexture(tex);
|
||||||
|
|
||||||
|
if (bd->pTexSamplerLinear) { bd->pTexSamplerLinear->Release(); bd->pTexSamplerLinear = nullptr; }
|
||||||
|
if (bd->pTexSamplerNearest) { bd->pTexSamplerNearest->Release(); bd->pTexSamplerNearest = nullptr; }
|
||||||
|
if (bd->pIB) { bd->pIB->Release(); bd->pIB = nullptr; }
|
||||||
|
if (bd->pVB) { bd->pVB->Release(); bd->pVB = nullptr; }
|
||||||
|
if (bd->pBlendState) { bd->pBlendState->Release(); bd->pBlendState = nullptr; }
|
||||||
|
if (bd->pDepthStencilState) { bd->pDepthStencilState->Release(); bd->pDepthStencilState = nullptr; }
|
||||||
|
if (bd->pRasterizerState) { bd->pRasterizerState->Release(); bd->pRasterizerState = nullptr; }
|
||||||
|
if (bd->pPixelShader) { bd->pPixelShader->Release(); bd->pPixelShader = nullptr; }
|
||||||
|
if (bd->pVertexConstantBuffer) { bd->pVertexConstantBuffer->Release(); bd->pVertexConstantBuffer = nullptr; }
|
||||||
|
if (bd->pInputLayout) { bd->pInputLayout->Release(); bd->pInputLayout = nullptr; }
|
||||||
|
if (bd->pVertexShader) { bd->pVertexShader->Release(); bd->pVertexShader = nullptr; }
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context)
|
||||||
|
{
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
IMGUI_CHECKVERSION();
|
||||||
|
IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!");
|
||||||
|
|
||||||
|
// Setup backend capabilities flags
|
||||||
|
ImGui_ImplDX11_Data* bd = IM_NEW(ImGui_ImplDX11_Data)();
|
||||||
|
io.BackendRendererUserData = (void*)bd;
|
||||||
|
io.BackendRendererName = "imgui_impl_dx11";
|
||||||
|
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||||
|
io.BackendFlags |= ImGuiBackendFlags_RendererHasTextures; // We can honor ImGuiPlatformIO::Textures[] requests during render.
|
||||||
|
io.BackendFlags |= ImGuiBackendFlags_RendererHasViewports; // We can create multi-viewports on the Renderer side (optional)
|
||||||
|
|
||||||
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
|
platform_io.Renderer_TextureMaxWidth = platform_io.Renderer_TextureMaxHeight = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
|
||||||
|
|
||||||
|
// Get factory from device
|
||||||
|
IDXGIDevice* pDXGIDevice = nullptr;
|
||||||
|
IDXGIAdapter* pDXGIAdapter = nullptr;
|
||||||
|
IDXGIFactory* pFactory = nullptr;
|
||||||
|
|
||||||
|
if (device->QueryInterface(IID_PPV_ARGS(&pDXGIDevice)) == S_OK)
|
||||||
|
if (pDXGIDevice->GetParent(IID_PPV_ARGS(&pDXGIAdapter)) == S_OK)
|
||||||
|
if (pDXGIAdapter->GetParent(IID_PPV_ARGS(&pFactory)) == S_OK)
|
||||||
|
{
|
||||||
|
bd->pd3dDevice = device;
|
||||||
|
bd->pd3dDeviceContext = device_context;
|
||||||
|
bd->pFactory = pFactory;
|
||||||
|
}
|
||||||
|
if (pDXGIDevice) pDXGIDevice->Release();
|
||||||
|
if (pDXGIAdapter) pDXGIAdapter->Release();
|
||||||
|
bd->pd3dDevice->AddRef();
|
||||||
|
bd->pd3dDeviceContext->AddRef();
|
||||||
|
|
||||||
|
ImGui_ImplDX11_InitMultiViewportSupport();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplDX11_Shutdown()
|
||||||
|
{
|
||||||
|
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||||
|
IM_ASSERT(bd != nullptr && "No renderer backend to shutdown, or already shutdown?");
|
||||||
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
|
|
||||||
|
ImGui_ImplDX11_ShutdownMultiViewportSupport();
|
||||||
|
ImGui_ImplDX11_InvalidateDeviceObjects();
|
||||||
|
if (bd->pFactory) { bd->pFactory->Release(); }
|
||||||
|
if (bd->pd3dDevice) { bd->pd3dDevice->Release(); }
|
||||||
|
if (bd->pd3dDeviceContext) { bd->pd3dDeviceContext->Release(); }
|
||||||
|
|
||||||
|
io.BackendRendererName = nullptr;
|
||||||
|
io.BackendRendererUserData = nullptr;
|
||||||
|
io.BackendFlags &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasTextures | ImGuiBackendFlags_RendererHasViewports);
|
||||||
|
platform_io.ClearRendererHandlers();
|
||||||
|
IM_DELETE(bd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ImGui_ImplDX11_NewFrame()
|
||||||
|
{
|
||||||
|
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||||
|
IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplDX11_Init()?");
|
||||||
|
|
||||||
|
if (!bd->pVertexShader)
|
||||||
|
if (!ImGui_ImplDX11_CreateDeviceObjects())
|
||||||
|
IM_ASSERT(0 && "ImGui_ImplDX11_CreateDeviceObjects() failed!");
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------
|
||||||
|
// MULTI-VIEWPORT / PLATFORM INTERFACE SUPPORT
|
||||||
|
// This is an _advanced_ and _optional_ feature, allowing the backend to create and handle multiple viewports simultaneously.
|
||||||
|
// If you are new to dear imgui or creating a new binding for dear imgui, it is recommended that you completely ignore this section first..
|
||||||
|
//--------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Helper structure we store in the void* RendererUserData field of each ImGuiViewport to easily retrieve our backend data.
|
||||||
|
struct ImGui_ImplDX11_ViewportData
|
||||||
|
{
|
||||||
|
IDXGISwapChain* SwapChain;
|
||||||
|
ID3D11RenderTargetView* RTView;
|
||||||
|
|
||||||
|
ImGui_ImplDX11_ViewportData() { SwapChain = nullptr; RTView = nullptr; }
|
||||||
|
~ImGui_ImplDX11_ViewportData() { IM_ASSERT(SwapChain == nullptr && RTView == nullptr); }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Multi-Viewports: configure templates used when creating swapchains for secondary viewports. Will try them in order.
|
||||||
|
// This is intentionally not declared in the .h file yet, so you will need to copy this declaration:
|
||||||
|
void ImGui_ImplDX11_SetSwapChainDescs(const DXGI_SWAP_CHAIN_DESC* desc_templates, int desc_templates_count);
|
||||||
|
void ImGui_ImplDX11_SetSwapChainDescs(const DXGI_SWAP_CHAIN_DESC* desc_templates, int desc_templates_count)
|
||||||
|
{
|
||||||
|
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||||
|
bd->SwapChainDescsForViewports.resize(desc_templates_count);
|
||||||
|
memcpy(bd->SwapChainDescsForViewports.Data, desc_templates, sizeof(DXGI_SWAP_CHAIN_DESC));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ImGui_ImplDX11_CreateWindow(ImGuiViewport* viewport)
|
||||||
|
{
|
||||||
|
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||||
|
ImGui_ImplDX11_ViewportData* vd = IM_NEW(ImGui_ImplDX11_ViewportData)();
|
||||||
|
viewport->RendererUserData = vd;
|
||||||
|
|
||||||
|
// PlatformHandleRaw should always be a HWND, whereas PlatformHandle might be a higher-level handle (e.g. GLFWWindow*, SDL's WindowID).
|
||||||
|
// Some backends will leave PlatformHandleRaw == 0, in which case we assume PlatformHandle will contain the HWND.
|
||||||
|
HWND hwnd = viewport->PlatformHandleRaw ? (HWND)viewport->PlatformHandleRaw : (HWND)viewport->PlatformHandle;
|
||||||
|
IM_ASSERT(hwnd != 0);
|
||||||
|
IM_ASSERT(vd->SwapChain == nullptr && vd->RTView == nullptr);
|
||||||
|
|
||||||
|
// Create swap chain
|
||||||
|
HRESULT hr = DXGI_ERROR_UNSUPPORTED;
|
||||||
|
for (const DXGI_SWAP_CHAIN_DESC& sd_template : bd->SwapChainDescsForViewports)
|
||||||
|
{
|
||||||
|
IM_ASSERT(sd_template.BufferDesc.Width == 0 && sd_template.BufferDesc.Height == 0 && sd_template.OutputWindow == nullptr);
|
||||||
|
DXGI_SWAP_CHAIN_DESC sd = sd_template;
|
||||||
|
sd.BufferDesc.Width = (UINT)viewport->Size.x;
|
||||||
|
sd.BufferDesc.Height = (UINT)viewport->Size.y;
|
||||||
|
sd.OutputWindow = hwnd;
|
||||||
|
hr = bd->pFactory->CreateSwapChain(bd->pd3dDevice, &sd, &vd->SwapChain);
|
||||||
|
if (SUCCEEDED(hr))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
IM_ASSERT(SUCCEEDED(hr));
|
||||||
|
bd->pFactory->MakeWindowAssociation(hwnd, DXGI_MWA_NO_ALT_ENTER | DXGI_MWA_NO_WINDOW_CHANGES); // Disable e.g. Alt+Enter
|
||||||
|
|
||||||
|
// Create the render target
|
||||||
|
if (vd->SwapChain != nullptr)
|
||||||
|
{
|
||||||
|
ID3D11Texture2D* pBackBuffer;
|
||||||
|
vd->SwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer));
|
||||||
|
bd->pd3dDevice->CreateRenderTargetView(pBackBuffer, nullptr, &vd->RTView);
|
||||||
|
pBackBuffer->Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ImGui_ImplDX11_DestroyWindow(ImGuiViewport* viewport)
|
||||||
|
{
|
||||||
|
// The main viewport (owned by the application) will always have RendererUserData == nullptr since we didn't create the data for it.
|
||||||
|
if (ImGui_ImplDX11_ViewportData* vd = (ImGui_ImplDX11_ViewportData*)viewport->RendererUserData)
|
||||||
|
{
|
||||||
|
if (vd->SwapChain)
|
||||||
|
vd->SwapChain->Release();
|
||||||
|
vd->SwapChain = nullptr;
|
||||||
|
if (vd->RTView)
|
||||||
|
vd->RTView->Release();
|
||||||
|
vd->RTView = nullptr;
|
||||||
|
IM_DELETE(vd);
|
||||||
|
}
|
||||||
|
viewport->RendererUserData = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ImGui_ImplDX11_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
||||||
|
{
|
||||||
|
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||||
|
ImGui_ImplDX11_ViewportData* vd = (ImGui_ImplDX11_ViewportData*)viewport->RendererUserData;
|
||||||
|
if (vd->RTView)
|
||||||
|
{
|
||||||
|
vd->RTView->Release();
|
||||||
|
vd->RTView = nullptr;
|
||||||
|
}
|
||||||
|
if (vd->SwapChain)
|
||||||
|
{
|
||||||
|
ID3D11Texture2D* pBackBuffer = nullptr;
|
||||||
|
vd->SwapChain->ResizeBuffers(0, (UINT)size.x, (UINT)size.y, DXGI_FORMAT_UNKNOWN, 0);
|
||||||
|
vd->SwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer));
|
||||||
|
if (pBackBuffer == nullptr) { fprintf(stderr, "ImGui_ImplDX11_SetWindowSize() failed creating buffers.\n"); return; }
|
||||||
|
bd->pd3dDevice->CreateRenderTargetView(pBackBuffer, nullptr, &vd->RTView);
|
||||||
|
pBackBuffer->Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ImGui_ImplDX11_RenderWindow(ImGuiViewport* viewport, void*)
|
||||||
|
{
|
||||||
|
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||||
|
ImGui_ImplDX11_ViewportData* vd = (ImGui_ImplDX11_ViewportData*)viewport->RendererUserData;
|
||||||
|
ImVec4 clear_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
bd->pd3dDeviceContext->OMSetRenderTargets(1, &vd->RTView, nullptr);
|
||||||
|
if (!(viewport->Flags & ImGuiViewportFlags_NoRendererClear))
|
||||||
|
bd->pd3dDeviceContext->ClearRenderTargetView(vd->RTView, (float*)&clear_color);
|
||||||
|
ImGui_ImplDX11_RenderDrawData(viewport->DrawData);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ImGui_ImplDX11_SwapBuffers(ImGuiViewport* viewport, void*)
|
||||||
|
{
|
||||||
|
ImGui_ImplDX11_ViewportData* vd = (ImGui_ImplDX11_ViewportData*)viewport->RendererUserData;
|
||||||
|
if (vd->SwapChain)
|
||||||
|
vd->SwapChain->Present(0, 0); // Present without vsync
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ImGui_ImplDX11_InitMultiViewportSupport()
|
||||||
|
{
|
||||||
|
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||||
|
platform_io.Renderer_CreateWindow = ImGui_ImplDX11_CreateWindow;
|
||||||
|
platform_io.Renderer_DestroyWindow = ImGui_ImplDX11_DestroyWindow;
|
||||||
|
platform_io.Renderer_SetWindowSize = ImGui_ImplDX11_SetWindowSize;
|
||||||
|
platform_io.Renderer_RenderWindow = ImGui_ImplDX11_RenderWindow;
|
||||||
|
platform_io.Renderer_SwapBuffers = ImGui_ImplDX11_SwapBuffers;
|
||||||
|
|
||||||
|
// Default swapchain format
|
||||||
|
DXGI_SWAP_CHAIN_DESC sd;
|
||||||
|
ZeroMemory(&sd, sizeof(sd));
|
||||||
|
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||||
|
sd.SampleDesc.Count = 1;
|
||||||
|
sd.SampleDesc.Quality = 0;
|
||||||
|
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||||
|
sd.BufferCount = 1;
|
||||||
|
sd.Windowed = TRUE;
|
||||||
|
sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
|
||||||
|
sd.Flags = 0;
|
||||||
|
ImGui_ImplDX11_SetSwapChainDescs(&sd, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ImGui_ImplDX11_ShutdownMultiViewportSupport()
|
||||||
|
{
|
||||||
|
ImGui::DestroyPlatformWindows();
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
53
libs/imgui/backends/imgui_impl_dx11.h
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
// dear imgui: Renderer Backend for DirectX11
|
||||||
|
// This needs to be used along with a Platform Backend (e.g. Win32)
|
||||||
|
|
||||||
|
// Implemented features:
|
||||||
|
// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
||||||
|
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||||
|
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||||
|
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||||
|
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||||
|
|
||||||
|
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||||
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
|
// Learn about Dear ImGui:
|
||||||
|
// - FAQ https://dearimgui.com/faq
|
||||||
|
// - Getting Started https://dearimgui.com/getting-started
|
||||||
|
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||||
|
// - Introduction, links and more at the top of imgui.cpp
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "imgui.h" // IMGUI_IMPL_API
|
||||||
|
#ifndef IMGUI_DISABLE
|
||||||
|
|
||||||
|
struct ID3D11Device;
|
||||||
|
struct ID3D11DeviceContext;
|
||||||
|
struct ID3D11SamplerState;
|
||||||
|
struct ID3D11Buffer;
|
||||||
|
|
||||||
|
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context);
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplDX11_Shutdown();
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplDX11_NewFrame();
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data);
|
||||||
|
|
||||||
|
// Use if you want to reset your rendering device without losing Dear ImGui state.
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplDX11_CreateDeviceObjects();
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplDX11_InvalidateDeviceObjects();
|
||||||
|
|
||||||
|
// (Advanced) Use e.g. if you need to precisely control the timing of texture updates (e.g. for staged rendering), by setting ImDrawData::Textures = nullptr to handle this manually.
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplDX11_UpdateTexture(ImTextureData* tex);
|
||||||
|
|
||||||
|
// [BETA] Selected render state data shared with callbacks.
|
||||||
|
// This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplDX11_RenderDrawData() call.
|
||||||
|
// (Please open an issue if you feel you need access to more data)
|
||||||
|
struct ImGui_ImplDX11_RenderState
|
||||||
|
{
|
||||||
|
ID3D11Device* Device;
|
||||||
|
ID3D11DeviceContext* DeviceContext;
|
||||||
|
ID3D11SamplerState* SamplerLinear;
|
||||||
|
ID3D11SamplerState* SamplerNearest;
|
||||||
|
ID3D11Buffer* VertexConstantBuffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
1104
libs/imgui/backends/imgui_impl_opengl3.cpp
Normal file
69
libs/imgui/backends/imgui_impl_opengl3.h
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
// dear imgui: Renderer Backend for modern OpenGL with shaders / programmatic pipeline
|
||||||
|
// - Desktop GL: 2.x 3.x 4.x
|
||||||
|
// - Embedded GL: ES 2.0 (WebGL 1.0), ES 3.0 (WebGL 2.0)
|
||||||
|
// This needs to be used along with a Platform Backend (e.g. GLFW, SDL, Win32, custom..)
|
||||||
|
|
||||||
|
// Implemented features:
|
||||||
|
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
||||||
|
// [x] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset) [Desktop OpenGL only!]
|
||||||
|
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||||
|
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||||
|
|
||||||
|
// About WebGL/ES:
|
||||||
|
// - You need to '#define IMGUI_IMPL_OPENGL_ES2' or '#define IMGUI_IMPL_OPENGL_ES3' to use WebGL or OpenGL ES.
|
||||||
|
// - This is done automatically on iOS, Android and Emscripten targets.
|
||||||
|
// - For other targets, the define needs to be visible from the imgui_impl_opengl3.cpp compilation unit. If unsure, define globally or in imconfig.h.
|
||||||
|
|
||||||
|
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||||
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
|
// Learn about Dear ImGui:
|
||||||
|
// - FAQ https://dearimgui.com/faq
|
||||||
|
// - Getting Started https://dearimgui.com/getting-started
|
||||||
|
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||||
|
// - Introduction, links and more at the top of imgui.cpp
|
||||||
|
|
||||||
|
// About GLSL version:
|
||||||
|
// The 'glsl_version' initialization parameter should be nullptr (default) or a "#version XXX" string.
|
||||||
|
// On computer platform the GLSL version default to "#version 130". On OpenGL ES 3 platform it defaults to "#version 300 es"
|
||||||
|
// Only override if your GL version doesn't handle this GLSL version. See GLSL version table at the top of imgui_impl_opengl3.cpp.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "imgui.h" // IMGUI_IMPL_API
|
||||||
|
#ifndef IMGUI_DISABLE
|
||||||
|
|
||||||
|
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplOpenGL3_Init(const char* glsl_version = nullptr);
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplOpenGL3_Shutdown();
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplOpenGL3_NewFrame();
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data);
|
||||||
|
|
||||||
|
// (Optional) Called by Init/NewFrame/Shutdown
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateDeviceObjects();
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyDeviceObjects();
|
||||||
|
|
||||||
|
// (Advanced) Use e.g. if you need to precisely control the timing of texture updates (e.g. for staged rendering), by setting ImDrawData::Textures = nullptr to handle this manually.
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplOpenGL3_UpdateTexture(ImTextureData* tex);
|
||||||
|
|
||||||
|
// Configuration flags to add in your imconfig file:
|
||||||
|
//#define IMGUI_IMPL_OPENGL_ES2 // Enable ES 2 (Auto-detected on Emscripten)
|
||||||
|
//#define IMGUI_IMPL_OPENGL_ES3 // Enable ES 3 (Auto-detected on iOS/Android)
|
||||||
|
|
||||||
|
// You can explicitly select GLES2 or GLES3 API by using one of the '#define IMGUI_IMPL_OPENGL_LOADER_XXX' in imconfig.h or compiler command-line.
|
||||||
|
#if !defined(IMGUI_IMPL_OPENGL_ES2) \
|
||||||
|
&& !defined(IMGUI_IMPL_OPENGL_ES3)
|
||||||
|
|
||||||
|
// Try to detect GLES on matching platforms
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
#include <TargetConditionals.h>
|
||||||
|
#endif
|
||||||
|
#if (defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV)) || (defined(__ANDROID__))
|
||||||
|
#define IMGUI_IMPL_OPENGL_ES3 // iOS, Android -> GL ES 3, "#version 300 es"
|
||||||
|
#elif defined(__EMSCRIPTEN__) || defined(__amigaos4__)
|
||||||
|
#define IMGUI_IMPL_OPENGL_ES2 // Emscripten -> GL ES 2, "#version 100"
|
||||||
|
#else
|
||||||
|
// Otherwise imgui_impl_opengl3_loader.h will be used.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
958
libs/imgui/backends/imgui_impl_opengl3_loader.h
Normal file
@@ -0,0 +1,958 @@
|
|||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// About imgui_impl_opengl3_loader.h:
|
||||||
|
//
|
||||||
|
// We embed our own OpenGL loader to not require user to provide their own or to have to use ours,
|
||||||
|
// which proved to be endless problems for users.
|
||||||
|
// Our loader is custom-generated, based on gl3w but automatically filtered to only include
|
||||||
|
// enums/functions that we use in our imgui_impl_opengl3.cpp source file in order to be small.
|
||||||
|
//
|
||||||
|
// YOU SHOULD NOT NEED TO INCLUDE/USE THIS DIRECTLY. THIS IS USED BY imgui_impl_opengl3.cpp ONLY.
|
||||||
|
// THE REST OF YOUR APP SHOULD USE A DIFFERENT GL LOADER: ANY GL LOADER OF YOUR CHOICE.
|
||||||
|
//
|
||||||
|
// IF YOU GET BUILD ERRORS IN THIS FILE (commonly macro redefinitions or function redefinitions):
|
||||||
|
// IT LIKELY MEANS THAT YOU ARE BUILDING 'imgui_impl_opengl3.cpp' OR INCLUDING 'imgui_impl_opengl3_loader.h'
|
||||||
|
// IN THE SAME COMPILATION UNIT AS ONE OF YOUR FILE WHICH IS USING A THIRD-PARTY OPENGL LOADER.
|
||||||
|
// (e.g. COULD HAPPEN IF YOU ARE DOING A UNITY/JUMBO BUILD, OR INCLUDING .CPP FILES FROM OTHERS)
|
||||||
|
// YOU SHOULD NOT BUILD BOTH IN THE SAME COMPILATION UNIT.
|
||||||
|
// BUT IF YOU REALLY WANT TO, you can '#define IMGUI_IMPL_OPENGL_LOADER_CUSTOM' and imgui_impl_opengl3.cpp
|
||||||
|
// WILL NOT BE USING OUR LOADER, AND INSTEAD EXPECT ANOTHER/YOUR LOADER TO BE AVAILABLE IN THE COMPILATION UNIT.
|
||||||
|
//
|
||||||
|
// Regenerate with:
|
||||||
|
// python3 gl3w_gen.py --output ../imgui/backends/imgui_impl_opengl3_loader.h --ref ../imgui/backends/imgui_impl_opengl3.cpp ./extra_symbols.txt
|
||||||
|
//
|
||||||
|
// More info:
|
||||||
|
// https://github.com/dearimgui/gl3w_stripped
|
||||||
|
// https://github.com/ocornut/imgui/issues/4445
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file was generated with gl3w_gen.py, part of imgl3w
|
||||||
|
* (hosted at https://github.com/dearimgui/gl3w_stripped)
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __gl3w_h_
|
||||||
|
#define __gl3w_h_
|
||||||
|
|
||||||
|
// Adapted from KHR/khrplatform.h to avoid including entire file.
|
||||||
|
#ifndef __khrplatform_h_
|
||||||
|
typedef float khronos_float_t;
|
||||||
|
typedef signed char khronos_int8_t;
|
||||||
|
typedef unsigned char khronos_uint8_t;
|
||||||
|
typedef signed short int khronos_int16_t;
|
||||||
|
typedef unsigned short int khronos_uint16_t;
|
||||||
|
#ifdef _WIN64
|
||||||
|
typedef signed long long int khronos_intptr_t;
|
||||||
|
typedef signed long long int khronos_ssize_t;
|
||||||
|
#else
|
||||||
|
typedef signed long int khronos_intptr_t;
|
||||||
|
typedef signed long int khronos_ssize_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && !defined(__clang__)
|
||||||
|
typedef signed __int64 khronos_int64_t;
|
||||||
|
typedef unsigned __int64 khronos_uint64_t;
|
||||||
|
#elif (defined(__clang__) || defined(__GNUC__)) && (__cplusplus < 201100)
|
||||||
|
#include <stdint.h>
|
||||||
|
typedef int64_t khronos_int64_t;
|
||||||
|
typedef uint64_t khronos_uint64_t;
|
||||||
|
#else
|
||||||
|
typedef signed long long khronos_int64_t;
|
||||||
|
typedef unsigned long long khronos_uint64_t;
|
||||||
|
#endif
|
||||||
|
#endif // __khrplatform_h_
|
||||||
|
|
||||||
|
#ifndef __gl_glcorearb_h_
|
||||||
|
#define __gl_glcorearb_h_ 1
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
** Copyright 2013-2020 The Khronos Group Inc.
|
||||||
|
** SPDX-License-Identifier: MIT
|
||||||
|
**
|
||||||
|
** This header is generated from the Khronos OpenGL / OpenGL ES XML
|
||||||
|
** API Registry. The current version of the Registry, generator scripts
|
||||||
|
** used to make the header, and the header can be found at
|
||||||
|
** https://github.com/KhronosGroup/OpenGL-Registry
|
||||||
|
*/
|
||||||
|
#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN 1
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
#ifndef APIENTRY
|
||||||
|
#define APIENTRY
|
||||||
|
#endif
|
||||||
|
#ifndef APIENTRYP
|
||||||
|
#define APIENTRYP APIENTRY *
|
||||||
|
#endif
|
||||||
|
#ifndef GLAPI
|
||||||
|
#define GLAPI extern
|
||||||
|
#endif
|
||||||
|
/* glcorearb.h is for use with OpenGL core profile implementations.
|
||||||
|
** It should should be placed in the same directory as gl.h and
|
||||||
|
** included as <GL/glcorearb.h>.
|
||||||
|
**
|
||||||
|
** glcorearb.h includes only APIs in the latest OpenGL core profile
|
||||||
|
** implementation together with APIs in newer ARB extensions which
|
||||||
|
** can be supported by the core profile. It does not, and never will
|
||||||
|
** include functionality removed from the core profile, such as
|
||||||
|
** fixed-function vertex and fragment processing.
|
||||||
|
**
|
||||||
|
** Do not #include both <GL/glcorearb.h> and either of <GL/gl.h> or
|
||||||
|
** <GL/glext.h> in the same source file.
|
||||||
|
*/
|
||||||
|
/* Generated C header for:
|
||||||
|
* API: gl
|
||||||
|
* Profile: core
|
||||||
|
* Versions considered: .*
|
||||||
|
* Versions emitted: .*
|
||||||
|
* Default extensions included: glcore
|
||||||
|
* Additional extensions included: _nomatch_^
|
||||||
|
* Extensions removed: _nomatch_^
|
||||||
|
*/
|
||||||
|
#ifndef GL_VERSION_1_0
|
||||||
|
typedef void GLvoid;
|
||||||
|
typedef unsigned int GLenum;
|
||||||
|
|
||||||
|
typedef khronos_float_t GLfloat;
|
||||||
|
typedef int GLint;
|
||||||
|
typedef int GLsizei;
|
||||||
|
typedef unsigned int GLbitfield;
|
||||||
|
typedef double GLdouble;
|
||||||
|
typedef unsigned int GLuint;
|
||||||
|
typedef unsigned char GLboolean;
|
||||||
|
typedef khronos_uint8_t GLubyte;
|
||||||
|
#define GL_COLOR_BUFFER_BIT 0x00004000
|
||||||
|
#define GL_FALSE 0
|
||||||
|
#define GL_TRUE 1
|
||||||
|
#define GL_TRIANGLES 0x0004
|
||||||
|
#define GL_ONE 1
|
||||||
|
#define GL_SRC_ALPHA 0x0302
|
||||||
|
#define GL_ONE_MINUS_SRC_ALPHA 0x0303
|
||||||
|
#define GL_FRONT 0x0404
|
||||||
|
#define GL_BACK 0x0405
|
||||||
|
#define GL_FRONT_AND_BACK 0x0408
|
||||||
|
#define GL_POLYGON_MODE 0x0B40
|
||||||
|
#define GL_CULL_FACE 0x0B44
|
||||||
|
#define GL_DEPTH_TEST 0x0B71
|
||||||
|
#define GL_STENCIL_TEST 0x0B90
|
||||||
|
#define GL_VIEWPORT 0x0BA2
|
||||||
|
#define GL_BLEND 0x0BE2
|
||||||
|
#define GL_SCISSOR_BOX 0x0C10
|
||||||
|
#define GL_SCISSOR_TEST 0x0C11
|
||||||
|
#define GL_UNPACK_ROW_LENGTH 0x0CF2
|
||||||
|
#define GL_UNPACK_ALIGNMENT 0x0CF5
|
||||||
|
#define GL_PACK_ALIGNMENT 0x0D05
|
||||||
|
#define GL_MAX_TEXTURE_SIZE 0x0D33
|
||||||
|
#define GL_TEXTURE_2D 0x0DE1
|
||||||
|
#define GL_UNSIGNED_BYTE 0x1401
|
||||||
|
#define GL_UNSIGNED_SHORT 0x1403
|
||||||
|
#define GL_UNSIGNED_INT 0x1405
|
||||||
|
#define GL_FLOAT 0x1406
|
||||||
|
#define GL_RGBA 0x1908
|
||||||
|
#define GL_FILL 0x1B02
|
||||||
|
#define GL_VENDOR 0x1F00
|
||||||
|
#define GL_RENDERER 0x1F01
|
||||||
|
#define GL_VERSION 0x1F02
|
||||||
|
#define GL_EXTENSIONS 0x1F03
|
||||||
|
#define GL_NEAREST 0x2600
|
||||||
|
#define GL_LINEAR 0x2601
|
||||||
|
#define GL_TEXTURE_MAG_FILTER 0x2800
|
||||||
|
#define GL_TEXTURE_MIN_FILTER 0x2801
|
||||||
|
#define GL_TEXTURE_WRAP_S 0x2802
|
||||||
|
#define GL_TEXTURE_WRAP_T 0x2803
|
||||||
|
#define GL_REPEAT 0x2901
|
||||||
|
typedef void (APIENTRYP PFNGLPOLYGONMODEPROC) (GLenum face, GLenum mode);
|
||||||
|
typedef void (APIENTRYP PFNGLSCISSORPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
|
||||||
|
typedef void (APIENTRYP PFNGLTEXPARAMETERIPROC) (GLenum target, GLenum pname, GLint param);
|
||||||
|
typedef void (APIENTRYP PFNGLTEXIMAGE2DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);
|
||||||
|
typedef void (APIENTRYP PFNGLCLEARPROC) (GLbitfield mask);
|
||||||
|
typedef void (APIENTRYP PFNGLCLEARCOLORPROC) (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
|
||||||
|
typedef void (APIENTRYP PFNGLDISABLEPROC) (GLenum cap);
|
||||||
|
typedef void (APIENTRYP PFNGLENABLEPROC) (GLenum cap);
|
||||||
|
typedef void (APIENTRYP PFNGLFLUSHPROC) (void);
|
||||||
|
typedef void (APIENTRYP PFNGLPIXELSTOREIPROC) (GLenum pname, GLint param);
|
||||||
|
typedef void (APIENTRYP PFNGLREADPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels);
|
||||||
|
typedef GLenum (APIENTRYP PFNGLGETERRORPROC) (void);
|
||||||
|
typedef void (APIENTRYP PFNGLGETINTEGERVPROC) (GLenum pname, GLint *data);
|
||||||
|
typedef const GLubyte *(APIENTRYP PFNGLGETSTRINGPROC) (GLenum name);
|
||||||
|
typedef GLboolean (APIENTRYP PFNGLISENABLEDPROC) (GLenum cap);
|
||||||
|
typedef void (APIENTRYP PFNGLVIEWPORTPROC) (GLint x, GLint y, GLsizei width, GLsizei height);
|
||||||
|
#ifdef GL_GLEXT_PROTOTYPES
|
||||||
|
GLAPI void APIENTRY glPolygonMode (GLenum face, GLenum mode);
|
||||||
|
GLAPI void APIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height);
|
||||||
|
GLAPI void APIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param);
|
||||||
|
GLAPI void APIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);
|
||||||
|
GLAPI void APIENTRY glClear (GLbitfield mask);
|
||||||
|
GLAPI void APIENTRY glClearColor (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
|
||||||
|
GLAPI void APIENTRY glDisable (GLenum cap);
|
||||||
|
GLAPI void APIENTRY glEnable (GLenum cap);
|
||||||
|
GLAPI void APIENTRY glFlush (void);
|
||||||
|
GLAPI void APIENTRY glPixelStorei (GLenum pname, GLint param);
|
||||||
|
GLAPI void APIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels);
|
||||||
|
GLAPI GLenum APIENTRY glGetError (void);
|
||||||
|
GLAPI void APIENTRY glGetIntegerv (GLenum pname, GLint *data);
|
||||||
|
GLAPI const GLubyte *APIENTRY glGetString (GLenum name);
|
||||||
|
GLAPI GLboolean APIENTRY glIsEnabled (GLenum cap);
|
||||||
|
GLAPI void APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height);
|
||||||
|
#endif
|
||||||
|
#endif /* GL_VERSION_1_0 */
|
||||||
|
#ifndef GL_VERSION_1_1
|
||||||
|
typedef khronos_float_t GLclampf;
|
||||||
|
typedef double GLclampd;
|
||||||
|
#define GL_TEXTURE_BINDING_2D 0x8069
|
||||||
|
typedef void (APIENTRYP PFNGLDRAWELEMENTSPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices);
|
||||||
|
typedef void (APIENTRYP PFNGLTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
|
||||||
|
typedef void (APIENTRYP PFNGLBINDTEXTUREPROC) (GLenum target, GLuint texture);
|
||||||
|
typedef void (APIENTRYP PFNGLDELETETEXTURESPROC) (GLsizei n, const GLuint *textures);
|
||||||
|
typedef void (APIENTRYP PFNGLGENTEXTURESPROC) (GLsizei n, GLuint *textures);
|
||||||
|
#ifdef GL_GLEXT_PROTOTYPES
|
||||||
|
GLAPI void APIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const void *indices);
|
||||||
|
GLAPI void APIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
|
||||||
|
GLAPI void APIENTRY glBindTexture (GLenum target, GLuint texture);
|
||||||
|
GLAPI void APIENTRY glDeleteTextures (GLsizei n, const GLuint *textures);
|
||||||
|
GLAPI void APIENTRY glGenTextures (GLsizei n, GLuint *textures);
|
||||||
|
#endif
|
||||||
|
#endif /* GL_VERSION_1_1 */
|
||||||
|
#ifndef GL_VERSION_1_2
|
||||||
|
#define GL_CLAMP_TO_EDGE 0x812F
|
||||||
|
#endif /* GL_VERSION_1_2 */
|
||||||
|
#ifndef GL_VERSION_1_3
|
||||||
|
#define GL_TEXTURE0 0x84C0
|
||||||
|
#define GL_ACTIVE_TEXTURE 0x84E0
|
||||||
|
typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture);
|
||||||
|
#ifdef GL_GLEXT_PROTOTYPES
|
||||||
|
GLAPI void APIENTRY glActiveTexture (GLenum texture);
|
||||||
|
#endif
|
||||||
|
#endif /* GL_VERSION_1_3 */
|
||||||
|
#ifndef GL_VERSION_1_4
|
||||||
|
#define GL_BLEND_DST_RGB 0x80C8
|
||||||
|
#define GL_BLEND_SRC_RGB 0x80C9
|
||||||
|
#define GL_BLEND_DST_ALPHA 0x80CA
|
||||||
|
#define GL_BLEND_SRC_ALPHA 0x80CB
|
||||||
|
#define GL_FUNC_ADD 0x8006
|
||||||
|
typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
|
||||||
|
typedef void (APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode);
|
||||||
|
#ifdef GL_GLEXT_PROTOTYPES
|
||||||
|
GLAPI void APIENTRY glBlendFuncSeparate (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
|
||||||
|
GLAPI void APIENTRY glBlendEquation (GLenum mode);
|
||||||
|
#endif
|
||||||
|
#endif /* GL_VERSION_1_4 */
|
||||||
|
#ifndef GL_VERSION_1_5
|
||||||
|
typedef khronos_ssize_t GLsizeiptr;
|
||||||
|
typedef khronos_intptr_t GLintptr;
|
||||||
|
#define GL_ARRAY_BUFFER 0x8892
|
||||||
|
#define GL_ELEMENT_ARRAY_BUFFER 0x8893
|
||||||
|
#define GL_ARRAY_BUFFER_BINDING 0x8894
|
||||||
|
#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895
|
||||||
|
#define GL_STREAM_DRAW 0x88E0
|
||||||
|
typedef void (APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer);
|
||||||
|
typedef void (APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers);
|
||||||
|
typedef void (APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers);
|
||||||
|
typedef void (APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const void *data, GLenum usage);
|
||||||
|
typedef void (APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const void *data);
|
||||||
|
#ifdef GL_GLEXT_PROTOTYPES
|
||||||
|
GLAPI void APIENTRY glBindBuffer (GLenum target, GLuint buffer);
|
||||||
|
GLAPI void APIENTRY glDeleteBuffers (GLsizei n, const GLuint *buffers);
|
||||||
|
GLAPI void APIENTRY glGenBuffers (GLsizei n, GLuint *buffers);
|
||||||
|
GLAPI void APIENTRY glBufferData (GLenum target, GLsizeiptr size, const void *data, GLenum usage);
|
||||||
|
GLAPI void APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const void *data);
|
||||||
|
#endif
|
||||||
|
#endif /* GL_VERSION_1_5 */
|
||||||
|
#ifndef GL_VERSION_2_0
|
||||||
|
typedef char GLchar;
|
||||||
|
typedef khronos_int16_t GLshort;
|
||||||
|
typedef khronos_int8_t GLbyte;
|
||||||
|
typedef khronos_uint16_t GLushort;
|
||||||
|
#define GL_BLEND_EQUATION_RGB 0x8009
|
||||||
|
#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622
|
||||||
|
#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623
|
||||||
|
#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624
|
||||||
|
#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625
|
||||||
|
#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645
|
||||||
|
#define GL_BLEND_EQUATION_ALPHA 0x883D
|
||||||
|
#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A
|
||||||
|
#define GL_FRAGMENT_SHADER 0x8B30
|
||||||
|
#define GL_VERTEX_SHADER 0x8B31
|
||||||
|
#define GL_COMPILE_STATUS 0x8B81
|
||||||
|
#define GL_LINK_STATUS 0x8B82
|
||||||
|
#define GL_INFO_LOG_LENGTH 0x8B84
|
||||||
|
#define GL_CURRENT_PROGRAM 0x8B8D
|
||||||
|
#define GL_UPPER_LEFT 0x8CA2
|
||||||
|
typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha);
|
||||||
|
typedef void (APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader);
|
||||||
|
typedef void (APIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader);
|
||||||
|
typedef GLuint (APIENTRYP PFNGLCREATEPROGRAMPROC) (void);
|
||||||
|
typedef GLuint (APIENTRYP PFNGLCREATESHADERPROC) (GLenum type);
|
||||||
|
typedef void (APIENTRYP PFNGLDELETEPROGRAMPROC) (GLuint program);
|
||||||
|
typedef void (APIENTRYP PFNGLDELETESHADERPROC) (GLuint shader);
|
||||||
|
typedef void (APIENTRYP PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader);
|
||||||
|
typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index);
|
||||||
|
typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index);
|
||||||
|
typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name);
|
||||||
|
typedef void (APIENTRYP PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params);
|
||||||
|
typedef void (APIENTRYP PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
|
||||||
|
typedef void (APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params);
|
||||||
|
typedef void (APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
|
||||||
|
typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name);
|
||||||
|
typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint *params);
|
||||||
|
typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, void **pointer);
|
||||||
|
typedef GLboolean (APIENTRYP PFNGLISPROGRAMPROC) (GLuint program);
|
||||||
|
typedef void (APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program);
|
||||||
|
typedef void (APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length);
|
||||||
|
typedef void (APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program);
|
||||||
|
typedef void (APIENTRYP PFNGLUNIFORM1IPROC) (GLint location, GLint v0);
|
||||||
|
typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
|
||||||
|
typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);
|
||||||
|
#ifdef GL_GLEXT_PROTOTYPES
|
||||||
|
GLAPI void APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha);
|
||||||
|
GLAPI void APIENTRY glAttachShader (GLuint program, GLuint shader);
|
||||||
|
GLAPI void APIENTRY glCompileShader (GLuint shader);
|
||||||
|
GLAPI GLuint APIENTRY glCreateProgram (void);
|
||||||
|
GLAPI GLuint APIENTRY glCreateShader (GLenum type);
|
||||||
|
GLAPI void APIENTRY glDeleteProgram (GLuint program);
|
||||||
|
GLAPI void APIENTRY glDeleteShader (GLuint shader);
|
||||||
|
GLAPI void APIENTRY glDetachShader (GLuint program, GLuint shader);
|
||||||
|
GLAPI void APIENTRY glDisableVertexAttribArray (GLuint index);
|
||||||
|
GLAPI void APIENTRY glEnableVertexAttribArray (GLuint index);
|
||||||
|
GLAPI GLint APIENTRY glGetAttribLocation (GLuint program, const GLchar *name);
|
||||||
|
GLAPI void APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint *params);
|
||||||
|
GLAPI void APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
|
||||||
|
GLAPI void APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint *params);
|
||||||
|
GLAPI void APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
|
||||||
|
GLAPI GLint APIENTRY glGetUniformLocation (GLuint program, const GLchar *name);
|
||||||
|
GLAPI void APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint *params);
|
||||||
|
GLAPI void APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, void **pointer);
|
||||||
|
GLAPI GLboolean APIENTRY glIsProgram (GLuint program);
|
||||||
|
GLAPI void APIENTRY glLinkProgram (GLuint program);
|
||||||
|
GLAPI void APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length);
|
||||||
|
GLAPI void APIENTRY glUseProgram (GLuint program);
|
||||||
|
GLAPI void APIENTRY glUniform1i (GLint location, GLint v0);
|
||||||
|
GLAPI void APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value);
|
||||||
|
GLAPI void APIENTRY glVertexAttribPointer (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer);
|
||||||
|
#endif
|
||||||
|
#endif /* GL_VERSION_2_0 */
|
||||||
|
#ifndef GL_VERSION_2_1
|
||||||
|
#define GL_PIXEL_UNPACK_BUFFER 0x88EC
|
||||||
|
#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF
|
||||||
|
#endif /* GL_VERSION_2_1 */
|
||||||
|
#ifndef GL_VERSION_3_0
|
||||||
|
typedef khronos_uint16_t GLhalf;
|
||||||
|
#define GL_MAJOR_VERSION 0x821B
|
||||||
|
#define GL_MINOR_VERSION 0x821C
|
||||||
|
#define GL_NUM_EXTENSIONS 0x821D
|
||||||
|
#define GL_FRAMEBUFFER_SRGB 0x8DB9
|
||||||
|
#define GL_VERTEX_ARRAY_BINDING 0x85B5
|
||||||
|
typedef void (APIENTRYP PFNGLGETBOOLEANI_VPROC) (GLenum target, GLuint index, GLboolean *data);
|
||||||
|
typedef void (APIENTRYP PFNGLGETINTEGERI_VPROC) (GLenum target, GLuint index, GLint *data);
|
||||||
|
typedef const GLubyte *(APIENTRYP PFNGLGETSTRINGIPROC) (GLenum name, GLuint index);
|
||||||
|
typedef void (APIENTRYP PFNGLBINDVERTEXARRAYPROC) (GLuint array);
|
||||||
|
typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint *arrays);
|
||||||
|
typedef void (APIENTRYP PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays);
|
||||||
|
#ifdef GL_GLEXT_PROTOTYPES
|
||||||
|
GLAPI const GLubyte *APIENTRY glGetStringi (GLenum name, GLuint index);
|
||||||
|
GLAPI void APIENTRY glBindVertexArray (GLuint array);
|
||||||
|
GLAPI void APIENTRY glDeleteVertexArrays (GLsizei n, const GLuint *arrays);
|
||||||
|
GLAPI void APIENTRY glGenVertexArrays (GLsizei n, GLuint *arrays);
|
||||||
|
#endif
|
||||||
|
#endif /* GL_VERSION_3_0 */
|
||||||
|
#ifndef GL_VERSION_3_1
|
||||||
|
#define GL_VERSION_3_1 1
|
||||||
|
#define GL_PRIMITIVE_RESTART 0x8F9D
|
||||||
|
#endif /* GL_VERSION_3_1 */
|
||||||
|
#ifndef GL_VERSION_3_2
|
||||||
|
#define GL_VERSION_3_2 1
|
||||||
|
typedef struct __GLsync *GLsync;
|
||||||
|
typedef khronos_uint64_t GLuint64;
|
||||||
|
typedef khronos_int64_t GLint64;
|
||||||
|
#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002
|
||||||
|
#define GL_CONTEXT_PROFILE_MASK 0x9126
|
||||||
|
typedef void (APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex);
|
||||||
|
typedef void (APIENTRYP PFNGLGETINTEGER64I_VPROC) (GLenum target, GLuint index, GLint64 *data);
|
||||||
|
#ifdef GL_GLEXT_PROTOTYPES
|
||||||
|
GLAPI void APIENTRY glDrawElementsBaseVertex (GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex);
|
||||||
|
#endif
|
||||||
|
#endif /* GL_VERSION_3_2 */
|
||||||
|
#ifndef GL_VERSION_3_3
|
||||||
|
#define GL_VERSION_3_3 1
|
||||||
|
#define GL_SAMPLER_BINDING 0x8919
|
||||||
|
typedef void (APIENTRYP PFNGLGENSAMPLERSPROC) (GLsizei count, GLuint *samplers);
|
||||||
|
typedef void (APIENTRYP PFNGLDELETESAMPLERSPROC) (GLsizei count, const GLuint *samplers);
|
||||||
|
typedef void (APIENTRYP PFNGLBINDSAMPLERPROC) (GLuint unit, GLuint sampler);
|
||||||
|
typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIPROC) (GLuint sampler, GLenum pname, GLint param);
|
||||||
|
#ifdef GL_GLEXT_PROTOTYPES
|
||||||
|
GLAPI void APIENTRY glGenSamplers (GLsizei count, GLuint *samplers);
|
||||||
|
GLAPI void APIENTRY glDeleteSamplers (GLsizei count, const GLuint *samplers);
|
||||||
|
GLAPI void APIENTRY glBindSampler (GLuint unit, GLuint sampler);
|
||||||
|
GLAPI void APIENTRY glSamplerParameteri (GLuint sampler, GLenum pname, GLint param);
|
||||||
|
#endif
|
||||||
|
#endif /* GL_VERSION_3_3 */
|
||||||
|
#ifndef GL_VERSION_4_1
|
||||||
|
typedef void (APIENTRYP PFNGLGETFLOATI_VPROC) (GLenum target, GLuint index, GLfloat *data);
|
||||||
|
typedef void (APIENTRYP PFNGLGETDOUBLEI_VPROC) (GLenum target, GLuint index, GLdouble *data);
|
||||||
|
#endif /* GL_VERSION_4_1 */
|
||||||
|
#ifndef GL_VERSION_4_3
|
||||||
|
typedef void (APIENTRY *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
|
||||||
|
#endif /* GL_VERSION_4_3 */
|
||||||
|
#ifndef GL_VERSION_4_5
|
||||||
|
#define GL_CLIP_ORIGIN 0x935C
|
||||||
|
typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKI_VPROC) (GLuint xfb, GLenum pname, GLuint index, GLint *param);
|
||||||
|
typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKI64_VPROC) (GLuint xfb, GLenum pname, GLuint index, GLint64 *param);
|
||||||
|
#endif /* GL_VERSION_4_5 */
|
||||||
|
#ifndef GL_ARB_bindless_texture
|
||||||
|
typedef khronos_uint64_t GLuint64EXT;
|
||||||
|
#endif /* GL_ARB_bindless_texture */
|
||||||
|
#ifndef GL_ARB_cl_event
|
||||||
|
struct _cl_context;
|
||||||
|
struct _cl_event;
|
||||||
|
#endif /* GL_ARB_cl_event */
|
||||||
|
#ifndef GL_ARB_clip_control
|
||||||
|
#define GL_ARB_clip_control 1
|
||||||
|
#endif /* GL_ARB_clip_control */
|
||||||
|
#ifndef GL_ARB_debug_output
|
||||||
|
typedef void (APIENTRY *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam);
|
||||||
|
#endif /* GL_ARB_debug_output */
|
||||||
|
#ifndef GL_EXT_EGL_image_storage
|
||||||
|
typedef void *GLeglImageOES;
|
||||||
|
#endif /* GL_EXT_EGL_image_storage */
|
||||||
|
#ifndef GL_EXT_direct_state_access
|
||||||
|
typedef void (APIENTRYP PFNGLGETFLOATI_VEXTPROC) (GLenum pname, GLuint index, GLfloat *params);
|
||||||
|
typedef void (APIENTRYP PFNGLGETDOUBLEI_VEXTPROC) (GLenum pname, GLuint index, GLdouble *params);
|
||||||
|
typedef void (APIENTRYP PFNGLGETPOINTERI_VEXTPROC) (GLenum pname, GLuint index, void **params);
|
||||||
|
typedef void (APIENTRYP PFNGLGETVERTEXARRAYINTEGERI_VEXTPROC) (GLuint vaobj, GLuint index, GLenum pname, GLint *param);
|
||||||
|
typedef void (APIENTRYP PFNGLGETVERTEXARRAYPOINTERI_VEXTPROC) (GLuint vaobj, GLuint index, GLenum pname, void **param);
|
||||||
|
#endif /* GL_EXT_direct_state_access */
|
||||||
|
#ifndef GL_NV_draw_vulkan_image
|
||||||
|
typedef void (APIENTRY *GLVULKANPROCNV)(void);
|
||||||
|
#endif /* GL_NV_draw_vulkan_image */
|
||||||
|
#ifndef GL_NV_gpu_shader5
|
||||||
|
typedef khronos_int64_t GLint64EXT;
|
||||||
|
#endif /* GL_NV_gpu_shader5 */
|
||||||
|
#ifndef GL_NV_vertex_buffer_unified_memory
|
||||||
|
typedef void (APIENTRYP PFNGLGETINTEGERUI64I_VNVPROC) (GLenum value, GLuint index, GLuint64EXT *result);
|
||||||
|
#endif /* GL_NV_vertex_buffer_unified_memory */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef GL3W_API
|
||||||
|
#define GL3W_API
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __gl_h_
|
||||||
|
#define __gl_h_
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define GL3W_OK 0
|
||||||
|
#define GL3W_ERROR_INIT -1
|
||||||
|
#define GL3W_ERROR_LIBRARY_OPEN -2
|
||||||
|
#define GL3W_ERROR_OPENGL_VERSION -3
|
||||||
|
|
||||||
|
typedef void (*GL3WglProc)(void);
|
||||||
|
typedef GL3WglProc (*GL3WGetProcAddressProc)(const char *proc);
|
||||||
|
|
||||||
|
/* gl3w api */
|
||||||
|
GL3W_API int imgl3wInit(void);
|
||||||
|
GL3W_API int imgl3wInit2(GL3WGetProcAddressProc proc);
|
||||||
|
GL3W_API void imgl3wShutdown(void);
|
||||||
|
GL3W_API int imgl3wIsSupported(int major, int minor);
|
||||||
|
GL3W_API GL3WglProc imgl3wGetProcAddress(const char *proc);
|
||||||
|
|
||||||
|
/* gl3w internal state */
|
||||||
|
union ImGL3WProcs {
|
||||||
|
GL3WglProc ptr[63];
|
||||||
|
struct {
|
||||||
|
PFNGLACTIVETEXTUREPROC ActiveTexture;
|
||||||
|
PFNGLATTACHSHADERPROC AttachShader;
|
||||||
|
PFNGLBINDBUFFERPROC BindBuffer;
|
||||||
|
PFNGLBINDSAMPLERPROC BindSampler;
|
||||||
|
PFNGLBINDTEXTUREPROC BindTexture;
|
||||||
|
PFNGLBINDVERTEXARRAYPROC BindVertexArray;
|
||||||
|
PFNGLBLENDEQUATIONPROC BlendEquation;
|
||||||
|
PFNGLBLENDEQUATIONSEPARATEPROC BlendEquationSeparate;
|
||||||
|
PFNGLBLENDFUNCSEPARATEPROC BlendFuncSeparate;
|
||||||
|
PFNGLBUFFERDATAPROC BufferData;
|
||||||
|
PFNGLBUFFERSUBDATAPROC BufferSubData;
|
||||||
|
PFNGLCLEARPROC Clear;
|
||||||
|
PFNGLCLEARCOLORPROC ClearColor;
|
||||||
|
PFNGLCOMPILESHADERPROC CompileShader;
|
||||||
|
PFNGLCREATEPROGRAMPROC CreateProgram;
|
||||||
|
PFNGLCREATESHADERPROC CreateShader;
|
||||||
|
PFNGLDELETEBUFFERSPROC DeleteBuffers;
|
||||||
|
PFNGLDELETEPROGRAMPROC DeleteProgram;
|
||||||
|
PFNGLDELETESAMPLERSPROC DeleteSamplers;
|
||||||
|
PFNGLDELETESHADERPROC DeleteShader;
|
||||||
|
PFNGLDELETETEXTURESPROC DeleteTextures;
|
||||||
|
PFNGLDELETEVERTEXARRAYSPROC DeleteVertexArrays;
|
||||||
|
PFNGLDETACHSHADERPROC DetachShader;
|
||||||
|
PFNGLDISABLEPROC Disable;
|
||||||
|
PFNGLDISABLEVERTEXATTRIBARRAYPROC DisableVertexAttribArray;
|
||||||
|
PFNGLDRAWELEMENTSPROC DrawElements;
|
||||||
|
PFNGLDRAWELEMENTSBASEVERTEXPROC DrawElementsBaseVertex;
|
||||||
|
PFNGLENABLEPROC Enable;
|
||||||
|
PFNGLENABLEVERTEXATTRIBARRAYPROC EnableVertexAttribArray;
|
||||||
|
PFNGLFLUSHPROC Flush;
|
||||||
|
PFNGLGENBUFFERSPROC GenBuffers;
|
||||||
|
PFNGLGENSAMPLERSPROC GenSamplers;
|
||||||
|
PFNGLGENTEXTURESPROC GenTextures;
|
||||||
|
PFNGLGENVERTEXARRAYSPROC GenVertexArrays;
|
||||||
|
PFNGLGETATTRIBLOCATIONPROC GetAttribLocation;
|
||||||
|
PFNGLGETERRORPROC GetError;
|
||||||
|
PFNGLGETINTEGERVPROC GetIntegerv;
|
||||||
|
PFNGLGETPROGRAMINFOLOGPROC GetProgramInfoLog;
|
||||||
|
PFNGLGETPROGRAMIVPROC GetProgramiv;
|
||||||
|
PFNGLGETSHADERINFOLOGPROC GetShaderInfoLog;
|
||||||
|
PFNGLGETSHADERIVPROC GetShaderiv;
|
||||||
|
PFNGLGETSTRINGPROC GetString;
|
||||||
|
PFNGLGETSTRINGIPROC GetStringi;
|
||||||
|
PFNGLGETUNIFORMLOCATIONPROC GetUniformLocation;
|
||||||
|
PFNGLGETVERTEXATTRIBPOINTERVPROC GetVertexAttribPointerv;
|
||||||
|
PFNGLGETVERTEXATTRIBIVPROC GetVertexAttribiv;
|
||||||
|
PFNGLISENABLEDPROC IsEnabled;
|
||||||
|
PFNGLISPROGRAMPROC IsProgram;
|
||||||
|
PFNGLLINKPROGRAMPROC LinkProgram;
|
||||||
|
PFNGLPIXELSTOREIPROC PixelStorei;
|
||||||
|
PFNGLPOLYGONMODEPROC PolygonMode;
|
||||||
|
PFNGLREADPIXELSPROC ReadPixels;
|
||||||
|
PFNGLSAMPLERPARAMETERIPROC SamplerParameteri;
|
||||||
|
PFNGLSCISSORPROC Scissor;
|
||||||
|
PFNGLSHADERSOURCEPROC ShaderSource;
|
||||||
|
PFNGLTEXIMAGE2DPROC TexImage2D;
|
||||||
|
PFNGLTEXPARAMETERIPROC TexParameteri;
|
||||||
|
PFNGLTEXSUBIMAGE2DPROC TexSubImage2D;
|
||||||
|
PFNGLUNIFORM1IPROC Uniform1i;
|
||||||
|
PFNGLUNIFORMMATRIX4FVPROC UniformMatrix4fv;
|
||||||
|
PFNGLUSEPROGRAMPROC UseProgram;
|
||||||
|
PFNGLVERTEXATTRIBPOINTERPROC VertexAttribPointer;
|
||||||
|
PFNGLVIEWPORTPROC Viewport;
|
||||||
|
} gl;
|
||||||
|
};
|
||||||
|
|
||||||
|
GL3W_API extern union ImGL3WProcs imgl3wProcs;
|
||||||
|
|
||||||
|
/* OpenGL functions */
|
||||||
|
#define glActiveTexture imgl3wProcs.gl.ActiveTexture
|
||||||
|
#define glAttachShader imgl3wProcs.gl.AttachShader
|
||||||
|
#define glBindBuffer imgl3wProcs.gl.BindBuffer
|
||||||
|
#define glBindSampler imgl3wProcs.gl.BindSampler
|
||||||
|
#define glBindTexture imgl3wProcs.gl.BindTexture
|
||||||
|
#define glBindVertexArray imgl3wProcs.gl.BindVertexArray
|
||||||
|
#define glBlendEquation imgl3wProcs.gl.BlendEquation
|
||||||
|
#define glBlendEquationSeparate imgl3wProcs.gl.BlendEquationSeparate
|
||||||
|
#define glBlendFuncSeparate imgl3wProcs.gl.BlendFuncSeparate
|
||||||
|
#define glBufferData imgl3wProcs.gl.BufferData
|
||||||
|
#define glBufferSubData imgl3wProcs.gl.BufferSubData
|
||||||
|
#define glClear imgl3wProcs.gl.Clear
|
||||||
|
#define glClearColor imgl3wProcs.gl.ClearColor
|
||||||
|
#define glCompileShader imgl3wProcs.gl.CompileShader
|
||||||
|
#define glCreateProgram imgl3wProcs.gl.CreateProgram
|
||||||
|
#define glCreateShader imgl3wProcs.gl.CreateShader
|
||||||
|
#define glDeleteBuffers imgl3wProcs.gl.DeleteBuffers
|
||||||
|
#define glDeleteProgram imgl3wProcs.gl.DeleteProgram
|
||||||
|
#define glDeleteSamplers imgl3wProcs.gl.DeleteSamplers
|
||||||
|
#define glDeleteShader imgl3wProcs.gl.DeleteShader
|
||||||
|
#define glDeleteTextures imgl3wProcs.gl.DeleteTextures
|
||||||
|
#define glDeleteVertexArrays imgl3wProcs.gl.DeleteVertexArrays
|
||||||
|
#define glDetachShader imgl3wProcs.gl.DetachShader
|
||||||
|
#define glDisable imgl3wProcs.gl.Disable
|
||||||
|
#define glDisableVertexAttribArray imgl3wProcs.gl.DisableVertexAttribArray
|
||||||
|
#define glDrawElements imgl3wProcs.gl.DrawElements
|
||||||
|
#define glDrawElementsBaseVertex imgl3wProcs.gl.DrawElementsBaseVertex
|
||||||
|
#define glEnable imgl3wProcs.gl.Enable
|
||||||
|
#define glEnableVertexAttribArray imgl3wProcs.gl.EnableVertexAttribArray
|
||||||
|
#define glFlush imgl3wProcs.gl.Flush
|
||||||
|
#define glGenBuffers imgl3wProcs.gl.GenBuffers
|
||||||
|
#define glGenSamplers imgl3wProcs.gl.GenSamplers
|
||||||
|
#define glGenTextures imgl3wProcs.gl.GenTextures
|
||||||
|
#define glGenVertexArrays imgl3wProcs.gl.GenVertexArrays
|
||||||
|
#define glGetAttribLocation imgl3wProcs.gl.GetAttribLocation
|
||||||
|
#define glGetError imgl3wProcs.gl.GetError
|
||||||
|
#define glGetIntegerv imgl3wProcs.gl.GetIntegerv
|
||||||
|
#define glGetProgramInfoLog imgl3wProcs.gl.GetProgramInfoLog
|
||||||
|
#define glGetProgramiv imgl3wProcs.gl.GetProgramiv
|
||||||
|
#define glGetShaderInfoLog imgl3wProcs.gl.GetShaderInfoLog
|
||||||
|
#define glGetShaderiv imgl3wProcs.gl.GetShaderiv
|
||||||
|
#define glGetString imgl3wProcs.gl.GetString
|
||||||
|
#define glGetStringi imgl3wProcs.gl.GetStringi
|
||||||
|
#define glGetUniformLocation imgl3wProcs.gl.GetUniformLocation
|
||||||
|
#define glGetVertexAttribPointerv imgl3wProcs.gl.GetVertexAttribPointerv
|
||||||
|
#define glGetVertexAttribiv imgl3wProcs.gl.GetVertexAttribiv
|
||||||
|
#define glIsEnabled imgl3wProcs.gl.IsEnabled
|
||||||
|
#define glIsProgram imgl3wProcs.gl.IsProgram
|
||||||
|
#define glLinkProgram imgl3wProcs.gl.LinkProgram
|
||||||
|
#define glPixelStorei imgl3wProcs.gl.PixelStorei
|
||||||
|
#define glPolygonMode imgl3wProcs.gl.PolygonMode
|
||||||
|
#define glReadPixels imgl3wProcs.gl.ReadPixels
|
||||||
|
#define glSamplerParameteri imgl3wProcs.gl.SamplerParameteri
|
||||||
|
#define glScissor imgl3wProcs.gl.Scissor
|
||||||
|
#define glShaderSource imgl3wProcs.gl.ShaderSource
|
||||||
|
#define glTexImage2D imgl3wProcs.gl.TexImage2D
|
||||||
|
#define glTexParameteri imgl3wProcs.gl.TexParameteri
|
||||||
|
#define glTexSubImage2D imgl3wProcs.gl.TexSubImage2D
|
||||||
|
#define glUniform1i imgl3wProcs.gl.Uniform1i
|
||||||
|
#define glUniformMatrix4fv imgl3wProcs.gl.UniformMatrix4fv
|
||||||
|
#define glUseProgram imgl3wProcs.gl.UseProgram
|
||||||
|
#define glVertexAttribPointer imgl3wProcs.gl.VertexAttribPointer
|
||||||
|
#define glViewport imgl3wProcs.gl.Viewport
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef IMGL3W_IMPL
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#define GL3W_ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
#ifndef WIN32_LEAN_AND_MEAN
|
||||||
|
#define WIN32_LEAN_AND_MEAN 1
|
||||||
|
#endif
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
static HMODULE libgl = NULL;
|
||||||
|
typedef PROC(__stdcall* GL3WglGetProcAddr)(LPCSTR);
|
||||||
|
static GL3WglGetProcAddr wgl_get_proc_address;
|
||||||
|
|
||||||
|
static int open_libgl(void)
|
||||||
|
{
|
||||||
|
libgl = LoadLibraryA("opengl32.dll");
|
||||||
|
if (!libgl)
|
||||||
|
return GL3W_ERROR_LIBRARY_OPEN;
|
||||||
|
wgl_get_proc_address = (GL3WglGetProcAddr)GetProcAddress(libgl, "wglGetProcAddress");
|
||||||
|
return GL3W_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void close_libgl(void) { FreeLibrary(libgl); libgl = NULL; }
|
||||||
|
static GL3WglProc get_proc(const char *proc)
|
||||||
|
{
|
||||||
|
GL3WglProc res;
|
||||||
|
res = (GL3WglProc)wgl_get_proc_address(proc);
|
||||||
|
if (!res)
|
||||||
|
res = (GL3WglProc)GetProcAddress(libgl, proc);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
#include <dlfcn.h>
|
||||||
|
|
||||||
|
static void *libgl = NULL;
|
||||||
|
static int open_libgl(void)
|
||||||
|
{
|
||||||
|
libgl = dlopen("/System/Library/Frameworks/OpenGL.framework/OpenGL", RTLD_LAZY | RTLD_LOCAL);
|
||||||
|
if (!libgl)
|
||||||
|
return GL3W_ERROR_LIBRARY_OPEN;
|
||||||
|
return GL3W_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void close_libgl(void) { dlclose(libgl); libgl = NULL; }
|
||||||
|
|
||||||
|
static GL3WglProc get_proc(const char *proc)
|
||||||
|
{
|
||||||
|
GL3WglProc res;
|
||||||
|
*(void **)(&res) = dlsym(libgl, proc);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#include <dlfcn.h>
|
||||||
|
|
||||||
|
static void* libgl; // OpenGL library
|
||||||
|
static void* libglx; // GLX library
|
||||||
|
static void* libegl; // EGL library
|
||||||
|
static GL3WGetProcAddressProc gl_get_proc_address;
|
||||||
|
|
||||||
|
static void close_libgl(void)
|
||||||
|
{
|
||||||
|
if (libgl) {
|
||||||
|
dlclose(libgl);
|
||||||
|
libgl = NULL;
|
||||||
|
}
|
||||||
|
if (libegl) {
|
||||||
|
dlclose(libegl);
|
||||||
|
libegl = NULL;
|
||||||
|
}
|
||||||
|
if (libglx) {
|
||||||
|
dlclose(libglx);
|
||||||
|
libglx = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int is_library_loaded(const char* name, void** lib)
|
||||||
|
{
|
||||||
|
#if defined(__HAIKU__)
|
||||||
|
*lib = NULL; // no support for RTLD_NOLOAD on Haiku.
|
||||||
|
#else
|
||||||
|
*lib = dlopen(name, RTLD_LAZY | RTLD_LOCAL | RTLD_NOLOAD);
|
||||||
|
#endif
|
||||||
|
return *lib != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int open_libs(void)
|
||||||
|
{
|
||||||
|
// On Linux we have two APIs to get process addresses: EGL and GLX.
|
||||||
|
// EGL is supported under both X11 and Wayland, whereas GLX is X11-specific.
|
||||||
|
|
||||||
|
libgl = NULL;
|
||||||
|
libegl = NULL;
|
||||||
|
libglx = NULL;
|
||||||
|
|
||||||
|
// First check what's already loaded, the windowing library might have
|
||||||
|
// already loaded either EGL or GLX and we want to use the same one.
|
||||||
|
|
||||||
|
if (is_library_loaded("libEGL.so.1", &libegl) ||
|
||||||
|
is_library_loaded("libGLX.so.0", &libglx)) {
|
||||||
|
libgl = dlopen("libOpenGL.so.0", RTLD_LAZY | RTLD_LOCAL);
|
||||||
|
if (libgl)
|
||||||
|
return GL3W_OK;
|
||||||
|
else
|
||||||
|
close_libgl();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_library_loaded("libGL.so", &libgl))
|
||||||
|
return GL3W_OK;
|
||||||
|
if (is_library_loaded("libGL.so.1", &libgl))
|
||||||
|
return GL3W_OK;
|
||||||
|
if (is_library_loaded("libGL.so.3", &libgl))
|
||||||
|
return GL3W_OK;
|
||||||
|
|
||||||
|
// Neither is already loaded, so we have to load one. Try EGL first
|
||||||
|
// because it is supported under both X11 and Wayland.
|
||||||
|
|
||||||
|
// Load OpenGL + EGL
|
||||||
|
libgl = dlopen("libOpenGL.so.0", RTLD_LAZY | RTLD_LOCAL);
|
||||||
|
libegl = dlopen("libEGL.so.1", RTLD_LAZY | RTLD_LOCAL);
|
||||||
|
if (libgl && libegl)
|
||||||
|
return GL3W_OK;
|
||||||
|
else
|
||||||
|
close_libgl();
|
||||||
|
|
||||||
|
// Fall back to legacy libGL, which includes GLX
|
||||||
|
// While most systems use libGL.so.1, NetBSD seems to use that libGL.so.3. See https://github.com/ocornut/imgui/issues/6983
|
||||||
|
libgl = dlopen("libGL.so", RTLD_LAZY | RTLD_LOCAL);
|
||||||
|
if (!libgl)
|
||||||
|
libgl = dlopen("libGL.so.1", RTLD_LAZY | RTLD_LOCAL);
|
||||||
|
if (!libgl)
|
||||||
|
libgl = dlopen("libGL.so.3", RTLD_LAZY | RTLD_LOCAL);
|
||||||
|
|
||||||
|
if (libgl)
|
||||||
|
return GL3W_OK;
|
||||||
|
|
||||||
|
return GL3W_ERROR_LIBRARY_OPEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int open_libgl(void)
|
||||||
|
{
|
||||||
|
int res = open_libs();
|
||||||
|
if (res)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
if (libegl)
|
||||||
|
*(void**)(&gl_get_proc_address) = dlsym(libegl, "eglGetProcAddress");
|
||||||
|
else if (libglx)
|
||||||
|
*(void**)(&gl_get_proc_address) = dlsym(libglx, "glXGetProcAddressARB");
|
||||||
|
else
|
||||||
|
*(void**)(&gl_get_proc_address) = dlsym(libgl, "glXGetProcAddressARB");
|
||||||
|
|
||||||
|
if (!gl_get_proc_address) {
|
||||||
|
close_libgl();
|
||||||
|
return GL3W_ERROR_LIBRARY_OPEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
return GL3W_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GL3WglProc get_proc(const char* proc)
|
||||||
|
{
|
||||||
|
GL3WglProc res = NULL;
|
||||||
|
|
||||||
|
// Before EGL version 1.5, eglGetProcAddress doesn't support querying core
|
||||||
|
// functions and may return a dummy function if we try, so try to load the
|
||||||
|
// function from the GL library directly first.
|
||||||
|
if (libegl)
|
||||||
|
*(void**)(&res) = dlsym(libgl, proc);
|
||||||
|
|
||||||
|
if (!res)
|
||||||
|
res = gl_get_proc_address(proc);
|
||||||
|
|
||||||
|
if (!libegl && !res)
|
||||||
|
*(void**)(&res) = dlsym(libgl, proc);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static struct { int major, minor; } version;
|
||||||
|
|
||||||
|
static int parse_version(void)
|
||||||
|
{
|
||||||
|
if (!glGetIntegerv)
|
||||||
|
return GL3W_ERROR_INIT;
|
||||||
|
glGetIntegerv(GL_MAJOR_VERSION, &version.major);
|
||||||
|
glGetIntegerv(GL_MINOR_VERSION, &version.minor);
|
||||||
|
if (version.major == 0 && version.minor == 0)
|
||||||
|
{
|
||||||
|
// Query GL_VERSION in desktop GL 2.x, the string will start with "<major>.<minor>"
|
||||||
|
if (const char* gl_version = (const char*)glGetString(GL_VERSION))
|
||||||
|
sscanf(gl_version, "%d.%d", &version.major, &version.minor);
|
||||||
|
}
|
||||||
|
if (version.major < 2)
|
||||||
|
return GL3W_ERROR_OPENGL_VERSION;
|
||||||
|
return GL3W_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void load_procs(GL3WGetProcAddressProc proc);
|
||||||
|
static void clear_procs();
|
||||||
|
|
||||||
|
int imgl3wInit(void)
|
||||||
|
{
|
||||||
|
int res = open_libgl();
|
||||||
|
if (res)
|
||||||
|
return res;
|
||||||
|
atexit(close_libgl);
|
||||||
|
return imgl3wInit2(get_proc);
|
||||||
|
}
|
||||||
|
|
||||||
|
int imgl3wInit2(GL3WGetProcAddressProc proc)
|
||||||
|
{
|
||||||
|
load_procs(proc);
|
||||||
|
return parse_version();
|
||||||
|
}
|
||||||
|
|
||||||
|
void imgl3wShutdown(void)
|
||||||
|
{
|
||||||
|
close_libgl();
|
||||||
|
clear_procs();
|
||||||
|
}
|
||||||
|
|
||||||
|
int imgl3wIsSupported(int major, int minor)
|
||||||
|
{
|
||||||
|
if (major < 2)
|
||||||
|
return 0;
|
||||||
|
if (version.major == major)
|
||||||
|
return version.minor >= minor;
|
||||||
|
return version.major >= major;
|
||||||
|
}
|
||||||
|
|
||||||
|
GL3WglProc imgl3wGetProcAddress(const char *proc) { return get_proc(proc); }
|
||||||
|
|
||||||
|
static const char *proc_names[] = {
|
||||||
|
"glActiveTexture",
|
||||||
|
"glAttachShader",
|
||||||
|
"glBindBuffer",
|
||||||
|
"glBindSampler",
|
||||||
|
"glBindTexture",
|
||||||
|
"glBindVertexArray",
|
||||||
|
"glBlendEquation",
|
||||||
|
"glBlendEquationSeparate",
|
||||||
|
"glBlendFuncSeparate",
|
||||||
|
"glBufferData",
|
||||||
|
"glBufferSubData",
|
||||||
|
"glClear",
|
||||||
|
"glClearColor",
|
||||||
|
"glCompileShader",
|
||||||
|
"glCreateProgram",
|
||||||
|
"glCreateShader",
|
||||||
|
"glDeleteBuffers",
|
||||||
|
"glDeleteProgram",
|
||||||
|
"glDeleteSamplers",
|
||||||
|
"glDeleteShader",
|
||||||
|
"glDeleteTextures",
|
||||||
|
"glDeleteVertexArrays",
|
||||||
|
"glDetachShader",
|
||||||
|
"glDisable",
|
||||||
|
"glDisableVertexAttribArray",
|
||||||
|
"glDrawElements",
|
||||||
|
"glDrawElementsBaseVertex",
|
||||||
|
"glEnable",
|
||||||
|
"glEnableVertexAttribArray",
|
||||||
|
"glFlush",
|
||||||
|
"glGenBuffers",
|
||||||
|
"glGenSamplers",
|
||||||
|
"glGenTextures",
|
||||||
|
"glGenVertexArrays",
|
||||||
|
"glGetAttribLocation",
|
||||||
|
"glGetError",
|
||||||
|
"glGetIntegerv",
|
||||||
|
"glGetProgramInfoLog",
|
||||||
|
"glGetProgramiv",
|
||||||
|
"glGetShaderInfoLog",
|
||||||
|
"glGetShaderiv",
|
||||||
|
"glGetString",
|
||||||
|
"glGetStringi",
|
||||||
|
"glGetUniformLocation",
|
||||||
|
"glGetVertexAttribPointerv",
|
||||||
|
"glGetVertexAttribiv",
|
||||||
|
"glIsEnabled",
|
||||||
|
"glIsProgram",
|
||||||
|
"glLinkProgram",
|
||||||
|
"glPixelStorei",
|
||||||
|
"glPolygonMode",
|
||||||
|
"glReadPixels",
|
||||||
|
"glSamplerParameteri",
|
||||||
|
"glScissor",
|
||||||
|
"glShaderSource",
|
||||||
|
"glTexImage2D",
|
||||||
|
"glTexParameteri",
|
||||||
|
"glTexSubImage2D",
|
||||||
|
"glUniform1i",
|
||||||
|
"glUniformMatrix4fv",
|
||||||
|
"glUseProgram",
|
||||||
|
"glVertexAttribPointer",
|
||||||
|
"glViewport",
|
||||||
|
};
|
||||||
|
|
||||||
|
GL3W_API union ImGL3WProcs imgl3wProcs;
|
||||||
|
|
||||||
|
static void load_procs(GL3WGetProcAddressProc proc)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < GL3W_ARRAY_SIZE(proc_names); i++)
|
||||||
|
imgl3wProcs.ptr[i] = proc(proc_names[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void clear_procs()
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < GL3W_ARRAY_SIZE(proc_names); i++)
|
||||||
|
imgl3wProcs.ptr[i] = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
1293
libs/imgui/backends/imgui_impl_sdl3.cpp
Normal file
50
libs/imgui/backends/imgui_impl_sdl3.h
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
// dear imgui: Platform Backend for SDL3
|
||||||
|
// This needs to be used along with a Renderer (e.g. SDL_GPU, DirectX11, OpenGL3, Vulkan..)
|
||||||
|
// (Info: SDL3 is a cross-platform general purpose library for handling windows, inputs, graphics context creation, etc.)
|
||||||
|
|
||||||
|
// Implemented features:
|
||||||
|
// [X] Platform: Clipboard support.
|
||||||
|
// [X] Platform: Mouse support. Can discriminate Mouse/TouchScreen.
|
||||||
|
// [X] Platform: Keyboard support. Since 1.87 we are using the io.AddKeyEvent() function. Pass ImGuiKey values to all key functions e.g. ImGui::IsKeyPressed(ImGuiKey_Space). [Legacy SDL_SCANCODE_* values are obsolete since 1.87 and not supported since 1.91.5]
|
||||||
|
// [X] Platform: Gamepad support.
|
||||||
|
// [X] Platform: Mouse cursor shape and visibility (ImGuiBackendFlags_HasMouseCursors). Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||||
|
// [x] Platform: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable' -> the OS animation effect when window gets created/destroyed is problematic. SDL2 backend doesn't have issue.
|
||||||
|
// Missing features or Issues:
|
||||||
|
// [ ] Platform: Multi-viewport: Minimized windows seems to break mouse wheel events (at least under Windows).
|
||||||
|
// [x] Platform: IME support. Position somehow broken in SDL3 + app needs to call 'SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");' before SDL_CreateWindow()!.
|
||||||
|
|
||||||
|
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||||
|
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||||
|
// Learn about Dear ImGui:
|
||||||
|
// - FAQ https://dearimgui.com/faq
|
||||||
|
// - Getting Started https://dearimgui.com/getting-started
|
||||||
|
// - Documentation https://dearimgui.com/docs (same as your local docs/ folder).
|
||||||
|
// - Introduction, links and more at the top of imgui.cpp
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "imgui.h" // IMGUI_IMPL_API
|
||||||
|
#ifndef IMGUI_DISABLE
|
||||||
|
|
||||||
|
struct SDL_Window;
|
||||||
|
struct SDL_Renderer;
|
||||||
|
struct SDL_Gamepad;
|
||||||
|
typedef union SDL_Event SDL_Event;
|
||||||
|
|
||||||
|
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplSDL3_InitForOpenGL(SDL_Window* window, void* sdl_gl_context);
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplSDL3_InitForVulkan(SDL_Window* window);
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplSDL3_InitForD3D(SDL_Window* window);
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplSDL3_InitForMetal(SDL_Window* window);
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplSDL3_InitForSDLRenderer(SDL_Window* window, SDL_Renderer* renderer);
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplSDL3_InitForSDLGPU(SDL_Window* window);
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplSDL3_InitForOther(SDL_Window* window);
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplSDL3_Shutdown();
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplSDL3_NewFrame();
|
||||||
|
IMGUI_IMPL_API bool ImGui_ImplSDL3_ProcessEvent(const SDL_Event* event);
|
||||||
|
|
||||||
|
// Gamepad selection automatically starts in AutoFirst mode, picking first available SDL_Gamepad. You may override this.
|
||||||
|
// When using manual mode, caller is responsible for opening/closing gamepad.
|
||||||
|
enum ImGui_ImplSDL3_GamepadMode { ImGui_ImplSDL3_GamepadMode_AutoFirst, ImGui_ImplSDL3_GamepadMode_AutoAll, ImGui_ImplSDL3_GamepadMode_Manual };
|
||||||
|
IMGUI_IMPL_API void ImGui_ImplSDL3_SetGamepadMode(ImGui_ImplSDL3_GamepadMode mode, SDL_Gamepad** manual_gamepads_array = nullptr, int manual_gamepads_count = -1);
|
||||||
|
|
||||||
|
#endif // #ifndef IMGUI_DISABLE
|
||||||
147
libs/imgui/imconfig.h
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// DEAR IMGUI COMPILE-TIME OPTIONS
|
||||||
|
// 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/rebased branch with your modifications to it)
|
||||||
|
// B) or '#define IMGUI_USER_CONFIG "my_imgui_config.h"' in your project and then add directives in your own file without touching this template.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// 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 file 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.
|
||||||
|
// - Compiling with NDEBUG will usually strip out assert() to nothing, which is NOT recommended because we use asserts to notify of programmer mistakes.
|
||||||
|
//#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.
|
||||||
|
// - Windows DLL users: heaps and globals are not shared across DLL boundaries! You will need to call SetCurrentContext() + SetAllocatorFunctions()
|
||||||
|
// for each static/DLL boundary you are calling from. Read "Context and Memory Allocators" section of imgui.cpp for more details.
|
||||||
|
//#define IMGUI_API __declspec(dllexport) // MSVC Windows: DLL export
|
||||||
|
//#define IMGUI_API __declspec(dllimport) // MSVC Windows: DLL import
|
||||||
|
//#define IMGUI_API __attribute__((visibility("default"))) // GCC/Clang: override visibility when set is hidden
|
||||||
|
|
||||||
|
//---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to clean your code of obsolete function/names.
|
||||||
|
//#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||||
|
|
||||||
|
//---- Disable all of Dear ImGui or don't implement standard windows/tools.
|
||||||
|
// It is very strongly recommended to NOT disable the demo windows and debug tool during development. They are extremely useful in day to day work. 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.
|
||||||
|
//#define IMGUI_DISABLE_DEBUG_TOOLS // Disable metrics/debugger and other debug tools: ShowMetricsWindow(), ShowDebugLogWindow() and ShowIDStackToolWindow() 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. (user32.lib/.a, kernel32.lib/.a)
|
||||||
|
//#define IMGUI_ENABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with Visual Studio] Implement default IME handler (require imm32.lib/.a, auto-link for Visual Studio, -limm32 on command-line for MinGW)
|
||||||
|
//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with non-Visual Studio compilers] Don't implement default IME handler (won't require imm32.lib/.a)
|
||||||
|
//#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_SHELL_FUNCTIONS // Don't implement default platform_io.Platform_OpenInShellFn() handler (Win32: ShellExecute(), require shell32.lib/.a, Mac/Linux: use system("")).
|
||||||
|
//#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_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle at all (replace them with dummies)
|
||||||
|
//#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle 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().
|
||||||
|
//#define IMGUI_DISABLE_DEFAULT_FONT // Disable default embedded fonts (ProggyClean/ProggyVector), remove ~9 KB + ~17 KB from output binary. AddFontDefaultXXX() functions will assert.
|
||||||
|
//#define IMGUI_DISABLE_SSE // Disable use of SSE intrinsics even if available
|
||||||
|
|
||||||
|
//---- Enable Test Engine / Automation features.
|
||||||
|
//#define IMGUI_ENABLE_TEST_ENGINE // Enable imgui_test_engine hooks. Generally set automatically by include "imgui_te_config.h", see Test Engine for details.
|
||||||
|
|
||||||
|
//---- Include imgui_user.h at the end of imgui.h as a convenience
|
||||||
|
// May be convenient for some users to only explicitly include vanilla imgui.h and have extra stuff included.
|
||||||
|
//#define IMGUI_INCLUDE_IMGUI_USER_H
|
||||||
|
//#define IMGUI_USER_H_FILENAME "my_folder/my_imgui_user.h"
|
||||||
|
|
||||||
|
//---- Pack vertex colors as BGRA8 instead of RGBA8 (to avoid converting from one to another). Need dedicated backend support.
|
||||||
|
//#define IMGUI_USE_BGRA_PACKED_COLOR
|
||||||
|
|
||||||
|
//---- Use legacy CRC32-adler tables (used before 1.91.6), in order to preserve old .ini data that you cannot afford to invalidate.
|
||||||
|
//#define IMGUI_USE_LEGACY_CRC32_ADLER
|
||||||
|
|
||||||
|
//---- Use 32-bit for ImWchar (default is 16-bit) to support Unicode planes 1-16. (e.g. point beyond 0xFFFF like emoticons, dingbats, symbols, shapes, ancient languages, etc...)
|
||||||
|
//#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 Dear ImGui sources 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_STB_SPRINTF_FILENAME "my_folder/stb_sprintf.h" // only used if IMGUI_USE_STB_SPRINTF is defined.
|
||||||
|
//#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION
|
||||||
|
//#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION
|
||||||
|
//#define IMGUI_DISABLE_STB_SPRINTF_IMPLEMENTATION // only disabled if IMGUI_USE_STB_SPRINTF is defined.
|
||||||
|
|
||||||
|
//---- Use stb_sprintf.h for a faster implementation of vsnprintf instead of the one from libc (unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined)
|
||||||
|
// Compatibility checks of arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by stb_sprintf.h.
|
||||||
|
//#define IMGUI_USE_STB_SPRINTF
|
||||||
|
|
||||||
|
//---- Use FreeType to build and rasterize the font atlas (instead of stb_truetype which is embedded by default in Dear ImGui)
|
||||||
|
// Requires FreeType headers to be available in the include path. Requires program to be compiled with 'misc/freetype/imgui_freetype.cpp' (in this repository) + the FreeType library (not provided).
|
||||||
|
// Note that imgui_freetype.cpp may be used _without_ this define, if you manually call ImFontAtlas::SetFontLoader(). The define is simply a convenience.
|
||||||
|
// On Windows you may use vcpkg with 'vcpkg install freetype --triplet=x64-windows' + 'vcpkg integrate install'.
|
||||||
|
//#define IMGUI_ENABLE_FREETYPE
|
||||||
|
|
||||||
|
//---- Use FreeType + plutosvg or lunasvg to render OpenType SVG fonts (SVGinOT)
|
||||||
|
// Only works in combination with IMGUI_ENABLE_FREETYPE.
|
||||||
|
// - plutosvg is currently easier to install, as e.g. it is part of vcpkg. It will support more fonts and may load them faster. See misc/freetype/README for instructions.
|
||||||
|
// - Both require headers to be available in the include path + program to be linked with the library code (not provided).
|
||||||
|
// - (note: lunasvg implementation is based on Freetype's rsvg-port.c which is licensed under CeCILL-C Free Software License Agreement)
|
||||||
|
//#define IMGUI_ENABLE_FREETYPE_PLUTOSVG
|
||||||
|
//#define IMGUI_ENABLE_FREETYPE_LUNASVG
|
||||||
|
|
||||||
|
//---- Use stb_truetype to build and rasterize the font atlas (default)
|
||||||
|
// The only purpose of this define is if you want force compilation of the stb_truetype backend ALONG with the FreeType backend.
|
||||||
|
//#define IMGUI_ENABLE_STB_TRUETYPE
|
||||||
|
|
||||||
|
//---- 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 \
|
||||||
|
constexpr ImVec2(const MyVec2& f) : x(f.x), y(f.y) {} \
|
||||||
|
operator MyVec2() const { return MyVec2(x,y); }
|
||||||
|
|
||||||
|
#define IM_VEC4_CLASS_EXTRA \
|
||||||
|
constexpr 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); }
|
||||||
|
*/
|
||||||
|
//---- ...Or use Dear ImGui's own very basic math operators.
|
||||||
|
//#define IMGUI_DEFINE_MATH_OPERATORS
|
||||||
|
|
||||||
|
//---- Use 32-bit vertex indices (default is 16-bit) is one way to allow large meshes with more than 64K vertices.
|
||||||
|
// Your renderer backend will need to support it (most example renderer backends 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 backends 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 (we provide a default implementation of this in the codebase)
|
||||||
|
// (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: Enable highlight ID conflicts _before_ hovering items. When io.ConfigDebugHighlightIdConflicts is set.
|
||||||
|
// (THIS WILL SLOW DOWN DEAR IMGUI. Only use occasionally and disable after use)
|
||||||
|
//#define IMGUI_DEBUG_HIGHLIGHT_ALL_ID_CONFLICTS
|
||||||
|
|
||||||
|
//---- Debug Tools: Enable slower asserts
|
||||||
|
//#define IMGUI_DEBUG_PARANOID
|
||||||
|
|
||||||
|
//---- Tip: You can add extra functions within the ImGui:: namespace from anywhere (e.g. your own sources/header files)
|
||||||
|
/*
|
||||||
|
namespace ImGui
|
||||||
|
{
|
||||||
|
void MyFunction(const char* name, MyMatrix44* mtx);
|
||||||
|
}
|
||||||
|
*/
|
||||||
24139
libs/imgui/imgui.cpp
Normal file
4473
libs/imgui/imgui.h
Normal file
11282
libs/imgui/imgui_demo.cpp
Normal file
6824
libs/imgui/imgui_draw.cpp
Normal file
4282
libs/imgui/imgui_internal.h
Normal file
4560
libs/imgui/imgui_tables.cpp
Normal file
10940
libs/imgui/imgui_widgets.cpp
Normal file
627
libs/imgui/imstb_rectpack.h
Normal file
@@ -0,0 +1,627 @@
|
|||||||
|
// [DEAR IMGUI]
|
||||||
|
// This is a slightly modified version of stb_rect_pack.h 1.01.
|
||||||
|
// Grep for [DEAR IMGUI] to find the changes.
|
||||||
|
//
|
||||||
|
// stb_rect_pack.h - v1.01 - public domain - rectangle packing
|
||||||
|
// Sean Barrett 2014
|
||||||
|
//
|
||||||
|
// Useful for e.g. packing rectangular textures into an atlas.
|
||||||
|
// Does not do rotation.
|
||||||
|
//
|
||||||
|
// Before #including,
|
||||||
|
//
|
||||||
|
// #define STB_RECT_PACK_IMPLEMENTATION
|
||||||
|
//
|
||||||
|
// in the file that you want to have the implementation.
|
||||||
|
//
|
||||||
|
// 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.01 (2021-07-11) always use large rect mode, expose STBRP__MAXVAL in public section
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
typedef int stbrp_coord;
|
||||||
|
|
||||||
|
#define STBRP__MAXVAL 0x7fffffff
|
||||||
|
// Mostly for internal use, but this is the maximum supported coordinate value.
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
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;
|
||||||
|
context->extra[1].y = (1<<30);
|
||||||
|
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); [DEAR IMGUI]
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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.
|
||||||
|
------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
1527
libs/imgui/imstb_textedit.h
Normal file
5085
libs/imgui/imstb_truetype.h
Normal file
107
libs/incbin.h
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
/*
|
||||||
|
* incbin.h — Portable binary embedding via assembler .incbin directive
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
* INCBIN(myData, "path/to/file.bin");
|
||||||
|
*
|
||||||
|
* This creates:
|
||||||
|
* extern const unsigned char g_myData_data[]; // file contents
|
||||||
|
* extern const unsigned char *g_myData_end; // one past end
|
||||||
|
* extern const unsigned int g_myData_size; // byte count
|
||||||
|
*
|
||||||
|
* Compared to xxd -i hex arrays, this uses near-zero compile-time RAM
|
||||||
|
* because the assembler streams the file directly into the object file
|
||||||
|
* without building an AST for millions of array elements.
|
||||||
|
*
|
||||||
|
* Supports: GCC, Clang, MinGW (any target that uses GAS).
|
||||||
|
* MSVC: not supported (would need a different strategy).
|
||||||
|
*
|
||||||
|
* Based on the public-domain incbin technique.
|
||||||
|
* Adapted for DragonX Wallet by The Hush Developers, 2024-2026.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DRAGONX_INCBIN_H
|
||||||
|
#define DRAGONX_INCBIN_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helper macros for token pasting and stringification.
|
||||||
|
*/
|
||||||
|
#define INCBIN_CAT(a, b) INCBIN_CAT_(a, b)
|
||||||
|
#define INCBIN_CAT_(a, b) a ## b
|
||||||
|
#define INCBIN_STR(x) INCBIN_STR_(x)
|
||||||
|
#define INCBIN_STR_(x) #x
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Section attribute: place embedded data in .rodata so it lives in the
|
||||||
|
* read-only segment just like a normal const array would.
|
||||||
|
*/
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
# define INCBIN_SECTION ".const_data"
|
||||||
|
# define INCBIN_MANGLE "_"
|
||||||
|
#else
|
||||||
|
# define INCBIN_SECTION ".rodata"
|
||||||
|
# define INCBIN_MANGLE ""
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Alignment: 16 bytes is sufficient for SIMD loads if anyone ever
|
||||||
|
* wants to process embedded data with SSE/NEON, and is a safe default.
|
||||||
|
*/
|
||||||
|
#define INCBIN_ALIGN 16
|
||||||
|
|
||||||
|
/*
|
||||||
|
* INCBIN_EXTERN — declare the symbols (use in headers)
|
||||||
|
*/
|
||||||
|
#define INCBIN_EXTERN(NAME) \
|
||||||
|
extern const unsigned char INCBIN_CAT(g_, INCBIN_CAT(NAME, _data))[]; \
|
||||||
|
extern const unsigned char *INCBIN_CAT(g_, INCBIN_CAT(NAME, _end)); \
|
||||||
|
extern const unsigned int INCBIN_CAT(g_, INCBIN_CAT(NAME, _size))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* INCBIN — define the symbols + embed the file (use in ONE .cpp/.c file)
|
||||||
|
*
|
||||||
|
* NAME : C identifier prefix (no quotes)
|
||||||
|
* FILE : path to the file to embed (string literal, relative to -I or absolute)
|
||||||
|
*
|
||||||
|
* The generated assembly:
|
||||||
|
* .section .rodata
|
||||||
|
* .balign 16
|
||||||
|
* .global g_NAME_data
|
||||||
|
* g_NAME_data:
|
||||||
|
* .incbin "FILE"
|
||||||
|
* .global g_NAME_end
|
||||||
|
* g_NAME_end:
|
||||||
|
* .byte 0 // NUL sentinel for C string compatibility
|
||||||
|
* .balign 4
|
||||||
|
* .global g_NAME_size
|
||||||
|
* g_NAME_size:
|
||||||
|
* .int g_NAME_end - g_NAME_data
|
||||||
|
*/
|
||||||
|
#define INCBIN(NAME, FILE) \
|
||||||
|
__asm__( \
|
||||||
|
".section " INCBIN_SECTION "\n" \
|
||||||
|
".balign " INCBIN_STR(INCBIN_ALIGN) "\n" \
|
||||||
|
".global " INCBIN_MANGLE "g_" #NAME "_data\n" \
|
||||||
|
INCBIN_MANGLE "g_" #NAME "_data:\n" \
|
||||||
|
" .incbin \"" FILE "\"\n" \
|
||||||
|
".global " INCBIN_MANGLE "g_" #NAME "_end\n" \
|
||||||
|
INCBIN_MANGLE "g_" #NAME "_end:\n" \
|
||||||
|
" .byte 0\n" \
|
||||||
|
".balign 4\n" \
|
||||||
|
".global " INCBIN_MANGLE "g_" #NAME "_size\n" \
|
||||||
|
INCBIN_MANGLE "g_" #NAME "_size:\n" \
|
||||||
|
" .int " INCBIN_MANGLE "g_" #NAME "_end - " \
|
||||||
|
INCBIN_MANGLE "g_" #NAME "_data\n" \
|
||||||
|
".text\n" /* restore default section */ \
|
||||||
|
); \
|
||||||
|
INCBIN_EXTERN(NAME)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* DRAGONX_INCBIN_H */
|
||||||
646
libs/miniz/miniz.c
Normal file
@@ -0,0 +1,646 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2013-2014 RAD Game Tools and Valve Software
|
||||||
|
* Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
|
||||||
|
* All Rights Reserved.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#include "miniz.h"
|
||||||
|
|
||||||
|
typedef unsigned char mz_validate_uint16[sizeof(mz_uint16) == 2 ? 1 : -1];
|
||||||
|
typedef unsigned char mz_validate_uint32[sizeof(mz_uint32) == 4 ? 1 : -1];
|
||||||
|
typedef unsigned char mz_validate_uint64[sizeof(mz_uint64) == 8 ? 1 : -1];
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ------------------- zlib-style API's */
|
||||||
|
|
||||||
|
mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len)
|
||||||
|
{
|
||||||
|
mz_uint32 i, s1 = (mz_uint32)(adler & 0xffff), s2 = (mz_uint32)(adler >> 16);
|
||||||
|
size_t block_len = buf_len % 5552;
|
||||||
|
if (!ptr)
|
||||||
|
return MZ_ADLER32_INIT;
|
||||||
|
while (buf_len)
|
||||||
|
{
|
||||||
|
for (i = 0; i + 7 < block_len; i += 8, ptr += 8)
|
||||||
|
{
|
||||||
|
s1 += ptr[0], s2 += s1;
|
||||||
|
s1 += ptr[1], s2 += s1;
|
||||||
|
s1 += ptr[2], s2 += s1;
|
||||||
|
s1 += ptr[3], s2 += s1;
|
||||||
|
s1 += ptr[4], s2 += s1;
|
||||||
|
s1 += ptr[5], s2 += s1;
|
||||||
|
s1 += ptr[6], s2 += s1;
|
||||||
|
s1 += ptr[7], s2 += s1;
|
||||||
|
}
|
||||||
|
for (; i < block_len; ++i)
|
||||||
|
s1 += *ptr++, s2 += s1;
|
||||||
|
s1 %= 65521U, s2 %= 65521U;
|
||||||
|
buf_len -= block_len;
|
||||||
|
block_len = 5552;
|
||||||
|
}
|
||||||
|
return (s2 << 16) + s1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Karl Malbrain's compact CRC-32. See "A compact CCITT crc16 and crc32 C implementation that balances processor cache usage against speed": http://www.geocities.com/malbrain/ */
|
||||||
|
#if 0
|
||||||
|
mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len)
|
||||||
|
{
|
||||||
|
static const mz_uint32 s_crc32[16] = { 0, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
|
||||||
|
0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c };
|
||||||
|
mz_uint32 crcu32 = (mz_uint32)crc;
|
||||||
|
if (!ptr)
|
||||||
|
return MZ_CRC32_INIT;
|
||||||
|
crcu32 = ~crcu32;
|
||||||
|
while (buf_len--)
|
||||||
|
{
|
||||||
|
mz_uint8 b = *ptr++;
|
||||||
|
crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b & 0xF)];
|
||||||
|
crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b >> 4)];
|
||||||
|
}
|
||||||
|
return ~crcu32;
|
||||||
|
}
|
||||||
|
#elif defined(USE_EXTERNAL_MZCRC)
|
||||||
|
/* If USE_EXTERNAL_CRC is defined, an external module will export the
|
||||||
|
* mz_crc32() symbol for us to use, e.g. an SSE-accelerated version.
|
||||||
|
* Depending on the impl, it may be necessary to ~ the input/output crc values.
|
||||||
|
*/
|
||||||
|
mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len);
|
||||||
|
#else
|
||||||
|
/* Faster, but larger CPU cache footprint.
|
||||||
|
*/
|
||||||
|
mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len)
|
||||||
|
{
|
||||||
|
static const mz_uint32 s_crc_table[256] = {
|
||||||
|
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535,
|
||||||
|
0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD,
|
||||||
|
0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D,
|
||||||
|
0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
|
||||||
|
0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4,
|
||||||
|
0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
|
||||||
|
0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC,
|
||||||
|
0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
|
||||||
|
0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB,
|
||||||
|
0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F,
|
||||||
|
0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB,
|
||||||
|
0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
|
||||||
|
0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA,
|
||||||
|
0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 0x4DB26158, 0x3AB551CE,
|
||||||
|
0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A,
|
||||||
|
0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
|
||||||
|
0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409,
|
||||||
|
0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
|
||||||
|
0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739,
|
||||||
|
0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
|
||||||
|
0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268,
|
||||||
|
0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0,
|
||||||
|
0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8,
|
||||||
|
0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
|
||||||
|
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF,
|
||||||
|
0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703,
|
||||||
|
0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7,
|
||||||
|
0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
|
||||||
|
0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE,
|
||||||
|
0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
|
||||||
|
0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 0x88085AE6,
|
||||||
|
0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
|
||||||
|
0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D,
|
||||||
|
0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5,
|
||||||
|
0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605,
|
||||||
|
0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
|
||||||
|
0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
|
||||||
|
};
|
||||||
|
|
||||||
|
mz_uint32 crc32 = (mz_uint32)crc ^ 0xFFFFFFFF;
|
||||||
|
const mz_uint8 *pByte_buf = (const mz_uint8 *)ptr;
|
||||||
|
|
||||||
|
while (buf_len >= 4)
|
||||||
|
{
|
||||||
|
crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[0]) & 0xFF];
|
||||||
|
crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[1]) & 0xFF];
|
||||||
|
crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[2]) & 0xFF];
|
||||||
|
crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[3]) & 0xFF];
|
||||||
|
pByte_buf += 4;
|
||||||
|
buf_len -= 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (buf_len)
|
||||||
|
{
|
||||||
|
crc32 = (crc32 >> 8) ^ s_crc_table[(crc32 ^ pByte_buf[0]) & 0xFF];
|
||||||
|
++pByte_buf;
|
||||||
|
--buf_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ~crc32;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void mz_free(void *p)
|
||||||
|
{
|
||||||
|
MZ_FREE(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
MINIZ_EXPORT void *miniz_def_alloc_func(void *opaque, size_t items, size_t size)
|
||||||
|
{
|
||||||
|
(void)opaque, (void)items, (void)size;
|
||||||
|
return MZ_MALLOC(items * size);
|
||||||
|
}
|
||||||
|
MINIZ_EXPORT void miniz_def_free_func(void *opaque, void *address)
|
||||||
|
{
|
||||||
|
(void)opaque, (void)address;
|
||||||
|
MZ_FREE(address);
|
||||||
|
}
|
||||||
|
MINIZ_EXPORT void *miniz_def_realloc_func(void *opaque, void *address, size_t items, size_t size)
|
||||||
|
{
|
||||||
|
(void)opaque, (void)address, (void)items, (void)size;
|
||||||
|
return MZ_REALLOC(address, items * size);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *mz_version(void)
|
||||||
|
{
|
||||||
|
return MZ_VERSION;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef MINIZ_NO_ZLIB_APIS
|
||||||
|
|
||||||
|
#ifndef MINIZ_NO_DEFLATE_APIS
|
||||||
|
|
||||||
|
int mz_deflateInit(mz_streamp pStream, int level)
|
||||||
|
{
|
||||||
|
return mz_deflateInit2(pStream, level, MZ_DEFLATED, MZ_DEFAULT_WINDOW_BITS, 9, MZ_DEFAULT_STRATEGY);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy)
|
||||||
|
{
|
||||||
|
tdefl_compressor *pComp;
|
||||||
|
mz_uint comp_flags = TDEFL_COMPUTE_ADLER32 | tdefl_create_comp_flags_from_zip_params(level, window_bits, strategy);
|
||||||
|
|
||||||
|
if (!pStream)
|
||||||
|
return MZ_STREAM_ERROR;
|
||||||
|
if ((method != MZ_DEFLATED) || ((mem_level < 1) || (mem_level > 9)) || ((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS)))
|
||||||
|
return MZ_PARAM_ERROR;
|
||||||
|
|
||||||
|
pStream->data_type = 0;
|
||||||
|
pStream->adler = MZ_ADLER32_INIT;
|
||||||
|
pStream->msg = NULL;
|
||||||
|
pStream->reserved = 0;
|
||||||
|
pStream->total_in = 0;
|
||||||
|
pStream->total_out = 0;
|
||||||
|
if (!pStream->zalloc)
|
||||||
|
pStream->zalloc = miniz_def_alloc_func;
|
||||||
|
if (!pStream->zfree)
|
||||||
|
pStream->zfree = miniz_def_free_func;
|
||||||
|
|
||||||
|
pComp = (tdefl_compressor *)pStream->zalloc(pStream->opaque, 1, sizeof(tdefl_compressor));
|
||||||
|
if (!pComp)
|
||||||
|
return MZ_MEM_ERROR;
|
||||||
|
|
||||||
|
pStream->state = (struct mz_internal_state *)pComp;
|
||||||
|
|
||||||
|
if (tdefl_init(pComp, NULL, NULL, comp_flags) != TDEFL_STATUS_OKAY)
|
||||||
|
{
|
||||||
|
mz_deflateEnd(pStream);
|
||||||
|
return MZ_PARAM_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return MZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mz_deflateReset(mz_streamp pStream)
|
||||||
|
{
|
||||||
|
if ((!pStream) || (!pStream->state) || (!pStream->zalloc) || (!pStream->zfree))
|
||||||
|
return MZ_STREAM_ERROR;
|
||||||
|
pStream->total_in = pStream->total_out = 0;
|
||||||
|
tdefl_init((tdefl_compressor *)pStream->state, NULL, NULL, ((tdefl_compressor *)pStream->state)->m_flags);
|
||||||
|
return MZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mz_deflate(mz_streamp pStream, int flush)
|
||||||
|
{
|
||||||
|
size_t in_bytes, out_bytes;
|
||||||
|
mz_ulong orig_total_in, orig_total_out;
|
||||||
|
int mz_status = MZ_OK;
|
||||||
|
|
||||||
|
if ((!pStream) || (!pStream->state) || (flush < 0) || (flush > MZ_FINISH) || (!pStream->next_out))
|
||||||
|
return MZ_STREAM_ERROR;
|
||||||
|
if (!pStream->avail_out)
|
||||||
|
return MZ_BUF_ERROR;
|
||||||
|
|
||||||
|
if (flush == MZ_PARTIAL_FLUSH)
|
||||||
|
flush = MZ_SYNC_FLUSH;
|
||||||
|
|
||||||
|
if (((tdefl_compressor *)pStream->state)->m_prev_return_status == TDEFL_STATUS_DONE)
|
||||||
|
return (flush == MZ_FINISH) ? MZ_STREAM_END : MZ_BUF_ERROR;
|
||||||
|
|
||||||
|
orig_total_in = pStream->total_in;
|
||||||
|
orig_total_out = pStream->total_out;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
tdefl_status defl_status;
|
||||||
|
in_bytes = pStream->avail_in;
|
||||||
|
out_bytes = pStream->avail_out;
|
||||||
|
|
||||||
|
defl_status = tdefl_compress((tdefl_compressor *)pStream->state, pStream->next_in, &in_bytes, pStream->next_out, &out_bytes, (tdefl_flush)flush);
|
||||||
|
pStream->next_in += (mz_uint)in_bytes;
|
||||||
|
pStream->avail_in -= (mz_uint)in_bytes;
|
||||||
|
pStream->total_in += (mz_uint)in_bytes;
|
||||||
|
pStream->adler = tdefl_get_adler32((tdefl_compressor *)pStream->state);
|
||||||
|
|
||||||
|
pStream->next_out += (mz_uint)out_bytes;
|
||||||
|
pStream->avail_out -= (mz_uint)out_bytes;
|
||||||
|
pStream->total_out += (mz_uint)out_bytes;
|
||||||
|
|
||||||
|
if (defl_status < 0)
|
||||||
|
{
|
||||||
|
mz_status = MZ_STREAM_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (defl_status == TDEFL_STATUS_DONE)
|
||||||
|
{
|
||||||
|
mz_status = MZ_STREAM_END;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (!pStream->avail_out)
|
||||||
|
break;
|
||||||
|
else if ((!pStream->avail_in) && (flush != MZ_FINISH))
|
||||||
|
{
|
||||||
|
if ((flush) || (pStream->total_in != orig_total_in) || (pStream->total_out != orig_total_out))
|
||||||
|
break;
|
||||||
|
return MZ_BUF_ERROR; /* Can't make forward progress without some input.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mz_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mz_deflateEnd(mz_streamp pStream)
|
||||||
|
{
|
||||||
|
if (!pStream)
|
||||||
|
return MZ_STREAM_ERROR;
|
||||||
|
if (pStream->state)
|
||||||
|
{
|
||||||
|
pStream->zfree(pStream->opaque, pStream->state);
|
||||||
|
pStream->state = NULL;
|
||||||
|
}
|
||||||
|
return MZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len)
|
||||||
|
{
|
||||||
|
(void)pStream;
|
||||||
|
/* This is really over conservative. (And lame, but it's actually pretty tricky to compute a true upper bound given the way tdefl's blocking works.) */
|
||||||
|
return MZ_MAX(128 + (source_len * 110) / 100, 128 + source_len + ((source_len / (31 * 1024)) + 1) * 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level)
|
||||||
|
{
|
||||||
|
int status;
|
||||||
|
mz_stream stream;
|
||||||
|
memset(&stream, 0, sizeof(stream));
|
||||||
|
|
||||||
|
/* In case mz_ulong is 64-bits (argh I hate longs). */
|
||||||
|
if ((mz_uint64)(source_len | *pDest_len) > 0xFFFFFFFFU)
|
||||||
|
return MZ_PARAM_ERROR;
|
||||||
|
|
||||||
|
stream.next_in = pSource;
|
||||||
|
stream.avail_in = (mz_uint32)source_len;
|
||||||
|
stream.next_out = pDest;
|
||||||
|
stream.avail_out = (mz_uint32)*pDest_len;
|
||||||
|
|
||||||
|
status = mz_deflateInit(&stream, level);
|
||||||
|
if (status != MZ_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
status = mz_deflate(&stream, MZ_FINISH);
|
||||||
|
if (status != MZ_STREAM_END)
|
||||||
|
{
|
||||||
|
mz_deflateEnd(&stream);
|
||||||
|
return (status == MZ_OK) ? MZ_BUF_ERROR : status;
|
||||||
|
}
|
||||||
|
|
||||||
|
*pDest_len = stream.total_out;
|
||||||
|
return mz_deflateEnd(&stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len)
|
||||||
|
{
|
||||||
|
return mz_compress2(pDest, pDest_len, pSource, source_len, MZ_DEFAULT_COMPRESSION);
|
||||||
|
}
|
||||||
|
|
||||||
|
mz_ulong mz_compressBound(mz_ulong source_len)
|
||||||
|
{
|
||||||
|
return mz_deflateBound(NULL, source_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /*#ifndef MINIZ_NO_DEFLATE_APIS*/
|
||||||
|
|
||||||
|
#ifndef MINIZ_NO_INFLATE_APIS
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
tinfl_decompressor m_decomp;
|
||||||
|
mz_uint m_dict_ofs, m_dict_avail, m_first_call, m_has_flushed;
|
||||||
|
int m_window_bits;
|
||||||
|
mz_uint8 m_dict[TINFL_LZ_DICT_SIZE];
|
||||||
|
tinfl_status m_last_status;
|
||||||
|
} inflate_state;
|
||||||
|
|
||||||
|
int mz_inflateInit2(mz_streamp pStream, int window_bits)
|
||||||
|
{
|
||||||
|
inflate_state *pDecomp;
|
||||||
|
if (!pStream)
|
||||||
|
return MZ_STREAM_ERROR;
|
||||||
|
if ((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS))
|
||||||
|
return MZ_PARAM_ERROR;
|
||||||
|
|
||||||
|
pStream->data_type = 0;
|
||||||
|
pStream->adler = 0;
|
||||||
|
pStream->msg = NULL;
|
||||||
|
pStream->total_in = 0;
|
||||||
|
pStream->total_out = 0;
|
||||||
|
pStream->reserved = 0;
|
||||||
|
if (!pStream->zalloc)
|
||||||
|
pStream->zalloc = miniz_def_alloc_func;
|
||||||
|
if (!pStream->zfree)
|
||||||
|
pStream->zfree = miniz_def_free_func;
|
||||||
|
|
||||||
|
pDecomp = (inflate_state *)pStream->zalloc(pStream->opaque, 1, sizeof(inflate_state));
|
||||||
|
if (!pDecomp)
|
||||||
|
return MZ_MEM_ERROR;
|
||||||
|
|
||||||
|
pStream->state = (struct mz_internal_state *)pDecomp;
|
||||||
|
|
||||||
|
tinfl_init(&pDecomp->m_decomp);
|
||||||
|
pDecomp->m_dict_ofs = 0;
|
||||||
|
pDecomp->m_dict_avail = 0;
|
||||||
|
pDecomp->m_last_status = TINFL_STATUS_NEEDS_MORE_INPUT;
|
||||||
|
pDecomp->m_first_call = 1;
|
||||||
|
pDecomp->m_has_flushed = 0;
|
||||||
|
pDecomp->m_window_bits = window_bits;
|
||||||
|
|
||||||
|
return MZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mz_inflateInit(mz_streamp pStream)
|
||||||
|
{
|
||||||
|
return mz_inflateInit2(pStream, MZ_DEFAULT_WINDOW_BITS);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mz_inflateReset(mz_streamp pStream)
|
||||||
|
{
|
||||||
|
inflate_state *pDecomp;
|
||||||
|
if (!pStream)
|
||||||
|
return MZ_STREAM_ERROR;
|
||||||
|
|
||||||
|
pStream->data_type = 0;
|
||||||
|
pStream->adler = 0;
|
||||||
|
pStream->msg = NULL;
|
||||||
|
pStream->total_in = 0;
|
||||||
|
pStream->total_out = 0;
|
||||||
|
pStream->reserved = 0;
|
||||||
|
|
||||||
|
pDecomp = (inflate_state *)pStream->state;
|
||||||
|
|
||||||
|
tinfl_init(&pDecomp->m_decomp);
|
||||||
|
pDecomp->m_dict_ofs = 0;
|
||||||
|
pDecomp->m_dict_avail = 0;
|
||||||
|
pDecomp->m_last_status = TINFL_STATUS_NEEDS_MORE_INPUT;
|
||||||
|
pDecomp->m_first_call = 1;
|
||||||
|
pDecomp->m_has_flushed = 0;
|
||||||
|
/* pDecomp->m_window_bits = window_bits */;
|
||||||
|
|
||||||
|
return MZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mz_inflate(mz_streamp pStream, int flush)
|
||||||
|
{
|
||||||
|
inflate_state *pState;
|
||||||
|
mz_uint n, first_call, decomp_flags = TINFL_FLAG_COMPUTE_ADLER32;
|
||||||
|
size_t in_bytes, out_bytes, orig_avail_in;
|
||||||
|
tinfl_status status;
|
||||||
|
|
||||||
|
if ((!pStream) || (!pStream->state))
|
||||||
|
return MZ_STREAM_ERROR;
|
||||||
|
if (flush == MZ_PARTIAL_FLUSH)
|
||||||
|
flush = MZ_SYNC_FLUSH;
|
||||||
|
if ((flush) && (flush != MZ_SYNC_FLUSH) && (flush != MZ_FINISH))
|
||||||
|
return MZ_STREAM_ERROR;
|
||||||
|
|
||||||
|
pState = (inflate_state *)pStream->state;
|
||||||
|
if (pState->m_window_bits > 0)
|
||||||
|
decomp_flags |= TINFL_FLAG_PARSE_ZLIB_HEADER;
|
||||||
|
orig_avail_in = pStream->avail_in;
|
||||||
|
|
||||||
|
first_call = pState->m_first_call;
|
||||||
|
pState->m_first_call = 0;
|
||||||
|
if (pState->m_last_status < 0)
|
||||||
|
return MZ_DATA_ERROR;
|
||||||
|
|
||||||
|
if (pState->m_has_flushed && (flush != MZ_FINISH))
|
||||||
|
return MZ_STREAM_ERROR;
|
||||||
|
pState->m_has_flushed |= (flush == MZ_FINISH);
|
||||||
|
|
||||||
|
if ((flush == MZ_FINISH) && (first_call))
|
||||||
|
{
|
||||||
|
/* MZ_FINISH on the first call implies that the input and output buffers are large enough to hold the entire compressed/decompressed file. */
|
||||||
|
decomp_flags |= TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF;
|
||||||
|
in_bytes = pStream->avail_in;
|
||||||
|
out_bytes = pStream->avail_out;
|
||||||
|
status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pStream->next_out, pStream->next_out, &out_bytes, decomp_flags);
|
||||||
|
pState->m_last_status = status;
|
||||||
|
pStream->next_in += (mz_uint)in_bytes;
|
||||||
|
pStream->avail_in -= (mz_uint)in_bytes;
|
||||||
|
pStream->total_in += (mz_uint)in_bytes;
|
||||||
|
pStream->adler = tinfl_get_adler32(&pState->m_decomp);
|
||||||
|
pStream->next_out += (mz_uint)out_bytes;
|
||||||
|
pStream->avail_out -= (mz_uint)out_bytes;
|
||||||
|
pStream->total_out += (mz_uint)out_bytes;
|
||||||
|
|
||||||
|
if (status < 0)
|
||||||
|
return MZ_DATA_ERROR;
|
||||||
|
else if (status != TINFL_STATUS_DONE)
|
||||||
|
{
|
||||||
|
pState->m_last_status = TINFL_STATUS_FAILED;
|
||||||
|
return MZ_BUF_ERROR;
|
||||||
|
}
|
||||||
|
return MZ_STREAM_END;
|
||||||
|
}
|
||||||
|
/* flush != MZ_FINISH then we must assume there's more input. */
|
||||||
|
if (flush != MZ_FINISH)
|
||||||
|
decomp_flags |= TINFL_FLAG_HAS_MORE_INPUT;
|
||||||
|
|
||||||
|
if (pState->m_dict_avail)
|
||||||
|
{
|
||||||
|
n = MZ_MIN(pState->m_dict_avail, pStream->avail_out);
|
||||||
|
memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n);
|
||||||
|
pStream->next_out += n;
|
||||||
|
pStream->avail_out -= n;
|
||||||
|
pStream->total_out += n;
|
||||||
|
pState->m_dict_avail -= n;
|
||||||
|
pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1);
|
||||||
|
return ((pState->m_last_status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
in_bytes = pStream->avail_in;
|
||||||
|
out_bytes = TINFL_LZ_DICT_SIZE - pState->m_dict_ofs;
|
||||||
|
|
||||||
|
status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pState->m_dict, pState->m_dict + pState->m_dict_ofs, &out_bytes, decomp_flags);
|
||||||
|
pState->m_last_status = status;
|
||||||
|
|
||||||
|
pStream->next_in += (mz_uint)in_bytes;
|
||||||
|
pStream->avail_in -= (mz_uint)in_bytes;
|
||||||
|
pStream->total_in += (mz_uint)in_bytes;
|
||||||
|
pStream->adler = tinfl_get_adler32(&pState->m_decomp);
|
||||||
|
|
||||||
|
pState->m_dict_avail = (mz_uint)out_bytes;
|
||||||
|
|
||||||
|
n = MZ_MIN(pState->m_dict_avail, pStream->avail_out);
|
||||||
|
memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n);
|
||||||
|
pStream->next_out += n;
|
||||||
|
pStream->avail_out -= n;
|
||||||
|
pStream->total_out += n;
|
||||||
|
pState->m_dict_avail -= n;
|
||||||
|
pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1);
|
||||||
|
|
||||||
|
if (status < 0)
|
||||||
|
return MZ_DATA_ERROR; /* Stream is corrupted (there could be some uncompressed data left in the output dictionary - oh well). */
|
||||||
|
else if ((status == TINFL_STATUS_NEEDS_MORE_INPUT) && (!orig_avail_in))
|
||||||
|
return MZ_BUF_ERROR; /* Signal caller that we can't make forward progress without supplying more input or by setting flush to MZ_FINISH. */
|
||||||
|
else if (flush == MZ_FINISH)
|
||||||
|
{
|
||||||
|
/* The output buffer MUST be large to hold the remaining uncompressed data when flush==MZ_FINISH. */
|
||||||
|
if (status == TINFL_STATUS_DONE)
|
||||||
|
return pState->m_dict_avail ? MZ_BUF_ERROR : MZ_STREAM_END;
|
||||||
|
/* status here must be TINFL_STATUS_HAS_MORE_OUTPUT, which means there's at least 1 more byte on the way. If there's no more room left in the output buffer then something is wrong. */
|
||||||
|
else if (!pStream->avail_out)
|
||||||
|
return MZ_BUF_ERROR;
|
||||||
|
}
|
||||||
|
else if ((status == TINFL_STATUS_DONE) || (!pStream->avail_in) || (!pStream->avail_out) || (pState->m_dict_avail))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ((status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mz_inflateEnd(mz_streamp pStream)
|
||||||
|
{
|
||||||
|
if (!pStream)
|
||||||
|
return MZ_STREAM_ERROR;
|
||||||
|
if (pStream->state)
|
||||||
|
{
|
||||||
|
pStream->zfree(pStream->opaque, pStream->state);
|
||||||
|
pStream->state = NULL;
|
||||||
|
}
|
||||||
|
return MZ_OK;
|
||||||
|
}
|
||||||
|
int mz_uncompress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong *pSource_len)
|
||||||
|
{
|
||||||
|
mz_stream stream;
|
||||||
|
int status;
|
||||||
|
memset(&stream, 0, sizeof(stream));
|
||||||
|
|
||||||
|
/* In case mz_ulong is 64-bits (argh I hate longs). */
|
||||||
|
if ((mz_uint64)(*pSource_len | *pDest_len) > 0xFFFFFFFFU)
|
||||||
|
return MZ_PARAM_ERROR;
|
||||||
|
|
||||||
|
stream.next_in = pSource;
|
||||||
|
stream.avail_in = (mz_uint32)*pSource_len;
|
||||||
|
stream.next_out = pDest;
|
||||||
|
stream.avail_out = (mz_uint32)*pDest_len;
|
||||||
|
|
||||||
|
status = mz_inflateInit(&stream);
|
||||||
|
if (status != MZ_OK)
|
||||||
|
return status;
|
||||||
|
|
||||||
|
status = mz_inflate(&stream, MZ_FINISH);
|
||||||
|
*pSource_len = *pSource_len - stream.avail_in;
|
||||||
|
if (status != MZ_STREAM_END)
|
||||||
|
{
|
||||||
|
mz_inflateEnd(&stream);
|
||||||
|
return ((status == MZ_BUF_ERROR) && (!stream.avail_in)) ? MZ_DATA_ERROR : status;
|
||||||
|
}
|
||||||
|
*pDest_len = stream.total_out;
|
||||||
|
|
||||||
|
return mz_inflateEnd(&stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len)
|
||||||
|
{
|
||||||
|
return mz_uncompress2(pDest, pDest_len, pSource, &source_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /*#ifndef MINIZ_NO_INFLATE_APIS*/
|
||||||
|
|
||||||
|
const char *mz_error(int err)
|
||||||
|
{
|
||||||
|
static struct
|
||||||
|
{
|
||||||
|
int m_err;
|
||||||
|
const char *m_pDesc;
|
||||||
|
} s_error_descs[] = {
|
||||||
|
{ MZ_OK, "" }, { MZ_STREAM_END, "stream end" }, { MZ_NEED_DICT, "need dictionary" }, { MZ_ERRNO, "file error" }, { MZ_STREAM_ERROR, "stream error" }, { MZ_DATA_ERROR, "data error" }, { MZ_MEM_ERROR, "out of memory" }, { MZ_BUF_ERROR, "buf error" }, { MZ_VERSION_ERROR, "version error" }, { MZ_PARAM_ERROR, "parameter error" }
|
||||||
|
};
|
||||||
|
mz_uint i;
|
||||||
|
for (i = 0; i < sizeof(s_error_descs) / sizeof(s_error_descs[0]); ++i)
|
||||||
|
if (s_error_descs[i].m_err == err)
|
||||||
|
return s_error_descs[i].m_pDesc;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /*MINIZ_NO_ZLIB_APIS */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
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/>
|
||||||
|
*/
|
||||||
615
libs/miniz/miniz.h
Normal file
@@ -0,0 +1,615 @@
|
|||||||
|
/* miniz.c 3.1.0 - public domain deflate/inflate, zlib-subset, ZIP reading/writing/appending, PNG writing
|
||||||
|
See "unlicense" statement at the end of this file.
|
||||||
|
Rich Geldreich <richgel99@gmail.com>, last updated Oct. 13, 2013
|
||||||
|
Implements RFC 1950: http://www.ietf.org/rfc/rfc1950.txt and RFC 1951: http://www.ietf.org/rfc/rfc1951.txt
|
||||||
|
|
||||||
|
Most API's defined in miniz.c are optional. For example, to disable the archive related functions just define
|
||||||
|
MINIZ_NO_ARCHIVE_APIS, or to get rid of all stdio usage define MINIZ_NO_STDIO (see the list below for more macros).
|
||||||
|
|
||||||
|
* Low-level Deflate/Inflate implementation notes:
|
||||||
|
|
||||||
|
Compression: Use the "tdefl" API's. The compressor supports raw, static, and dynamic blocks, lazy or
|
||||||
|
greedy parsing, match length filtering, RLE-only, and Huffman-only streams. It performs and compresses
|
||||||
|
approximately as well as zlib.
|
||||||
|
|
||||||
|
Decompression: Use the "tinfl" API's. The entire decompressor is implemented as a single function
|
||||||
|
coroutine: see tinfl_decompress(). It supports decompression into a 32KB (or larger power of 2) wrapping buffer, or into a memory
|
||||||
|
block large enough to hold the entire file.
|
||||||
|
|
||||||
|
The low-level tdefl/tinfl API's do not make any use of dynamic memory allocation.
|
||||||
|
|
||||||
|
* zlib-style API notes:
|
||||||
|
|
||||||
|
miniz.c implements a fairly large subset of zlib. There's enough functionality present for it to be a drop-in
|
||||||
|
zlib replacement in many apps:
|
||||||
|
The z_stream struct, optional memory allocation callbacks
|
||||||
|
deflateInit/deflateInit2/deflate/deflateReset/deflateEnd/deflateBound
|
||||||
|
inflateInit/inflateInit2/inflate/inflateReset/inflateEnd
|
||||||
|
compress, compress2, compressBound, uncompress
|
||||||
|
CRC-32, Adler-32 - Using modern, minimal code size, CPU cache friendly routines.
|
||||||
|
Supports raw deflate streams or standard zlib streams with adler-32 checking.
|
||||||
|
|
||||||
|
Limitations:
|
||||||
|
The callback API's are not implemented yet. No support for gzip headers or zlib static dictionaries.
|
||||||
|
I've tried to closely emulate zlib's various flavors of stream flushing and return status codes, but
|
||||||
|
there are no guarantees that miniz.c pulls this off perfectly.
|
||||||
|
|
||||||
|
* PNG writing: See the tdefl_write_image_to_png_file_in_memory() function, originally written by
|
||||||
|
Alex Evans. Supports 1-4 bytes/pixel images.
|
||||||
|
|
||||||
|
* ZIP archive API notes:
|
||||||
|
|
||||||
|
The ZIP archive API's where designed with simplicity and efficiency in mind, with just enough abstraction to
|
||||||
|
get the job done with minimal fuss. There are simple API's to retrieve file information, read files from
|
||||||
|
existing archives, create new archives, append new files to existing archives, or clone archive data from
|
||||||
|
one archive to another. It supports archives located in memory or the heap, on disk (using stdio.h),
|
||||||
|
or you can specify custom file read/write callbacks.
|
||||||
|
|
||||||
|
- Archive reading: Just call this function to read a single file from a disk archive:
|
||||||
|
|
||||||
|
void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name,
|
||||||
|
size_t *pSize, mz_uint zip_flags);
|
||||||
|
|
||||||
|
For more complex cases, use the "mz_zip_reader" functions. Upon opening an archive, the entire central
|
||||||
|
directory is located and read as-is into memory, and subsequent file access only occurs when reading individual files.
|
||||||
|
|
||||||
|
- Archives file scanning: The simple way is to use this function to scan a loaded archive for a specific file:
|
||||||
|
|
||||||
|
int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags);
|
||||||
|
|
||||||
|
The locate operation can optionally check file comments too, which (as one example) can be used to identify
|
||||||
|
multiple versions of the same file in an archive. This function uses a simple linear search through the central
|
||||||
|
directory, so it's not very fast.
|
||||||
|
|
||||||
|
Alternately, you can iterate through all the files in an archive (using mz_zip_reader_get_num_files()) and
|
||||||
|
retrieve detailed info on each file by calling mz_zip_reader_file_stat().
|
||||||
|
|
||||||
|
- Archive creation: Use the "mz_zip_writer" functions. The ZIP writer immediately writes compressed file data
|
||||||
|
to disk and builds an exact image of the central directory in memory. The central directory image is written
|
||||||
|
all at once at the end of the archive file when the archive is finalized.
|
||||||
|
|
||||||
|
The archive writer can optionally align each file's local header and file data to any power of 2 alignment,
|
||||||
|
which can be useful when the archive will be read from optical media. Also, the writer supports placing
|
||||||
|
arbitrary data blobs at the very beginning of ZIP archives. Archives written using either feature are still
|
||||||
|
readable by any ZIP tool.
|
||||||
|
|
||||||
|
- Archive appending: The simple way to add a single file to an archive is to call this function:
|
||||||
|
|
||||||
|
mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const char *pArchive_name,
|
||||||
|
const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags);
|
||||||
|
|
||||||
|
The archive will be created if it doesn't already exist, otherwise it'll be appended to.
|
||||||
|
Note the appending is done in-place and is not an atomic operation, so if something goes wrong
|
||||||
|
during the operation it's possible the archive could be left without a central directory (although the local
|
||||||
|
file headers and file data will be fine, so the archive will be recoverable).
|
||||||
|
|
||||||
|
For more complex archive modification scenarios:
|
||||||
|
1. The safest way is to use a mz_zip_reader to read the existing archive, cloning only those bits you want to
|
||||||
|
preserve into a new archive using using the mz_zip_writer_add_from_zip_reader() function (which compiles the
|
||||||
|
compressed file data as-is). When you're done, delete the old archive and rename the newly written archive, and
|
||||||
|
you're done. This is safe but requires a bunch of temporary disk space or heap memory.
|
||||||
|
|
||||||
|
2. Or, you can convert an mz_zip_reader in-place to an mz_zip_writer using mz_zip_writer_init_from_reader(),
|
||||||
|
append new files as needed, then finalize the archive which will write an updated central directory to the
|
||||||
|
original archive. (This is basically what mz_zip_add_mem_to_archive_file_in_place() does.) There's a
|
||||||
|
possibility that the archive's central directory could be lost with this method if anything goes wrong, though.
|
||||||
|
|
||||||
|
- ZIP archive support limitations:
|
||||||
|
No spanning support. Extraction functions can only handle unencrypted, stored or deflated files.
|
||||||
|
Requires streams capable of seeking.
|
||||||
|
|
||||||
|
* This is a header file library, like stb_image.c. To get only a header file, either cut and paste the
|
||||||
|
below header, or create miniz.h, #define MINIZ_HEADER_FILE_ONLY, and then include miniz.c from it.
|
||||||
|
|
||||||
|
* Important: For best perf. be sure to customize the below macros for your target platform:
|
||||||
|
#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1
|
||||||
|
#define MINIZ_LITTLE_ENDIAN 1
|
||||||
|
#define MINIZ_HAS_64BIT_REGISTERS 1
|
||||||
|
|
||||||
|
* On platforms using glibc, Be sure to "#define _LARGEFILE64_SOURCE 1" before including miniz.c to ensure miniz
|
||||||
|
uses the 64-bit variants: fopen64(), stat64(), etc. Otherwise you won't be able to process large files
|
||||||
|
(i.e. 32-bit stat() fails for me on files > 0x7FFFFFFF bytes).
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "miniz_export.h"
|
||||||
|
|
||||||
|
#if defined(__STRICT_ANSI__)
|
||||||
|
#define MZ_FORCEINLINE
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#define MZ_FORCEINLINE __forceinline
|
||||||
|
#elif defined(__GNUC__)
|
||||||
|
#define MZ_FORCEINLINE __inline__ __attribute__((__always_inline__))
|
||||||
|
#else
|
||||||
|
#define MZ_FORCEINLINE inline
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Defines to completely disable specific portions of miniz.c:
|
||||||
|
If all macros here are defined the only functionality remaining will be CRC-32 and adler-32. */
|
||||||
|
|
||||||
|
/* Define MINIZ_NO_STDIO to disable all usage and any functions which rely on stdio for file I/O. */
|
||||||
|
/*#define MINIZ_NO_STDIO */
|
||||||
|
|
||||||
|
/* If MINIZ_NO_TIME is specified then the ZIP archive functions will not be able to get the current time, or */
|
||||||
|
/* get/set file times, and the C run-time funcs that get/set times won't be called. */
|
||||||
|
/* The current downside is the times written to your archives will be from 1979. */
|
||||||
|
/*#define MINIZ_NO_TIME */
|
||||||
|
|
||||||
|
/* Define MINIZ_NO_DEFLATE_APIS to disable all compression API's. */
|
||||||
|
/*#define MINIZ_NO_DEFLATE_APIS */
|
||||||
|
|
||||||
|
/* Define MINIZ_NO_INFLATE_APIS to disable all decompression API's. */
|
||||||
|
/*#define MINIZ_NO_INFLATE_APIS */
|
||||||
|
|
||||||
|
/* Define MINIZ_NO_ARCHIVE_APIS to disable all ZIP archive API's. */
|
||||||
|
/*#define MINIZ_NO_ARCHIVE_APIS */
|
||||||
|
|
||||||
|
/* Define MINIZ_NO_ARCHIVE_WRITING_APIS to disable all writing related ZIP archive API's. */
|
||||||
|
/*#define MINIZ_NO_ARCHIVE_WRITING_APIS */
|
||||||
|
|
||||||
|
/* Define MINIZ_NO_ZLIB_APIS to remove all ZLIB-style compression/decompression API's. */
|
||||||
|
/*#define MINIZ_NO_ZLIB_APIS */
|
||||||
|
|
||||||
|
/* Define MINIZ_NO_ZLIB_COMPATIBLE_NAME to disable zlib names, to prevent conflicts against stock zlib. */
|
||||||
|
/*#define MINIZ_NO_ZLIB_COMPATIBLE_NAMES */
|
||||||
|
|
||||||
|
/* Define MINIZ_NO_MALLOC to disable all calls to malloc, free, and realloc.
|
||||||
|
Note if MINIZ_NO_MALLOC is defined then the user must always provide custom user alloc/free/realloc
|
||||||
|
callbacks to the zlib and archive API's, and a few stand-alone helper API's which don't provide custom user
|
||||||
|
functions (such as tdefl_compress_mem_to_heap() and tinfl_decompress_mem_to_heap()) won't work. */
|
||||||
|
/*#define MINIZ_NO_MALLOC */
|
||||||
|
|
||||||
|
#ifdef MINIZ_NO_INFLATE_APIS
|
||||||
|
#define MINIZ_NO_ARCHIVE_APIS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MINIZ_NO_DEFLATE_APIS
|
||||||
|
#define MINIZ_NO_ARCHIVE_WRITING_APIS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__TINYC__) && (defined(__linux) || defined(__linux__))
|
||||||
|
/* TODO: Work around "error: include file 'sys\utime.h' when compiling with tcc on Linux */
|
||||||
|
#define MINIZ_NO_TIME
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#if !defined(MINIZ_NO_TIME) && !defined(MINIZ_NO_ARCHIVE_APIS)
|
||||||
|
#include <time.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || defined(__i386) || defined(__i486__) || defined(__i486) || defined(i386) || defined(__ia64__) || defined(__x86_64__)
|
||||||
|
/* MINIZ_X86_OR_X64_CPU is only used to help set the below macros. */
|
||||||
|
#define MINIZ_X86_OR_X64_CPU 1
|
||||||
|
#else
|
||||||
|
#define MINIZ_X86_OR_X64_CPU 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Set MINIZ_LITTLE_ENDIAN only if not set */
|
||||||
|
#if !defined(MINIZ_LITTLE_ENDIAN)
|
||||||
|
#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__)
|
||||||
|
|
||||||
|
#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
|
||||||
|
/* Set MINIZ_LITTLE_ENDIAN to 1 if the processor is little endian. */
|
||||||
|
#define MINIZ_LITTLE_ENDIAN 1
|
||||||
|
#else
|
||||||
|
#define MINIZ_LITTLE_ENDIAN 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#if MINIZ_X86_OR_X64_CPU
|
||||||
|
#define MINIZ_LITTLE_ENDIAN 1
|
||||||
|
#else
|
||||||
|
#define MINIZ_LITTLE_ENDIAN 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Using unaligned loads and stores causes errors when using UBSan */
|
||||||
|
#if defined(__has_feature)
|
||||||
|
#if __has_feature(undefined_behavior_sanitizer)
|
||||||
|
#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Set MINIZ_USE_UNALIGNED_LOADS_AND_STORES only if not set */
|
||||||
|
#if !defined(MINIZ_USE_UNALIGNED_LOADS_AND_STORES)
|
||||||
|
#if MINIZ_X86_OR_X64_CPU
|
||||||
|
/* Set MINIZ_USE_UNALIGNED_LOADS_AND_STORES to 1 on CPU's that permit efficient integer loads and stores from unaligned addresses. */
|
||||||
|
#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 0
|
||||||
|
#define MINIZ_UNALIGNED_USE_MEMCPY
|
||||||
|
#else
|
||||||
|
#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_M_X64) || defined(_WIN64) || defined(__MINGW64__) || defined(_LP64) || defined(__LP64__) || defined(__ia64__) || defined(__x86_64__)
|
||||||
|
/* Set MINIZ_HAS_64BIT_REGISTERS to 1 if operations on 64-bit integers are reasonably fast (and don't involve compiler generated calls to helper functions). */
|
||||||
|
#define MINIZ_HAS_64BIT_REGISTERS 1
|
||||||
|
#else
|
||||||
|
#define MINIZ_HAS_64BIT_REGISTERS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ------------------- zlib-style API Definitions. */
|
||||||
|
|
||||||
|
/* For more compatibility with zlib, miniz.c uses unsigned long for some parameters/struct members. Beware: mz_ulong can be either 32 or 64-bits! */
|
||||||
|
typedef unsigned long mz_ulong;
|
||||||
|
|
||||||
|
/* mz_free() internally uses the MZ_FREE() macro (which by default calls free() unless you've modified the MZ_MALLOC macro) to release a block allocated from the heap. */
|
||||||
|
MINIZ_EXPORT void mz_free(void *p);
|
||||||
|
|
||||||
|
#define MZ_ADLER32_INIT (1)
|
||||||
|
/* mz_adler32() returns the initial adler-32 value to use when called with ptr==NULL. */
|
||||||
|
MINIZ_EXPORT mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len);
|
||||||
|
|
||||||
|
#define MZ_CRC32_INIT (0)
|
||||||
|
/* mz_crc32() returns the initial CRC-32 value to use when called with ptr==NULL. */
|
||||||
|
MINIZ_EXPORT mz_ulong mz_crc32(mz_ulong crc, const unsigned char *ptr, size_t buf_len);
|
||||||
|
|
||||||
|
/* Compression strategies. */
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
MZ_DEFAULT_STRATEGY = 0,
|
||||||
|
MZ_FILTERED = 1,
|
||||||
|
MZ_HUFFMAN_ONLY = 2,
|
||||||
|
MZ_RLE = 3,
|
||||||
|
MZ_FIXED = 4
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Method */
|
||||||
|
#define MZ_DEFLATED 8
|
||||||
|
|
||||||
|
/* Heap allocation callbacks.
|
||||||
|
Note that mz_alloc_func parameter types purposely differ from zlib's: items/size is size_t, not unsigned long. */
|
||||||
|
typedef void *(*mz_alloc_func)(void *opaque, size_t items, size_t size);
|
||||||
|
typedef void (*mz_free_func)(void *opaque, void *address);
|
||||||
|
typedef void *(*mz_realloc_func)(void *opaque, void *address, size_t items, size_t size);
|
||||||
|
|
||||||
|
/* Compression levels: 0-9 are the standard zlib-style levels, 10 is best possible compression (not zlib compatible, and may be very slow), MZ_DEFAULT_COMPRESSION=MZ_DEFAULT_LEVEL. */
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
MZ_NO_COMPRESSION = 0,
|
||||||
|
MZ_BEST_SPEED = 1,
|
||||||
|
MZ_BEST_COMPRESSION = 9,
|
||||||
|
MZ_UBER_COMPRESSION = 10,
|
||||||
|
MZ_DEFAULT_LEVEL = 6,
|
||||||
|
MZ_DEFAULT_COMPRESSION = -1
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MZ_VERSION "11.3.1"
|
||||||
|
#define MZ_VERNUM 0xB301
|
||||||
|
#define MZ_VER_MAJOR 11
|
||||||
|
#define MZ_VER_MINOR 3
|
||||||
|
#define MZ_VER_REVISION 1
|
||||||
|
#define MZ_VER_SUBREVISION 0
|
||||||
|
|
||||||
|
#ifndef MINIZ_NO_ZLIB_APIS
|
||||||
|
|
||||||
|
/* Flush values. For typical usage you only need MZ_NO_FLUSH and MZ_FINISH. The other values are for advanced use (refer to the zlib docs). */
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
MZ_NO_FLUSH = 0,
|
||||||
|
MZ_PARTIAL_FLUSH = 1,
|
||||||
|
MZ_SYNC_FLUSH = 2,
|
||||||
|
MZ_FULL_FLUSH = 3,
|
||||||
|
MZ_FINISH = 4,
|
||||||
|
MZ_BLOCK = 5
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Return status codes. MZ_PARAM_ERROR is non-standard. */
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
MZ_OK = 0,
|
||||||
|
MZ_STREAM_END = 1,
|
||||||
|
MZ_NEED_DICT = 2,
|
||||||
|
MZ_ERRNO = -1,
|
||||||
|
MZ_STREAM_ERROR = -2,
|
||||||
|
MZ_DATA_ERROR = -3,
|
||||||
|
MZ_MEM_ERROR = -4,
|
||||||
|
MZ_BUF_ERROR = -5,
|
||||||
|
MZ_VERSION_ERROR = -6,
|
||||||
|
MZ_PARAM_ERROR = -10000
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Window bits */
|
||||||
|
#define MZ_DEFAULT_WINDOW_BITS 15
|
||||||
|
|
||||||
|
struct mz_internal_state;
|
||||||
|
|
||||||
|
/* Compression/decompression stream struct. */
|
||||||
|
typedef struct mz_stream_s
|
||||||
|
{
|
||||||
|
const unsigned char *next_in; /* pointer to next byte to read */
|
||||||
|
unsigned int avail_in; /* number of bytes available at next_in */
|
||||||
|
mz_ulong total_in; /* total number of bytes consumed so far */
|
||||||
|
|
||||||
|
unsigned char *next_out; /* pointer to next byte to write */
|
||||||
|
unsigned int avail_out; /* number of bytes that can be written to next_out */
|
||||||
|
mz_ulong total_out; /* total number of bytes produced so far */
|
||||||
|
|
||||||
|
char *msg; /* error msg (unused) */
|
||||||
|
struct mz_internal_state *state; /* internal state, allocated by zalloc/zfree */
|
||||||
|
|
||||||
|
mz_alloc_func zalloc; /* optional heap allocation function (defaults to malloc) */
|
||||||
|
mz_free_func zfree; /* optional heap free function (defaults to free) */
|
||||||
|
void *opaque; /* heap alloc function user pointer */
|
||||||
|
|
||||||
|
int data_type; /* data_type (unused) */
|
||||||
|
mz_ulong adler; /* adler32 of the source or uncompressed data */
|
||||||
|
mz_ulong reserved; /* not used */
|
||||||
|
} mz_stream;
|
||||||
|
|
||||||
|
typedef mz_stream *mz_streamp;
|
||||||
|
|
||||||
|
/* Returns the version string of miniz.c. */
|
||||||
|
MINIZ_EXPORT const char *mz_version(void);
|
||||||
|
|
||||||
|
#ifndef MINIZ_NO_DEFLATE_APIS
|
||||||
|
|
||||||
|
/* mz_deflateInit() initializes a compressor with default options: */
|
||||||
|
/* Parameters: */
|
||||||
|
/* pStream must point to an initialized mz_stream struct. */
|
||||||
|
/* level must be between [MZ_NO_COMPRESSION, MZ_BEST_COMPRESSION]. */
|
||||||
|
/* level 1 enables a specially optimized compression function that's been optimized purely for performance, not ratio. */
|
||||||
|
/* (This special func. is currently only enabled when MINIZ_USE_UNALIGNED_LOADS_AND_STORES and MINIZ_LITTLE_ENDIAN are defined.) */
|
||||||
|
/* Return values: */
|
||||||
|
/* MZ_OK on success. */
|
||||||
|
/* MZ_STREAM_ERROR if the stream is bogus. */
|
||||||
|
/* MZ_PARAM_ERROR if the input parameters are bogus. */
|
||||||
|
/* MZ_MEM_ERROR on out of memory. */
|
||||||
|
MINIZ_EXPORT int mz_deflateInit(mz_streamp pStream, int level);
|
||||||
|
|
||||||
|
/* mz_deflateInit2() is like mz_deflate(), except with more control: */
|
||||||
|
/* Additional parameters: */
|
||||||
|
/* method must be MZ_DEFLATED */
|
||||||
|
/* window_bits must be MZ_DEFAULT_WINDOW_BITS (to wrap the deflate stream with zlib header/adler-32 footer) or -MZ_DEFAULT_WINDOW_BITS (raw deflate/no header or footer) */
|
||||||
|
/* mem_level must be between [1, 9] (it's checked but ignored by miniz.c) */
|
||||||
|
MINIZ_EXPORT int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy);
|
||||||
|
|
||||||
|
/* Quickly resets a compressor without having to reallocate anything. Same as calling mz_deflateEnd() followed by mz_deflateInit()/mz_deflateInit2(). */
|
||||||
|
MINIZ_EXPORT int mz_deflateReset(mz_streamp pStream);
|
||||||
|
|
||||||
|
/* mz_deflate() compresses the input to output, consuming as much of the input and producing as much output as possible. */
|
||||||
|
/* Parameters: */
|
||||||
|
/* pStream is the stream to read from and write to. You must initialize/update the next_in, avail_in, next_out, and avail_out members. */
|
||||||
|
/* flush may be MZ_NO_FLUSH, MZ_PARTIAL_FLUSH/MZ_SYNC_FLUSH, MZ_FULL_FLUSH, or MZ_FINISH. */
|
||||||
|
/* Return values: */
|
||||||
|
/* MZ_OK on success (when flushing, or if more input is needed but not available, and/or there's more output to be written but the output buffer is full). */
|
||||||
|
/* MZ_STREAM_END if all input has been consumed and all output bytes have been written. Don't call mz_deflate() on the stream anymore. */
|
||||||
|
/* MZ_STREAM_ERROR if the stream is bogus. */
|
||||||
|
/* MZ_PARAM_ERROR if one of the parameters is invalid. */
|
||||||
|
/* MZ_BUF_ERROR if no forward progress is possible because the input and/or output buffers are empty. (Fill up the input buffer or free up some output space and try again.) */
|
||||||
|
MINIZ_EXPORT int mz_deflate(mz_streamp pStream, int flush);
|
||||||
|
|
||||||
|
/* mz_deflateEnd() deinitializes a compressor: */
|
||||||
|
/* Return values: */
|
||||||
|
/* MZ_OK on success. */
|
||||||
|
/* MZ_STREAM_ERROR if the stream is bogus. */
|
||||||
|
MINIZ_EXPORT int mz_deflateEnd(mz_streamp pStream);
|
||||||
|
|
||||||
|
/* mz_deflateBound() returns a (very) conservative upper bound on the amount of data that could be generated by deflate(), assuming flush is set to only MZ_NO_FLUSH or MZ_FINISH. */
|
||||||
|
MINIZ_EXPORT mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len);
|
||||||
|
|
||||||
|
/* Single-call compression functions mz_compress() and mz_compress2(): */
|
||||||
|
/* Returns MZ_OK on success, or one of the error codes from mz_deflate() on failure. */
|
||||||
|
MINIZ_EXPORT int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len);
|
||||||
|
MINIZ_EXPORT int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level);
|
||||||
|
|
||||||
|
/* mz_compressBound() returns a (very) conservative upper bound on the amount of data that could be generated by calling mz_compress(). */
|
||||||
|
MINIZ_EXPORT mz_ulong mz_compressBound(mz_ulong source_len);
|
||||||
|
|
||||||
|
#endif /*#ifndef MINIZ_NO_DEFLATE_APIS*/
|
||||||
|
|
||||||
|
#ifndef MINIZ_NO_INFLATE_APIS
|
||||||
|
|
||||||
|
/* Initializes a decompressor. */
|
||||||
|
MINIZ_EXPORT int mz_inflateInit(mz_streamp pStream);
|
||||||
|
|
||||||
|
/* mz_inflateInit2() is like mz_inflateInit() with an additional option that controls the window size and whether or not the stream has been wrapped with a zlib header/footer: */
|
||||||
|
/* window_bits must be MZ_DEFAULT_WINDOW_BITS (to parse zlib header/footer) or -MZ_DEFAULT_WINDOW_BITS (raw deflate). */
|
||||||
|
MINIZ_EXPORT int mz_inflateInit2(mz_streamp pStream, int window_bits);
|
||||||
|
|
||||||
|
/* Quickly resets a compressor without having to reallocate anything. Same as calling mz_inflateEnd() followed by mz_inflateInit()/mz_inflateInit2(). */
|
||||||
|
MINIZ_EXPORT int mz_inflateReset(mz_streamp pStream);
|
||||||
|
|
||||||
|
/* Decompresses the input stream to the output, consuming only as much of the input as needed, and writing as much to the output as possible. */
|
||||||
|
/* Parameters: */
|
||||||
|
/* pStream is the stream to read from and write to. You must initialize/update the next_in, avail_in, next_out, and avail_out members. */
|
||||||
|
/* flush may be MZ_NO_FLUSH, MZ_SYNC_FLUSH, or MZ_FINISH. */
|
||||||
|
/* On the first call, if flush is MZ_FINISH it's assumed the input and output buffers are both sized large enough to decompress the entire stream in a single call (this is slightly faster). */
|
||||||
|
/* MZ_FINISH implies that there are no more source bytes available beside what's already in the input buffer, and that the output buffer is large enough to hold the rest of the decompressed data. */
|
||||||
|
/* Return values: */
|
||||||
|
/* MZ_OK on success. Either more input is needed but not available, and/or there's more output to be written but the output buffer is full. */
|
||||||
|
/* MZ_STREAM_END if all needed input has been consumed and all output bytes have been written. For zlib streams, the adler-32 of the decompressed data has also been verified. */
|
||||||
|
/* MZ_STREAM_ERROR if the stream is bogus. */
|
||||||
|
/* MZ_DATA_ERROR if the deflate stream is invalid. */
|
||||||
|
/* MZ_PARAM_ERROR if one of the parameters is invalid. */
|
||||||
|
/* MZ_BUF_ERROR if no forward progress is possible because the input buffer is empty but the inflater needs more input to continue, or if the output buffer is not large enough. Call mz_inflate() again */
|
||||||
|
/* with more input data, or with more room in the output buffer (except when using single call decompression, described above). */
|
||||||
|
MINIZ_EXPORT int mz_inflate(mz_streamp pStream, int flush);
|
||||||
|
|
||||||
|
/* Deinitializes a decompressor. */
|
||||||
|
MINIZ_EXPORT int mz_inflateEnd(mz_streamp pStream);
|
||||||
|
|
||||||
|
/* Single-call decompression. */
|
||||||
|
/* Returns MZ_OK on success, or one of the error codes from mz_inflate() on failure. */
|
||||||
|
MINIZ_EXPORT int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len);
|
||||||
|
MINIZ_EXPORT int mz_uncompress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong *pSource_len);
|
||||||
|
#endif /*#ifndef MINIZ_NO_INFLATE_APIS*/
|
||||||
|
|
||||||
|
/* Returns a string description of the specified error code, or NULL if the error code is invalid. */
|
||||||
|
MINIZ_EXPORT const char *mz_error(int err);
|
||||||
|
|
||||||
|
/* Redefine zlib-compatible names to miniz equivalents, so miniz.c can be used as a drop-in replacement for the subset of zlib that miniz.c supports. */
|
||||||
|
/* Define MINIZ_NO_ZLIB_COMPATIBLE_NAMES to disable zlib-compatibility if you use zlib in the same project. */
|
||||||
|
#ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES
|
||||||
|
typedef unsigned char Byte;
|
||||||
|
typedef unsigned int uInt;
|
||||||
|
typedef mz_ulong uLong;
|
||||||
|
typedef Byte Bytef;
|
||||||
|
typedef uInt uIntf;
|
||||||
|
typedef char charf;
|
||||||
|
typedef int intf;
|
||||||
|
typedef void *voidpf;
|
||||||
|
typedef uLong uLongf;
|
||||||
|
typedef void *voidp;
|
||||||
|
typedef void *const voidpc;
|
||||||
|
#define Z_NULL 0
|
||||||
|
#define Z_NO_FLUSH MZ_NO_FLUSH
|
||||||
|
#define Z_PARTIAL_FLUSH MZ_PARTIAL_FLUSH
|
||||||
|
#define Z_SYNC_FLUSH MZ_SYNC_FLUSH
|
||||||
|
#define Z_FULL_FLUSH MZ_FULL_FLUSH
|
||||||
|
#define Z_FINISH MZ_FINISH
|
||||||
|
#define Z_BLOCK MZ_BLOCK
|
||||||
|
#define Z_OK MZ_OK
|
||||||
|
#define Z_STREAM_END MZ_STREAM_END
|
||||||
|
#define Z_NEED_DICT MZ_NEED_DICT
|
||||||
|
#define Z_ERRNO MZ_ERRNO
|
||||||
|
#define Z_STREAM_ERROR MZ_STREAM_ERROR
|
||||||
|
#define Z_DATA_ERROR MZ_DATA_ERROR
|
||||||
|
#define Z_MEM_ERROR MZ_MEM_ERROR
|
||||||
|
#define Z_BUF_ERROR MZ_BUF_ERROR
|
||||||
|
#define Z_VERSION_ERROR MZ_VERSION_ERROR
|
||||||
|
#define Z_PARAM_ERROR MZ_PARAM_ERROR
|
||||||
|
#define Z_NO_COMPRESSION MZ_NO_COMPRESSION
|
||||||
|
#define Z_BEST_SPEED MZ_BEST_SPEED
|
||||||
|
#define Z_BEST_COMPRESSION MZ_BEST_COMPRESSION
|
||||||
|
#define Z_DEFAULT_COMPRESSION MZ_DEFAULT_COMPRESSION
|
||||||
|
#define Z_DEFAULT_STRATEGY MZ_DEFAULT_STRATEGY
|
||||||
|
#define Z_FILTERED MZ_FILTERED
|
||||||
|
#define Z_HUFFMAN_ONLY MZ_HUFFMAN_ONLY
|
||||||
|
#define Z_RLE MZ_RLE
|
||||||
|
#define Z_FIXED MZ_FIXED
|
||||||
|
#define Z_DEFLATED MZ_DEFLATED
|
||||||
|
#define Z_DEFAULT_WINDOW_BITS MZ_DEFAULT_WINDOW_BITS
|
||||||
|
/* See mz_alloc_func */
|
||||||
|
typedef void *(*alloc_func)(void *opaque, size_t items, size_t size);
|
||||||
|
/* See mz_free_func */
|
||||||
|
typedef void (*free_func)(void *opaque, void *address);
|
||||||
|
|
||||||
|
#define internal_state mz_internal_state
|
||||||
|
#define z_stream mz_stream
|
||||||
|
|
||||||
|
#ifndef MINIZ_NO_DEFLATE_APIS
|
||||||
|
/* Compatiblity with zlib API. See called functions for documentation */
|
||||||
|
static MZ_FORCEINLINE int deflateInit(mz_streamp pStream, int level)
|
||||||
|
{
|
||||||
|
return mz_deflateInit(pStream, level);
|
||||||
|
}
|
||||||
|
static MZ_FORCEINLINE int deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy)
|
||||||
|
{
|
||||||
|
return mz_deflateInit2(pStream, level, method, window_bits, mem_level, strategy);
|
||||||
|
}
|
||||||
|
static MZ_FORCEINLINE int deflateReset(mz_streamp pStream)
|
||||||
|
{
|
||||||
|
return mz_deflateReset(pStream);
|
||||||
|
}
|
||||||
|
static MZ_FORCEINLINE int deflate(mz_streamp pStream, int flush)
|
||||||
|
{
|
||||||
|
return mz_deflate(pStream, flush);
|
||||||
|
}
|
||||||
|
static MZ_FORCEINLINE int deflateEnd(mz_streamp pStream)
|
||||||
|
{
|
||||||
|
return mz_deflateEnd(pStream);
|
||||||
|
}
|
||||||
|
static MZ_FORCEINLINE mz_ulong deflateBound(mz_streamp pStream, mz_ulong source_len)
|
||||||
|
{
|
||||||
|
return mz_deflateBound(pStream, source_len);
|
||||||
|
}
|
||||||
|
static MZ_FORCEINLINE int compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len)
|
||||||
|
{
|
||||||
|
return mz_compress(pDest, pDest_len, pSource, source_len);
|
||||||
|
}
|
||||||
|
static MZ_FORCEINLINE int compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level)
|
||||||
|
{
|
||||||
|
return mz_compress2(pDest, pDest_len, pSource, source_len, level);
|
||||||
|
}
|
||||||
|
static MZ_FORCEINLINE mz_ulong compressBound(mz_ulong source_len)
|
||||||
|
{
|
||||||
|
return mz_compressBound(source_len);
|
||||||
|
}
|
||||||
|
#endif /*#ifndef MINIZ_NO_DEFLATE_APIS*/
|
||||||
|
|
||||||
|
#ifndef MINIZ_NO_INFLATE_APIS
|
||||||
|
/* Compatiblity with zlib API. See called functions for documentation */
|
||||||
|
static MZ_FORCEINLINE int inflateInit(mz_streamp pStream)
|
||||||
|
{
|
||||||
|
return mz_inflateInit(pStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
static MZ_FORCEINLINE int inflateInit2(mz_streamp pStream, int window_bits)
|
||||||
|
{
|
||||||
|
return mz_inflateInit2(pStream, window_bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
static MZ_FORCEINLINE int inflateReset(mz_streamp pStream)
|
||||||
|
{
|
||||||
|
return mz_inflateReset(pStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
static MZ_FORCEINLINE int inflate(mz_streamp pStream, int flush)
|
||||||
|
{
|
||||||
|
return mz_inflate(pStream, flush);
|
||||||
|
}
|
||||||
|
|
||||||
|
static MZ_FORCEINLINE int inflateEnd(mz_streamp pStream)
|
||||||
|
{
|
||||||
|
return mz_inflateEnd(pStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
static MZ_FORCEINLINE int uncompress(unsigned char* pDest, mz_ulong* pDest_len, const unsigned char* pSource, mz_ulong source_len)
|
||||||
|
{
|
||||||
|
return mz_uncompress(pDest, pDest_len, pSource, source_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static MZ_FORCEINLINE int uncompress2(unsigned char* pDest, mz_ulong* pDest_len, const unsigned char* pSource, mz_ulong* pSource_len)
|
||||||
|
{
|
||||||
|
return mz_uncompress2(pDest, pDest_len, pSource, pSource_len);
|
||||||
|
}
|
||||||
|
#endif /*#ifndef MINIZ_NO_INFLATE_APIS*/
|
||||||
|
|
||||||
|
static MZ_FORCEINLINE mz_ulong crc32(mz_ulong crc, const unsigned char *ptr, size_t buf_len)
|
||||||
|
{
|
||||||
|
return mz_crc32(crc, ptr, buf_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static MZ_FORCEINLINE mz_ulong adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len)
|
||||||
|
{
|
||||||
|
return mz_adler32(adler, ptr, buf_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define MAX_WBITS 15
|
||||||
|
#define MAX_MEM_LEVEL 9
|
||||||
|
|
||||||
|
static MZ_FORCEINLINE const char* zError(int err)
|
||||||
|
{
|
||||||
|
return mz_error(err);
|
||||||
|
}
|
||||||
|
#define ZLIB_VERSION MZ_VERSION
|
||||||
|
#define ZLIB_VERNUM MZ_VERNUM
|
||||||
|
#define ZLIB_VER_MAJOR MZ_VER_MAJOR
|
||||||
|
#define ZLIB_VER_MINOR MZ_VER_MINOR
|
||||||
|
#define ZLIB_VER_REVISION MZ_VER_REVISION
|
||||||
|
#define ZLIB_VER_SUBREVISION MZ_VER_SUBREVISION
|
||||||
|
|
||||||
|
#define zlibVersion mz_version
|
||||||
|
#define zlib_version mz_version()
|
||||||
|
#endif /* #ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES */
|
||||||
|
|
||||||
|
#endif /* MINIZ_NO_ZLIB_APIS */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "miniz_common.h"
|
||||||
|
#include "miniz_tdef.h"
|
||||||
|
#include "miniz_tinfl.h"
|
||||||
|
#include "miniz_zip.h"
|
||||||
89
libs/miniz/miniz_common.h
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "miniz_export.h"
|
||||||
|
|
||||||
|
/* ------------------- Types and macros */
|
||||||
|
typedef unsigned char mz_uint8;
|
||||||
|
typedef int16_t mz_int16;
|
||||||
|
typedef uint16_t mz_uint16;
|
||||||
|
typedef uint32_t mz_uint32;
|
||||||
|
typedef uint32_t mz_uint;
|
||||||
|
typedef int64_t mz_int64;
|
||||||
|
typedef uint64_t mz_uint64;
|
||||||
|
typedef int mz_bool;
|
||||||
|
|
||||||
|
#define MZ_FALSE (0)
|
||||||
|
#define MZ_TRUE (1)
|
||||||
|
|
||||||
|
/* Works around MSVC's spammy "warning C4127: conditional expression is constant" message. */
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#define MZ_MACRO_END while (0, 0)
|
||||||
|
#else
|
||||||
|
#define MZ_MACRO_END while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MINIZ_NO_STDIO
|
||||||
|
#define MZ_FILE void *
|
||||||
|
#else
|
||||||
|
#include <stdio.h>
|
||||||
|
#define MZ_FILE FILE
|
||||||
|
#endif /* #ifdef MINIZ_NO_STDIO */
|
||||||
|
|
||||||
|
#ifdef MINIZ_NO_TIME
|
||||||
|
typedef struct mz_dummy_time_t_tag
|
||||||
|
{
|
||||||
|
mz_uint32 m_dummy1;
|
||||||
|
mz_uint32 m_dummy2;
|
||||||
|
} mz_dummy_time_t;
|
||||||
|
#define MZ_TIME_T mz_dummy_time_t
|
||||||
|
#else
|
||||||
|
#define MZ_TIME_T time_t
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MZ_ASSERT(x) assert(x)
|
||||||
|
|
||||||
|
#ifdef MINIZ_NO_MALLOC
|
||||||
|
#define MZ_MALLOC(x) NULL
|
||||||
|
#define MZ_FREE(x) (void)x, ((void)0)
|
||||||
|
#define MZ_REALLOC(p, x) NULL
|
||||||
|
#else
|
||||||
|
#define MZ_MALLOC(x) malloc(x)
|
||||||
|
#define MZ_FREE(x) free(x)
|
||||||
|
#define MZ_REALLOC(p, x) realloc(p, x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MZ_MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||||
|
#define MZ_MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||||
|
#define MZ_CLEAR_OBJ(obj) memset(&(obj), 0, sizeof(obj))
|
||||||
|
#define MZ_CLEAR_ARR(obj) memset((obj), 0, sizeof(obj))
|
||||||
|
#define MZ_CLEAR_PTR(obj) memset((obj), 0, sizeof(*obj))
|
||||||
|
|
||||||
|
#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
|
||||||
|
#define MZ_READ_LE16(p) *((const mz_uint16 *)(p))
|
||||||
|
#define MZ_READ_LE32(p) *((const mz_uint32 *)(p))
|
||||||
|
#else
|
||||||
|
#define MZ_READ_LE16(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U))
|
||||||
|
#define MZ_READ_LE32(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U) | ((mz_uint32)(((const mz_uint8 *)(p))[2]) << 16U) | ((mz_uint32)(((const mz_uint8 *)(p))[3]) << 24U))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MZ_READ_LE64(p) (((mz_uint64)MZ_READ_LE32(p)) | (((mz_uint64)MZ_READ_LE32((const mz_uint8 *)(p) + sizeof(mz_uint32))) << 32U))
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern MINIZ_EXPORT void *miniz_def_alloc_func(void *opaque, size_t items, size_t size);
|
||||||
|
extern MINIZ_EXPORT void miniz_def_free_func(void *opaque, void *address);
|
||||||
|
extern MINIZ_EXPORT void *miniz_def_realloc_func(void *opaque, void *address, size_t items, size_t size);
|
||||||
|
|
||||||
|
#define MZ_UINT16_MAX (0xFFFFU)
|
||||||
|
#define MZ_UINT32_MAX (0xFFFFFFFFU)
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
9
libs/miniz/miniz_export.h
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#pragma once
|
||||||
|
// Stub for miniz_export.h — normally generated by CMake.
|
||||||
|
// We build miniz as a static source file, so no export macros are needed.
|
||||||
|
#ifndef MINIZ_EXPORT
|
||||||
|
#define MINIZ_EXPORT
|
||||||
|
#endif
|
||||||
|
#ifndef MINIZ_NO_EXPORT
|
||||||
|
#define MINIZ_NO_EXPORT
|
||||||
|
#endif
|
||||||
1597
libs/miniz/miniz_tdef.c
Normal file
199
libs/miniz/miniz_tdef.h
Normal file
@@ -0,0 +1,199 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "miniz_common.h"
|
||||||
|
|
||||||
|
#ifndef MINIZ_NO_DEFLATE_APIS
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
/* ------------------- Low-level Compression API Definitions */
|
||||||
|
|
||||||
|
/* Set TDEFL_LESS_MEMORY to 1 to use less memory (compression will be slightly slower, and raw/dynamic blocks will be output more frequently). */
|
||||||
|
#ifndef TDEFL_LESS_MEMORY
|
||||||
|
#define TDEFL_LESS_MEMORY 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* tdefl_init() compression flags logically OR'd together (low 12 bits contain the max. number of probes per dictionary search): */
|
||||||
|
/* TDEFL_DEFAULT_MAX_PROBES: The compressor defaults to 128 dictionary probes per dictionary search. 0=Huffman only, 1=Huffman+LZ (fastest/crap compression), 4095=Huffman+LZ (slowest/best compression). */
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
TDEFL_HUFFMAN_ONLY = 0,
|
||||||
|
TDEFL_DEFAULT_MAX_PROBES = 128,
|
||||||
|
TDEFL_MAX_PROBES_MASK = 0xFFF
|
||||||
|
};
|
||||||
|
|
||||||
|
/* TDEFL_WRITE_ZLIB_HEADER: If set, the compressor outputs a zlib header before the deflate data, and the Adler-32 of the source data at the end. Otherwise, you'll get raw deflate data. */
|
||||||
|
/* TDEFL_COMPUTE_ADLER32: Always compute the adler-32 of the input data (even when not writing zlib headers). */
|
||||||
|
/* TDEFL_GREEDY_PARSING_FLAG: Set to use faster greedy parsing, instead of more efficient lazy parsing. */
|
||||||
|
/* TDEFL_NONDETERMINISTIC_PARSING_FLAG: Enable to decrease the compressor's initialization time to the minimum, but the output may vary from run to run given the same input (depending on the contents of memory). */
|
||||||
|
/* TDEFL_RLE_MATCHES: Only look for RLE matches (matches with a distance of 1) */
|
||||||
|
/* TDEFL_FILTER_MATCHES: Discards matches <= 5 chars if enabled. */
|
||||||
|
/* TDEFL_FORCE_ALL_STATIC_BLOCKS: Disable usage of optimized Huffman tables. */
|
||||||
|
/* TDEFL_FORCE_ALL_RAW_BLOCKS: Only use raw (uncompressed) deflate blocks. */
|
||||||
|
/* The low 12 bits are reserved to control the max # of hash probes per dictionary lookup (see TDEFL_MAX_PROBES_MASK). */
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
TDEFL_WRITE_ZLIB_HEADER = 0x01000,
|
||||||
|
TDEFL_COMPUTE_ADLER32 = 0x02000,
|
||||||
|
TDEFL_GREEDY_PARSING_FLAG = 0x04000,
|
||||||
|
TDEFL_NONDETERMINISTIC_PARSING_FLAG = 0x08000,
|
||||||
|
TDEFL_RLE_MATCHES = 0x10000,
|
||||||
|
TDEFL_FILTER_MATCHES = 0x20000,
|
||||||
|
TDEFL_FORCE_ALL_STATIC_BLOCKS = 0x40000,
|
||||||
|
TDEFL_FORCE_ALL_RAW_BLOCKS = 0x80000
|
||||||
|
};
|
||||||
|
|
||||||
|
/* High level compression functions: */
|
||||||
|
/* tdefl_compress_mem_to_heap() compresses a block in memory to a heap block allocated via malloc(). */
|
||||||
|
/* On entry: */
|
||||||
|
/* pSrc_buf, src_buf_len: Pointer and size of source block to compress. */
|
||||||
|
/* flags: The max match finder probes (default is 128) logically OR'd against the above flags. Higher probes are slower but improve compression. */
|
||||||
|
/* On return: */
|
||||||
|
/* Function returns a pointer to the compressed data, or NULL on failure. */
|
||||||
|
/* *pOut_len will be set to the compressed data's size, which could be larger than src_buf_len on uncompressible data. */
|
||||||
|
/* The caller must free() the returned block when it's no longer needed. */
|
||||||
|
MINIZ_EXPORT void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags);
|
||||||
|
|
||||||
|
/* tdefl_compress_mem_to_mem() compresses a block in memory to another block in memory. */
|
||||||
|
/* Returns 0 on failure. */
|
||||||
|
MINIZ_EXPORT size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags);
|
||||||
|
|
||||||
|
/* Compresses an image to a compressed PNG file in memory. */
|
||||||
|
/* On entry: */
|
||||||
|
/* pImage, w, h, and num_chans describe the image to compress. num_chans may be 1, 2, 3, or 4. */
|
||||||
|
/* The image pitch in bytes per scanline will be w*num_chans. The leftmost pixel on the top scanline is stored first in memory. */
|
||||||
|
/* level may range from [0,10], use MZ_NO_COMPRESSION, MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc. or a decent default is MZ_DEFAULT_LEVEL */
|
||||||
|
/* If flip is true, the image will be flipped on the Y axis (useful for OpenGL apps). */
|
||||||
|
/* On return: */
|
||||||
|
/* Function returns a pointer to the compressed data, or NULL on failure. */
|
||||||
|
/* *pLen_out will be set to the size of the PNG image file. */
|
||||||
|
/* The caller must mz_free() the returned heap block (which will typically be larger than *pLen_out) when it's no longer needed. */
|
||||||
|
MINIZ_EXPORT void *tdefl_write_image_to_png_file_in_memory_ex(const void *pImage, int w, int h, int num_chans, size_t *pLen_out, mz_uint level, mz_bool flip);
|
||||||
|
MINIZ_EXPORT void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out);
|
||||||
|
|
||||||
|
/* Output stream interface. The compressor uses this interface to write compressed data. It'll typically be called TDEFL_OUT_BUF_SIZE at a time. */
|
||||||
|
typedef mz_bool (*tdefl_put_buf_func_ptr)(const void *pBuf, int len, void *pUser);
|
||||||
|
|
||||||
|
/* tdefl_compress_mem_to_output() compresses a block to an output stream. The above helpers use this function internally. */
|
||||||
|
MINIZ_EXPORT mz_bool tdefl_compress_mem_to_output(const void *pBuf, size_t buf_len, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags);
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
TDEFL_MAX_HUFF_TABLES = 3,
|
||||||
|
TDEFL_MAX_HUFF_SYMBOLS_0 = 288,
|
||||||
|
TDEFL_MAX_HUFF_SYMBOLS_1 = 32,
|
||||||
|
TDEFL_MAX_HUFF_SYMBOLS_2 = 19,
|
||||||
|
TDEFL_LZ_DICT_SIZE = 32768,
|
||||||
|
TDEFL_LZ_DICT_SIZE_MASK = TDEFL_LZ_DICT_SIZE - 1,
|
||||||
|
TDEFL_MIN_MATCH_LEN = 3,
|
||||||
|
TDEFL_MAX_MATCH_LEN = 258
|
||||||
|
};
|
||||||
|
|
||||||
|
/* TDEFL_OUT_BUF_SIZE MUST be large enough to hold a single entire compressed output block (using static/fixed Huffman codes). */
|
||||||
|
#if TDEFL_LESS_MEMORY
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
TDEFL_LZ_CODE_BUF_SIZE = 24 * 1024,
|
||||||
|
TDEFL_OUT_BUF_SIZE = (TDEFL_LZ_CODE_BUF_SIZE * 13) / 10,
|
||||||
|
TDEFL_MAX_HUFF_SYMBOLS = 288,
|
||||||
|
TDEFL_LZ_HASH_BITS = 12,
|
||||||
|
TDEFL_LEVEL1_HASH_SIZE_MASK = 4095,
|
||||||
|
TDEFL_LZ_HASH_SHIFT = (TDEFL_LZ_HASH_BITS + 2) / 3,
|
||||||
|
TDEFL_LZ_HASH_SIZE = 1 << TDEFL_LZ_HASH_BITS
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
TDEFL_LZ_CODE_BUF_SIZE = 64 * 1024,
|
||||||
|
TDEFL_OUT_BUF_SIZE = (mz_uint)((TDEFL_LZ_CODE_BUF_SIZE * 13) / 10),
|
||||||
|
TDEFL_MAX_HUFF_SYMBOLS = 288,
|
||||||
|
TDEFL_LZ_HASH_BITS = 15,
|
||||||
|
TDEFL_LEVEL1_HASH_SIZE_MASK = 4095,
|
||||||
|
TDEFL_LZ_HASH_SHIFT = (TDEFL_LZ_HASH_BITS + 2) / 3,
|
||||||
|
TDEFL_LZ_HASH_SIZE = 1 << TDEFL_LZ_HASH_BITS
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The low-level tdefl functions below may be used directly if the above helper functions aren't flexible enough. The low-level functions don't make any heap allocations, unlike the above helper functions. */
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
TDEFL_STATUS_BAD_PARAM = -2,
|
||||||
|
TDEFL_STATUS_PUT_BUF_FAILED = -1,
|
||||||
|
TDEFL_STATUS_OKAY = 0,
|
||||||
|
TDEFL_STATUS_DONE = 1
|
||||||
|
} tdefl_status;
|
||||||
|
|
||||||
|
/* Must map to MZ_NO_FLUSH, MZ_SYNC_FLUSH, etc. enums */
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
TDEFL_NO_FLUSH = 0,
|
||||||
|
TDEFL_SYNC_FLUSH = 2,
|
||||||
|
TDEFL_FULL_FLUSH = 3,
|
||||||
|
TDEFL_FINISH = 4
|
||||||
|
} tdefl_flush;
|
||||||
|
|
||||||
|
/* tdefl's compression state structure. */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
tdefl_put_buf_func_ptr m_pPut_buf_func;
|
||||||
|
void *m_pPut_buf_user;
|
||||||
|
mz_uint m_flags, m_max_probes[2];
|
||||||
|
int m_greedy_parsing;
|
||||||
|
mz_uint m_adler32, m_lookahead_pos, m_lookahead_size, m_dict_size;
|
||||||
|
mz_uint8 *m_pLZ_code_buf, *m_pLZ_flags, *m_pOutput_buf, *m_pOutput_buf_end;
|
||||||
|
mz_uint m_num_flags_left, m_total_lz_bytes, m_lz_code_buf_dict_pos, m_bits_in, m_bit_buffer;
|
||||||
|
mz_uint m_saved_match_dist, m_saved_match_len, m_saved_lit, m_output_flush_ofs, m_output_flush_remaining, m_finished, m_block_index, m_wants_to_finish;
|
||||||
|
tdefl_status m_prev_return_status;
|
||||||
|
const void *m_pIn_buf;
|
||||||
|
void *m_pOut_buf;
|
||||||
|
size_t *m_pIn_buf_size, *m_pOut_buf_size;
|
||||||
|
tdefl_flush m_flush;
|
||||||
|
const mz_uint8 *m_pSrc;
|
||||||
|
size_t m_src_buf_left, m_out_buf_ofs;
|
||||||
|
mz_uint8 m_dict[TDEFL_LZ_DICT_SIZE + TDEFL_MAX_MATCH_LEN - 1];
|
||||||
|
mz_uint16 m_huff_count[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS];
|
||||||
|
mz_uint16 m_huff_codes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS];
|
||||||
|
mz_uint8 m_huff_code_sizes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS];
|
||||||
|
mz_uint8 m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE];
|
||||||
|
mz_uint16 m_next[TDEFL_LZ_DICT_SIZE];
|
||||||
|
mz_uint16 m_hash[TDEFL_LZ_HASH_SIZE];
|
||||||
|
mz_uint8 m_output_buf[TDEFL_OUT_BUF_SIZE];
|
||||||
|
} tdefl_compressor;
|
||||||
|
|
||||||
|
/* Initializes the compressor. */
|
||||||
|
/* There is no corresponding deinit() function because the tdefl API's do not dynamically allocate memory. */
|
||||||
|
/* pBut_buf_func: If NULL, output data will be supplied to the specified callback. In this case, the user should call the tdefl_compress_buffer() API for compression. */
|
||||||
|
/* If pBut_buf_func is NULL the user should always call the tdefl_compress() API. */
|
||||||
|
/* flags: See the above enums (TDEFL_HUFFMAN_ONLY, TDEFL_WRITE_ZLIB_HEADER, etc.) */
|
||||||
|
MINIZ_EXPORT tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags);
|
||||||
|
|
||||||
|
/* Compresses a block of data, consuming as much of the specified input buffer as possible, and writing as much compressed data to the specified output buffer as possible. */
|
||||||
|
MINIZ_EXPORT tdefl_status tdefl_compress(tdefl_compressor *d, const void *pIn_buf, size_t *pIn_buf_size, void *pOut_buf, size_t *pOut_buf_size, tdefl_flush flush);
|
||||||
|
|
||||||
|
/* tdefl_compress_buffer() is only usable when the tdefl_init() is called with a non-NULL tdefl_put_buf_func_ptr. */
|
||||||
|
/* tdefl_compress_buffer() always consumes the entire input buffer. */
|
||||||
|
MINIZ_EXPORT tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf, size_t in_buf_size, tdefl_flush flush);
|
||||||
|
|
||||||
|
MINIZ_EXPORT tdefl_status tdefl_get_prev_return_status(tdefl_compressor *d);
|
||||||
|
MINIZ_EXPORT mz_uint32 tdefl_get_adler32(tdefl_compressor *d);
|
||||||
|
|
||||||
|
/* Create tdefl_compress() flags given zlib-style compression parameters. */
|
||||||
|
/* level may range from [0,10] (where 10 is absolute max compression, but may be much slower on some files) */
|
||||||
|
/* window_bits may be -15 (raw deflate) or 15 (zlib) */
|
||||||
|
/* strategy may be either MZ_DEFAULT_STRATEGY, MZ_FILTERED, MZ_HUFFMAN_ONLY, MZ_RLE, or MZ_FIXED */
|
||||||
|
MINIZ_EXPORT mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy);
|
||||||
|
|
||||||
|
#ifndef MINIZ_NO_MALLOC
|
||||||
|
/* Allocate the tdefl_compressor structure in C so that */
|
||||||
|
/* non-C language bindings to tdefl_ API don't need to worry about */
|
||||||
|
/* structure size and allocation mechanism. */
|
||||||
|
MINIZ_EXPORT tdefl_compressor *tdefl_compressor_alloc(void);
|
||||||
|
MINIZ_EXPORT void tdefl_compressor_free(tdefl_compressor *pComp);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*#ifndef MINIZ_NO_DEFLATE_APIS*/
|
||||||
778
libs/miniz/miniz_tinfl.c
Normal file
@@ -0,0 +1,778 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright 2013-2014 RAD Game Tools and Valve Software
|
||||||
|
* Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
|
||||||
|
* All Rights Reserved.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#include "miniz.h"
|
||||||
|
|
||||||
|
#ifndef MINIZ_NO_INFLATE_APIS
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ------------------- Low-level Decompression (completely independent from all compression API's) */
|
||||||
|
|
||||||
|
#define TINFL_MEMCPY(d, s, l) memcpy(d, s, l)
|
||||||
|
#define TINFL_MEMSET(p, c, l) memset(p, c, l)
|
||||||
|
|
||||||
|
#define TINFL_CR_BEGIN \
|
||||||
|
switch (r->m_state) \
|
||||||
|
{ \
|
||||||
|
case 0:
|
||||||
|
#define TINFL_CR_RETURN(state_index, result) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
status = result; \
|
||||||
|
r->m_state = state_index; \
|
||||||
|
goto common_exit; \
|
||||||
|
case state_index:; \
|
||||||
|
} \
|
||||||
|
MZ_MACRO_END
|
||||||
|
#define TINFL_CR_RETURN_FOREVER(state_index, result) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
for (;;) \
|
||||||
|
{ \
|
||||||
|
TINFL_CR_RETURN(state_index, result); \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
MZ_MACRO_END
|
||||||
|
#define TINFL_CR_FINISH }
|
||||||
|
|
||||||
|
#define TINFL_GET_BYTE(state_index, c) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
while (pIn_buf_cur >= pIn_buf_end) \
|
||||||
|
{ \
|
||||||
|
TINFL_CR_RETURN(state_index, (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) ? TINFL_STATUS_NEEDS_MORE_INPUT : TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS); \
|
||||||
|
} \
|
||||||
|
c = *pIn_buf_cur++; \
|
||||||
|
} \
|
||||||
|
MZ_MACRO_END
|
||||||
|
|
||||||
|
#define TINFL_NEED_BITS(state_index, n) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
mz_uint c; \
|
||||||
|
TINFL_GET_BYTE(state_index, c); \
|
||||||
|
bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); \
|
||||||
|
num_bits += 8; \
|
||||||
|
} while (num_bits < (mz_uint)(n))
|
||||||
|
#define TINFL_SKIP_BITS(state_index, n) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if (num_bits < (mz_uint)(n)) \
|
||||||
|
{ \
|
||||||
|
TINFL_NEED_BITS(state_index, n); \
|
||||||
|
} \
|
||||||
|
bit_buf >>= (n); \
|
||||||
|
num_bits -= (n); \
|
||||||
|
} \
|
||||||
|
MZ_MACRO_END
|
||||||
|
#define TINFL_GET_BITS(state_index, b, n) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if (num_bits < (mz_uint)(n)) \
|
||||||
|
{ \
|
||||||
|
TINFL_NEED_BITS(state_index, n); \
|
||||||
|
} \
|
||||||
|
b = bit_buf & ((1 << (n)) - 1); \
|
||||||
|
bit_buf >>= (n); \
|
||||||
|
num_bits -= (n); \
|
||||||
|
} \
|
||||||
|
MZ_MACRO_END
|
||||||
|
|
||||||
|
/* TINFL_HUFF_BITBUF_FILL() is only used rarely, when the number of bytes remaining in the input buffer falls below 2. */
|
||||||
|
/* It reads just enough bytes from the input stream that are needed to decode the next Huffman code (and absolutely no more). It works by trying to fully decode a */
|
||||||
|
/* Huffman code by using whatever bits are currently present in the bit buffer. If this fails, it reads another byte, and tries again until it succeeds or until the */
|
||||||
|
/* bit buffer contains >=15 bits (deflate's max. Huffman code size). */
|
||||||
|
#define TINFL_HUFF_BITBUF_FILL(state_index, pLookUp, pTree) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
temp = pLookUp[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \
|
||||||
|
if (temp >= 0) \
|
||||||
|
{ \
|
||||||
|
code_len = temp >> 9; \
|
||||||
|
if ((code_len) && (num_bits >= code_len)) \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
else if (num_bits > TINFL_FAST_LOOKUP_BITS) \
|
||||||
|
{ \
|
||||||
|
code_len = TINFL_FAST_LOOKUP_BITS; \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
temp = pTree[~temp + ((bit_buf >> code_len++) & 1)]; \
|
||||||
|
} while ((temp < 0) && (num_bits >= (code_len + 1))); \
|
||||||
|
if (temp >= 0) \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
TINFL_GET_BYTE(state_index, c); \
|
||||||
|
bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); \
|
||||||
|
num_bits += 8; \
|
||||||
|
} while (num_bits < 15);
|
||||||
|
|
||||||
|
/* TINFL_HUFF_DECODE() decodes the next Huffman coded symbol. It's more complex than you would initially expect because the zlib API expects the decompressor to never read */
|
||||||
|
/* beyond the final byte of the deflate stream. (In other words, when this macro wants to read another byte from the input, it REALLY needs another byte in order to fully */
|
||||||
|
/* decode the next Huffman code.) Handling this properly is particularly important on raw deflate (non-zlib) streams, which aren't followed by a byte aligned adler-32. */
|
||||||
|
/* The slow path is only executed at the very end of the input buffer. */
|
||||||
|
/* v1.16: The original macro handled the case at the very end of the passed-in input buffer, but we also need to handle the case where the user passes in 1+zillion bytes */
|
||||||
|
/* following the deflate data and our non-conservative read-ahead path won't kick in here on this code. This is much trickier. */
|
||||||
|
#define TINFL_HUFF_DECODE(state_index, sym, pLookUp, pTree) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
int temp; \
|
||||||
|
mz_uint code_len, c; \
|
||||||
|
if (num_bits < 15) \
|
||||||
|
{ \
|
||||||
|
if ((pIn_buf_end - pIn_buf_cur) < 2) \
|
||||||
|
{ \
|
||||||
|
TINFL_HUFF_BITBUF_FILL(state_index, pLookUp, pTree); \
|
||||||
|
} \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
bit_buf |= (((tinfl_bit_buf_t)pIn_buf_cur[0]) << num_bits) | (((tinfl_bit_buf_t)pIn_buf_cur[1]) << (num_bits + 8)); \
|
||||||
|
pIn_buf_cur += 2; \
|
||||||
|
num_bits += 16; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
if ((temp = pLookUp[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) \
|
||||||
|
code_len = temp >> 9, temp &= 511; \
|
||||||
|
else \
|
||||||
|
{ \
|
||||||
|
code_len = TINFL_FAST_LOOKUP_BITS; \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
temp = pTree[~temp + ((bit_buf >> code_len++) & 1)]; \
|
||||||
|
} while (temp < 0); \
|
||||||
|
} \
|
||||||
|
sym = temp; \
|
||||||
|
bit_buf >>= code_len; \
|
||||||
|
num_bits -= code_len; \
|
||||||
|
} \
|
||||||
|
MZ_MACRO_END
|
||||||
|
|
||||||
|
static void tinfl_clear_tree(tinfl_decompressor *r)
|
||||||
|
{
|
||||||
|
if (r->m_type == 0)
|
||||||
|
MZ_CLEAR_ARR(r->m_tree_0);
|
||||||
|
else if (r->m_type == 1)
|
||||||
|
MZ_CLEAR_ARR(r->m_tree_1);
|
||||||
|
else
|
||||||
|
MZ_CLEAR_ARR(r->m_tree_2);
|
||||||
|
}
|
||||||
|
|
||||||
|
tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags)
|
||||||
|
{
|
||||||
|
static const mz_uint16 s_length_base[31] = { 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 };
|
||||||
|
static const mz_uint8 s_length_extra[31] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 0, 0 };
|
||||||
|
static const mz_uint16 s_dist_base[32] = { 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 0, 0 };
|
||||||
|
static const mz_uint8 s_dist_extra[32] = { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 };
|
||||||
|
static const mz_uint8 s_length_dezigzag[19] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
|
||||||
|
static const mz_uint16 s_min_table_sizes[3] = { 257, 1, 4 };
|
||||||
|
|
||||||
|
mz_int16 *pTrees[3];
|
||||||
|
mz_uint8 *pCode_sizes[3];
|
||||||
|
|
||||||
|
tinfl_status status = TINFL_STATUS_FAILED;
|
||||||
|
mz_uint32 num_bits, dist, counter, num_extra;
|
||||||
|
tinfl_bit_buf_t bit_buf;
|
||||||
|
const mz_uint8 *pIn_buf_cur = pIn_buf_next, *const pIn_buf_end = pIn_buf_next + *pIn_buf_size;
|
||||||
|
mz_uint8 *pOut_buf_cur = pOut_buf_next, *const pOut_buf_end = pOut_buf_next ? pOut_buf_next + *pOut_buf_size : NULL;
|
||||||
|
size_t out_buf_size_mask = (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF) ? (size_t)-1 : ((pOut_buf_next - pOut_buf_start) + *pOut_buf_size) - 1, dist_from_out_buf_start;
|
||||||
|
|
||||||
|
/* Ensure the output buffer's size is a power of 2, unless the output buffer is large enough to hold the entire output file (in which case it doesn't matter). */
|
||||||
|
if (((out_buf_size_mask + 1) & out_buf_size_mask) || (pOut_buf_next < pOut_buf_start))
|
||||||
|
{
|
||||||
|
*pIn_buf_size = *pOut_buf_size = 0;
|
||||||
|
return TINFL_STATUS_BAD_PARAM;
|
||||||
|
}
|
||||||
|
|
||||||
|
pTrees[0] = r->m_tree_0;
|
||||||
|
pTrees[1] = r->m_tree_1;
|
||||||
|
pTrees[2] = r->m_tree_2;
|
||||||
|
pCode_sizes[0] = r->m_code_size_0;
|
||||||
|
pCode_sizes[1] = r->m_code_size_1;
|
||||||
|
pCode_sizes[2] = r->m_code_size_2;
|
||||||
|
|
||||||
|
num_bits = r->m_num_bits;
|
||||||
|
bit_buf = r->m_bit_buf;
|
||||||
|
dist = r->m_dist;
|
||||||
|
counter = r->m_counter;
|
||||||
|
num_extra = r->m_num_extra;
|
||||||
|
dist_from_out_buf_start = r->m_dist_from_out_buf_start;
|
||||||
|
TINFL_CR_BEGIN
|
||||||
|
|
||||||
|
bit_buf = num_bits = dist = counter = num_extra = r->m_zhdr0 = r->m_zhdr1 = 0;
|
||||||
|
r->m_z_adler32 = r->m_check_adler32 = 1;
|
||||||
|
if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER)
|
||||||
|
{
|
||||||
|
TINFL_GET_BYTE(1, r->m_zhdr0);
|
||||||
|
TINFL_GET_BYTE(2, r->m_zhdr1);
|
||||||
|
counter = (((r->m_zhdr0 * 256 + r->m_zhdr1) % 31 != 0) || (r->m_zhdr1 & 32) || ((r->m_zhdr0 & 15) != 8));
|
||||||
|
if (!(decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))
|
||||||
|
counter |= (((1U << (8U + (r->m_zhdr0 >> 4))) > 32768U) || ((out_buf_size_mask + 1) < (size_t)((size_t)1 << (8U + (r->m_zhdr0 >> 4)))));
|
||||||
|
if (counter)
|
||||||
|
{
|
||||||
|
TINFL_CR_RETURN_FOREVER(36, TINFL_STATUS_FAILED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
TINFL_GET_BITS(3, r->m_final, 3);
|
||||||
|
r->m_type = r->m_final >> 1;
|
||||||
|
if (r->m_type == 0)
|
||||||
|
{
|
||||||
|
TINFL_SKIP_BITS(5, num_bits & 7);
|
||||||
|
for (counter = 0; counter < 4; ++counter)
|
||||||
|
{
|
||||||
|
if (num_bits)
|
||||||
|
TINFL_GET_BITS(6, r->m_raw_header[counter], 8);
|
||||||
|
else
|
||||||
|
TINFL_GET_BYTE(7, r->m_raw_header[counter]);
|
||||||
|
}
|
||||||
|
if ((counter = (r->m_raw_header[0] | (r->m_raw_header[1] << 8))) != (mz_uint)(0xFFFF ^ (r->m_raw_header[2] | (r->m_raw_header[3] << 8))))
|
||||||
|
{
|
||||||
|
TINFL_CR_RETURN_FOREVER(39, TINFL_STATUS_FAILED);
|
||||||
|
}
|
||||||
|
while ((counter) && (num_bits))
|
||||||
|
{
|
||||||
|
TINFL_GET_BITS(51, dist, 8);
|
||||||
|
while (pOut_buf_cur >= pOut_buf_end)
|
||||||
|
{
|
||||||
|
TINFL_CR_RETURN(52, TINFL_STATUS_HAS_MORE_OUTPUT);
|
||||||
|
}
|
||||||
|
*pOut_buf_cur++ = (mz_uint8)dist;
|
||||||
|
counter--;
|
||||||
|
}
|
||||||
|
while (counter)
|
||||||
|
{
|
||||||
|
size_t n;
|
||||||
|
while (pOut_buf_cur >= pOut_buf_end)
|
||||||
|
{
|
||||||
|
TINFL_CR_RETURN(9, TINFL_STATUS_HAS_MORE_OUTPUT);
|
||||||
|
}
|
||||||
|
while (pIn_buf_cur >= pIn_buf_end)
|
||||||
|
{
|
||||||
|
TINFL_CR_RETURN(38, (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) ? TINFL_STATUS_NEEDS_MORE_INPUT : TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS);
|
||||||
|
}
|
||||||
|
n = MZ_MIN(MZ_MIN((size_t)(pOut_buf_end - pOut_buf_cur), (size_t)(pIn_buf_end - pIn_buf_cur)), counter);
|
||||||
|
TINFL_MEMCPY(pOut_buf_cur, pIn_buf_cur, n);
|
||||||
|
pIn_buf_cur += n;
|
||||||
|
pOut_buf_cur += n;
|
||||||
|
counter -= (mz_uint)n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (r->m_type == 3)
|
||||||
|
{
|
||||||
|
TINFL_CR_RETURN_FOREVER(10, TINFL_STATUS_FAILED);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (r->m_type == 1)
|
||||||
|
{
|
||||||
|
mz_uint8 *p = r->m_code_size_0;
|
||||||
|
mz_uint i;
|
||||||
|
r->m_table_sizes[0] = 288;
|
||||||
|
r->m_table_sizes[1] = 32;
|
||||||
|
TINFL_MEMSET(r->m_code_size_1, 5, 32);
|
||||||
|
for (i = 0; i <= 143; ++i)
|
||||||
|
*p++ = 8;
|
||||||
|
for (; i <= 255; ++i)
|
||||||
|
*p++ = 9;
|
||||||
|
for (; i <= 279; ++i)
|
||||||
|
*p++ = 7;
|
||||||
|
for (; i <= 287; ++i)
|
||||||
|
*p++ = 8;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (counter = 0; counter < 3; counter++)
|
||||||
|
{
|
||||||
|
TINFL_GET_BITS(11, r->m_table_sizes[counter], "\05\05\04"[counter]);
|
||||||
|
r->m_table_sizes[counter] += s_min_table_sizes[counter];
|
||||||
|
}
|
||||||
|
MZ_CLEAR_ARR(r->m_code_size_2);
|
||||||
|
for (counter = 0; counter < r->m_table_sizes[2]; counter++)
|
||||||
|
{
|
||||||
|
mz_uint s;
|
||||||
|
TINFL_GET_BITS(14, s, 3);
|
||||||
|
r->m_code_size_2[s_length_dezigzag[counter]] = (mz_uint8)s;
|
||||||
|
}
|
||||||
|
r->m_table_sizes[2] = 19;
|
||||||
|
}
|
||||||
|
for (; (int)r->m_type >= 0; r->m_type--)
|
||||||
|
{
|
||||||
|
int tree_next, tree_cur;
|
||||||
|
mz_int16 *pLookUp;
|
||||||
|
mz_int16 *pTree;
|
||||||
|
mz_uint8 *pCode_size;
|
||||||
|
mz_uint i, j, used_syms, total, sym_index, next_code[17], total_syms[16];
|
||||||
|
pLookUp = r->m_look_up[r->m_type];
|
||||||
|
pTree = pTrees[r->m_type];
|
||||||
|
pCode_size = pCode_sizes[r->m_type];
|
||||||
|
MZ_CLEAR_ARR(total_syms);
|
||||||
|
TINFL_MEMSET(pLookUp, 0, sizeof(r->m_look_up[0]));
|
||||||
|
tinfl_clear_tree(r);
|
||||||
|
for (i = 0; i < r->m_table_sizes[r->m_type]; ++i)
|
||||||
|
total_syms[pCode_size[i]]++;
|
||||||
|
used_syms = 0, total = 0;
|
||||||
|
next_code[0] = next_code[1] = 0;
|
||||||
|
for (i = 1; i <= 15; ++i)
|
||||||
|
{
|
||||||
|
used_syms += total_syms[i];
|
||||||
|
next_code[i + 1] = (total = ((total + total_syms[i]) << 1));
|
||||||
|
}
|
||||||
|
if ((65536 != total) && (used_syms > 1))
|
||||||
|
{
|
||||||
|
TINFL_CR_RETURN_FOREVER(35, TINFL_STATUS_FAILED);
|
||||||
|
}
|
||||||
|
for (tree_next = -1, sym_index = 0; sym_index < r->m_table_sizes[r->m_type]; ++sym_index)
|
||||||
|
{
|
||||||
|
mz_uint rev_code = 0, l, cur_code, code_size = pCode_size[sym_index];
|
||||||
|
if (!code_size)
|
||||||
|
continue;
|
||||||
|
cur_code = next_code[code_size]++;
|
||||||
|
for (l = code_size; l > 0; l--, cur_code >>= 1)
|
||||||
|
rev_code = (rev_code << 1) | (cur_code & 1);
|
||||||
|
if (code_size <= TINFL_FAST_LOOKUP_BITS)
|
||||||
|
{
|
||||||
|
mz_int16 k = (mz_int16)((code_size << 9) | sym_index);
|
||||||
|
while (rev_code < TINFL_FAST_LOOKUP_SIZE)
|
||||||
|
{
|
||||||
|
pLookUp[rev_code] = k;
|
||||||
|
rev_code += (1 << code_size);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (0 == (tree_cur = pLookUp[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)]))
|
||||||
|
{
|
||||||
|
pLookUp[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)] = (mz_int16)tree_next;
|
||||||
|
tree_cur = tree_next;
|
||||||
|
tree_next -= 2;
|
||||||
|
}
|
||||||
|
rev_code >>= (TINFL_FAST_LOOKUP_BITS - 1);
|
||||||
|
for (j = code_size; j > (TINFL_FAST_LOOKUP_BITS + 1); j--)
|
||||||
|
{
|
||||||
|
tree_cur -= ((rev_code >>= 1) & 1);
|
||||||
|
if (!pTree[-tree_cur - 1])
|
||||||
|
{
|
||||||
|
pTree[-tree_cur - 1] = (mz_int16)tree_next;
|
||||||
|
tree_cur = tree_next;
|
||||||
|
tree_next -= 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
tree_cur = pTree[-tree_cur - 1];
|
||||||
|
}
|
||||||
|
tree_cur -= ((rev_code >>= 1) & 1);
|
||||||
|
pTree[-tree_cur - 1] = (mz_int16)sym_index;
|
||||||
|
}
|
||||||
|
if (r->m_type == 2)
|
||||||
|
{
|
||||||
|
for (counter = 0; counter < (r->m_table_sizes[0] + r->m_table_sizes[1]);)
|
||||||
|
{
|
||||||
|
mz_uint s;
|
||||||
|
TINFL_HUFF_DECODE(16, dist, r->m_look_up[2], r->m_tree_2);
|
||||||
|
if (dist < 16)
|
||||||
|
{
|
||||||
|
r->m_len_codes[counter++] = (mz_uint8)dist;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ((dist == 16) && (!counter))
|
||||||
|
{
|
||||||
|
TINFL_CR_RETURN_FOREVER(17, TINFL_STATUS_FAILED);
|
||||||
|
}
|
||||||
|
num_extra = "\02\03\07"[dist - 16];
|
||||||
|
TINFL_GET_BITS(18, s, num_extra);
|
||||||
|
s += "\03\03\013"[dist - 16];
|
||||||
|
TINFL_MEMSET(r->m_len_codes + counter, (dist == 16) ? r->m_len_codes[counter - 1] : 0, s);
|
||||||
|
counter += s;
|
||||||
|
}
|
||||||
|
if ((r->m_table_sizes[0] + r->m_table_sizes[1]) != counter)
|
||||||
|
{
|
||||||
|
TINFL_CR_RETURN_FOREVER(21, TINFL_STATUS_FAILED);
|
||||||
|
}
|
||||||
|
TINFL_MEMCPY(r->m_code_size_0, r->m_len_codes, r->m_table_sizes[0]);
|
||||||
|
TINFL_MEMCPY(r->m_code_size_1, r->m_len_codes + r->m_table_sizes[0], r->m_table_sizes[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
mz_uint8 *pSrc;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
if (((pIn_buf_end - pIn_buf_cur) < 4) || ((pOut_buf_end - pOut_buf_cur) < 2))
|
||||||
|
{
|
||||||
|
TINFL_HUFF_DECODE(23, counter, r->m_look_up[0], r->m_tree_0);
|
||||||
|
if (counter >= 256)
|
||||||
|
break;
|
||||||
|
while (pOut_buf_cur >= pOut_buf_end)
|
||||||
|
{
|
||||||
|
TINFL_CR_RETURN(24, TINFL_STATUS_HAS_MORE_OUTPUT);
|
||||||
|
}
|
||||||
|
*pOut_buf_cur++ = (mz_uint8)counter;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int sym2;
|
||||||
|
mz_uint code_len;
|
||||||
|
#if TINFL_USE_64BIT_BITBUF
|
||||||
|
if (num_bits < 30)
|
||||||
|
{
|
||||||
|
bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE32(pIn_buf_cur)) << num_bits);
|
||||||
|
pIn_buf_cur += 4;
|
||||||
|
num_bits += 32;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (num_bits < 15)
|
||||||
|
{
|
||||||
|
bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits);
|
||||||
|
pIn_buf_cur += 2;
|
||||||
|
num_bits += 16;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if ((sym2 = r->m_look_up[0][bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
|
||||||
|
code_len = sym2 >> 9;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
code_len = TINFL_FAST_LOOKUP_BITS;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
sym2 = r->m_tree_0[~sym2 + ((bit_buf >> code_len++) & 1)];
|
||||||
|
} while (sym2 < 0);
|
||||||
|
}
|
||||||
|
counter = sym2;
|
||||||
|
bit_buf >>= code_len;
|
||||||
|
num_bits -= code_len;
|
||||||
|
if (code_len == 0)
|
||||||
|
{
|
||||||
|
TINFL_CR_RETURN_FOREVER(40, TINFL_STATUS_FAILED);
|
||||||
|
}
|
||||||
|
if (counter & 256)
|
||||||
|
break;
|
||||||
|
|
||||||
|
#if !TINFL_USE_64BIT_BITBUF
|
||||||
|
if (num_bits < 15)
|
||||||
|
{
|
||||||
|
bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits);
|
||||||
|
pIn_buf_cur += 2;
|
||||||
|
num_bits += 16;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if ((sym2 = r->m_look_up[0][bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
|
||||||
|
code_len = sym2 >> 9;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
code_len = TINFL_FAST_LOOKUP_BITS;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
sym2 = r->m_tree_0[~sym2 + ((bit_buf >> code_len++) & 1)];
|
||||||
|
} while (sym2 < 0);
|
||||||
|
}
|
||||||
|
bit_buf >>= code_len;
|
||||||
|
num_bits -= code_len;
|
||||||
|
if (code_len == 0)
|
||||||
|
{
|
||||||
|
TINFL_CR_RETURN_FOREVER(54, TINFL_STATUS_FAILED);
|
||||||
|
}
|
||||||
|
|
||||||
|
pOut_buf_cur[0] = (mz_uint8)counter;
|
||||||
|
if (sym2 & 256)
|
||||||
|
{
|
||||||
|
pOut_buf_cur++;
|
||||||
|
counter = sym2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pOut_buf_cur[1] = (mz_uint8)sym2;
|
||||||
|
pOut_buf_cur += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((counter &= 511) == 256)
|
||||||
|
break;
|
||||||
|
|
||||||
|
num_extra = s_length_extra[counter - 257];
|
||||||
|
counter = s_length_base[counter - 257];
|
||||||
|
if (num_extra)
|
||||||
|
{
|
||||||
|
mz_uint extra_bits;
|
||||||
|
TINFL_GET_BITS(25, extra_bits, num_extra);
|
||||||
|
counter += extra_bits;
|
||||||
|
}
|
||||||
|
|
||||||
|
TINFL_HUFF_DECODE(26, dist, r->m_look_up[1], r->m_tree_1);
|
||||||
|
num_extra = s_dist_extra[dist];
|
||||||
|
dist = s_dist_base[dist];
|
||||||
|
if (num_extra)
|
||||||
|
{
|
||||||
|
mz_uint extra_bits;
|
||||||
|
TINFL_GET_BITS(27, extra_bits, num_extra);
|
||||||
|
dist += extra_bits;
|
||||||
|
}
|
||||||
|
|
||||||
|
dist_from_out_buf_start = pOut_buf_cur - pOut_buf_start;
|
||||||
|
if ((dist == 0 || dist > dist_from_out_buf_start || dist_from_out_buf_start == 0) && (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))
|
||||||
|
{
|
||||||
|
TINFL_CR_RETURN_FOREVER(37, TINFL_STATUS_FAILED);
|
||||||
|
}
|
||||||
|
|
||||||
|
pSrc = pOut_buf_start + ((dist_from_out_buf_start - dist) & out_buf_size_mask);
|
||||||
|
|
||||||
|
if ((MZ_MAX(pOut_buf_cur, pSrc) + counter) > pOut_buf_end)
|
||||||
|
{
|
||||||
|
while (counter--)
|
||||||
|
{
|
||||||
|
while (pOut_buf_cur >= pOut_buf_end)
|
||||||
|
{
|
||||||
|
TINFL_CR_RETURN(53, TINFL_STATUS_HAS_MORE_OUTPUT);
|
||||||
|
}
|
||||||
|
*pOut_buf_cur++ = pOut_buf_start[(dist_from_out_buf_start++ - dist) & out_buf_size_mask];
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
|
||||||
|
else if ((counter >= 9) && (counter <= dist))
|
||||||
|
{
|
||||||
|
const mz_uint8 *pSrc_end = pSrc + (counter & ~7);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
#ifdef MINIZ_UNALIGNED_USE_MEMCPY
|
||||||
|
memcpy(pOut_buf_cur, pSrc, sizeof(mz_uint32) * 2);
|
||||||
|
#else
|
||||||
|
((mz_uint32 *)pOut_buf_cur)[0] = ((const mz_uint32 *)pSrc)[0];
|
||||||
|
((mz_uint32 *)pOut_buf_cur)[1] = ((const mz_uint32 *)pSrc)[1];
|
||||||
|
#endif
|
||||||
|
pOut_buf_cur += 8;
|
||||||
|
} while ((pSrc += 8) < pSrc_end);
|
||||||
|
if ((counter &= 7) < 3)
|
||||||
|
{
|
||||||
|
if (counter)
|
||||||
|
{
|
||||||
|
pOut_buf_cur[0] = pSrc[0];
|
||||||
|
if (counter > 1)
|
||||||
|
pOut_buf_cur[1] = pSrc[1];
|
||||||
|
pOut_buf_cur += counter;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
while (counter > 2)
|
||||||
|
{
|
||||||
|
pOut_buf_cur[0] = pSrc[0];
|
||||||
|
pOut_buf_cur[1] = pSrc[1];
|
||||||
|
pOut_buf_cur[2] = pSrc[2];
|
||||||
|
pOut_buf_cur += 3;
|
||||||
|
pSrc += 3;
|
||||||
|
counter -= 3;
|
||||||
|
}
|
||||||
|
if (counter > 0)
|
||||||
|
{
|
||||||
|
pOut_buf_cur[0] = pSrc[0];
|
||||||
|
if (counter > 1)
|
||||||
|
pOut_buf_cur[1] = pSrc[1];
|
||||||
|
pOut_buf_cur += counter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (!(r->m_final & 1));
|
||||||
|
|
||||||
|
/* Ensure byte alignment and put back any bytes from the bitbuf if we've looked ahead too far on gzip, or other Deflate streams followed by arbitrary data. */
|
||||||
|
/* I'm being super conservative here. A number of simplifications can be made to the byte alignment part, and the Adler32 check shouldn't ever need to worry about reading from the bitbuf now. */
|
||||||
|
TINFL_SKIP_BITS(32, num_bits & 7);
|
||||||
|
while ((pIn_buf_cur > pIn_buf_next) && (num_bits >= 8))
|
||||||
|
{
|
||||||
|
--pIn_buf_cur;
|
||||||
|
num_bits -= 8;
|
||||||
|
}
|
||||||
|
bit_buf &= ~(~(tinfl_bit_buf_t)0 << num_bits);
|
||||||
|
MZ_ASSERT(!num_bits); /* if this assert fires then we've read beyond the end of non-deflate/zlib streams with following data (such as gzip streams). */
|
||||||
|
|
||||||
|
if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER)
|
||||||
|
{
|
||||||
|
for (counter = 0; counter < 4; ++counter)
|
||||||
|
{
|
||||||
|
mz_uint s;
|
||||||
|
if (num_bits)
|
||||||
|
TINFL_GET_BITS(41, s, 8);
|
||||||
|
else
|
||||||
|
TINFL_GET_BYTE(42, s);
|
||||||
|
r->m_z_adler32 = (r->m_z_adler32 << 8) | s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TINFL_CR_RETURN_FOREVER(34, TINFL_STATUS_DONE);
|
||||||
|
|
||||||
|
TINFL_CR_FINISH
|
||||||
|
|
||||||
|
common_exit:
|
||||||
|
/* As long as we aren't telling the caller that we NEED more input to make forward progress: */
|
||||||
|
/* Put back any bytes from the bitbuf in case we've looked ahead too far on gzip, or other Deflate streams followed by arbitrary data. */
|
||||||
|
/* We need to be very careful here to NOT push back any bytes we definitely know we need to make forward progress, though, or we'll lock the caller up into an inf loop. */
|
||||||
|
if ((status != TINFL_STATUS_NEEDS_MORE_INPUT) && (status != TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS))
|
||||||
|
{
|
||||||
|
while ((pIn_buf_cur > pIn_buf_next) && (num_bits >= 8))
|
||||||
|
{
|
||||||
|
--pIn_buf_cur;
|
||||||
|
num_bits -= 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
r->m_num_bits = num_bits;
|
||||||
|
r->m_bit_buf = bit_buf & ~(~(tinfl_bit_buf_t)0 << num_bits);
|
||||||
|
r->m_dist = dist;
|
||||||
|
r->m_counter = counter;
|
||||||
|
r->m_num_extra = num_extra;
|
||||||
|
r->m_dist_from_out_buf_start = dist_from_out_buf_start;
|
||||||
|
*pIn_buf_size = pIn_buf_cur - pIn_buf_next;
|
||||||
|
*pOut_buf_size = pOut_buf_cur - pOut_buf_next;
|
||||||
|
if ((decomp_flags & (TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_COMPUTE_ADLER32)) && (status >= 0))
|
||||||
|
{
|
||||||
|
const mz_uint8 *ptr = pOut_buf_next;
|
||||||
|
size_t buf_len = *pOut_buf_size;
|
||||||
|
mz_uint32 i, s1 = r->m_check_adler32 & 0xffff, s2 = r->m_check_adler32 >> 16;
|
||||||
|
size_t block_len = buf_len % 5552;
|
||||||
|
while (buf_len)
|
||||||
|
{
|
||||||
|
for (i = 0; i + 7 < block_len; i += 8, ptr += 8)
|
||||||
|
{
|
||||||
|
s1 += ptr[0], s2 += s1;
|
||||||
|
s1 += ptr[1], s2 += s1;
|
||||||
|
s1 += ptr[2], s2 += s1;
|
||||||
|
s1 += ptr[3], s2 += s1;
|
||||||
|
s1 += ptr[4], s2 += s1;
|
||||||
|
s1 += ptr[5], s2 += s1;
|
||||||
|
s1 += ptr[6], s2 += s1;
|
||||||
|
s1 += ptr[7], s2 += s1;
|
||||||
|
}
|
||||||
|
for (; i < block_len; ++i)
|
||||||
|
s1 += *ptr++, s2 += s1;
|
||||||
|
s1 %= 65521U, s2 %= 65521U;
|
||||||
|
buf_len -= block_len;
|
||||||
|
block_len = 5552;
|
||||||
|
}
|
||||||
|
r->m_check_adler32 = (s2 << 16) + s1;
|
||||||
|
if ((status == TINFL_STATUS_DONE) && (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) && (r->m_check_adler32 != r->m_z_adler32))
|
||||||
|
status = TINFL_STATUS_ADLER32_MISMATCH;
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Higher level helper functions. */
|
||||||
|
void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags)
|
||||||
|
{
|
||||||
|
tinfl_decompressor decomp;
|
||||||
|
void *pBuf = NULL, *pNew_buf;
|
||||||
|
size_t src_buf_ofs = 0, out_buf_capacity = 0;
|
||||||
|
*pOut_len = 0;
|
||||||
|
tinfl_init(&decomp);
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
size_t src_buf_size = src_buf_len - src_buf_ofs, dst_buf_size = out_buf_capacity - *pOut_len, new_out_buf_capacity;
|
||||||
|
tinfl_status status = tinfl_decompress(&decomp, (const mz_uint8 *)pSrc_buf + src_buf_ofs, &src_buf_size, (mz_uint8 *)pBuf, pBuf ? (mz_uint8 *)pBuf + *pOut_len : NULL, &dst_buf_size,
|
||||||
|
(flags & ~TINFL_FLAG_HAS_MORE_INPUT) | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF);
|
||||||
|
if ((status < 0) || (status == TINFL_STATUS_NEEDS_MORE_INPUT))
|
||||||
|
{
|
||||||
|
MZ_FREE(pBuf);
|
||||||
|
*pOut_len = 0;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
src_buf_ofs += src_buf_size;
|
||||||
|
*pOut_len += dst_buf_size;
|
||||||
|
if (status == TINFL_STATUS_DONE)
|
||||||
|
break;
|
||||||
|
new_out_buf_capacity = out_buf_capacity * 2;
|
||||||
|
if (new_out_buf_capacity < 128)
|
||||||
|
new_out_buf_capacity = 128;
|
||||||
|
pNew_buf = MZ_REALLOC(pBuf, new_out_buf_capacity);
|
||||||
|
if (!pNew_buf)
|
||||||
|
{
|
||||||
|
MZ_FREE(pBuf);
|
||||||
|
*pOut_len = 0;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
pBuf = pNew_buf;
|
||||||
|
out_buf_capacity = new_out_buf_capacity;
|
||||||
|
}
|
||||||
|
return pBuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags)
|
||||||
|
{
|
||||||
|
tinfl_decompressor decomp;
|
||||||
|
tinfl_status status;
|
||||||
|
tinfl_init(&decomp);
|
||||||
|
status = tinfl_decompress(&decomp, (const mz_uint8 *)pSrc_buf, &src_buf_len, (mz_uint8 *)pOut_buf, (mz_uint8 *)pOut_buf, &out_buf_len, (flags & ~TINFL_FLAG_HAS_MORE_INPUT) | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF);
|
||||||
|
return (status != TINFL_STATUS_DONE) ? TINFL_DECOMPRESS_MEM_TO_MEM_FAILED : out_buf_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, tinfl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags)
|
||||||
|
{
|
||||||
|
int result = 0;
|
||||||
|
tinfl_decompressor decomp;
|
||||||
|
mz_uint8 *pDict = (mz_uint8 *)MZ_MALLOC(TINFL_LZ_DICT_SIZE);
|
||||||
|
size_t in_buf_ofs = 0, dict_ofs = 0;
|
||||||
|
if (!pDict)
|
||||||
|
return TINFL_STATUS_FAILED;
|
||||||
|
memset(pDict, 0, TINFL_LZ_DICT_SIZE);
|
||||||
|
tinfl_init(&decomp);
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
size_t in_buf_size = *pIn_buf_size - in_buf_ofs, dst_buf_size = TINFL_LZ_DICT_SIZE - dict_ofs;
|
||||||
|
tinfl_status status = tinfl_decompress(&decomp, (const mz_uint8 *)pIn_buf + in_buf_ofs, &in_buf_size, pDict, pDict + dict_ofs, &dst_buf_size,
|
||||||
|
(flags & ~(TINFL_FLAG_HAS_MORE_INPUT | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)));
|
||||||
|
in_buf_ofs += in_buf_size;
|
||||||
|
if ((dst_buf_size) && (!(*pPut_buf_func)(pDict + dict_ofs, (int)dst_buf_size, pPut_buf_user)))
|
||||||
|
break;
|
||||||
|
if (status != TINFL_STATUS_HAS_MORE_OUTPUT)
|
||||||
|
{
|
||||||
|
result = (status == TINFL_STATUS_DONE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
dict_ofs = (dict_ofs + dst_buf_size) & (TINFL_LZ_DICT_SIZE - 1);
|
||||||
|
}
|
||||||
|
MZ_FREE(pDict);
|
||||||
|
*pIn_buf_size = in_buf_ofs;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef MINIZ_NO_MALLOC
|
||||||
|
tinfl_decompressor *tinfl_decompressor_alloc(void)
|
||||||
|
{
|
||||||
|
tinfl_decompressor *pDecomp = (tinfl_decompressor *)MZ_MALLOC(sizeof(tinfl_decompressor));
|
||||||
|
if (pDecomp)
|
||||||
|
tinfl_init(pDecomp);
|
||||||
|
return pDecomp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void tinfl_decompressor_free(tinfl_decompressor *pDecomp)
|
||||||
|
{
|
||||||
|
MZ_FREE(pDecomp);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*#ifndef MINIZ_NO_INFLATE_APIS*/
|
||||||
150
libs/miniz/miniz_tinfl.h
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "miniz_common.h"
|
||||||
|
/* ------------------- Low-level Decompression API Definitions */
|
||||||
|
|
||||||
|
#ifndef MINIZ_NO_INFLATE_APIS
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
/* Decompression flags used by tinfl_decompress(). */
|
||||||
|
/* TINFL_FLAG_PARSE_ZLIB_HEADER: If set, the input has a valid zlib header and ends with an adler32 checksum (it's a valid zlib stream). Otherwise, the input is a raw deflate stream. */
|
||||||
|
/* TINFL_FLAG_HAS_MORE_INPUT: If set, there are more input bytes available beyond the end of the supplied input buffer. If clear, the input buffer contains all remaining input. */
|
||||||
|
/* TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF: If set, the output buffer is large enough to hold the entire decompressed stream. If clear, the output buffer is at least the size of the dictionary (typically 32KB). */
|
||||||
|
/* TINFL_FLAG_COMPUTE_ADLER32: Force adler-32 checksum computation of the decompressed bytes. */
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
TINFL_FLAG_PARSE_ZLIB_HEADER = 1,
|
||||||
|
TINFL_FLAG_HAS_MORE_INPUT = 2,
|
||||||
|
TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF = 4,
|
||||||
|
TINFL_FLAG_COMPUTE_ADLER32 = 8
|
||||||
|
};
|
||||||
|
|
||||||
|
/* High level decompression functions: */
|
||||||
|
/* tinfl_decompress_mem_to_heap() decompresses a block in memory to a heap block allocated via malloc(). */
|
||||||
|
/* On entry: */
|
||||||
|
/* pSrc_buf, src_buf_len: Pointer and size of the Deflate or zlib source data to decompress. */
|
||||||
|
/* On return: */
|
||||||
|
/* Function returns a pointer to the decompressed data, or NULL on failure. */
|
||||||
|
/* *pOut_len will be set to the decompressed data's size, which could be larger than src_buf_len on uncompressible data. */
|
||||||
|
/* The caller must call mz_free() on the returned block when it's no longer needed. */
|
||||||
|
MINIZ_EXPORT void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags);
|
||||||
|
|
||||||
|
/* tinfl_decompress_mem_to_mem() decompresses a block in memory to another block in memory. */
|
||||||
|
/* Returns TINFL_DECOMPRESS_MEM_TO_MEM_FAILED on failure, or the number of bytes written on success. */
|
||||||
|
#define TINFL_DECOMPRESS_MEM_TO_MEM_FAILED ((size_t)(-1))
|
||||||
|
MINIZ_EXPORT size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags);
|
||||||
|
|
||||||
|
/* tinfl_decompress_mem_to_callback() decompresses a block in memory to an internal 32KB buffer, and a user provided callback function will be called to flush the buffer. */
|
||||||
|
/* Returns 1 on success or 0 on failure. */
|
||||||
|
typedef int (*tinfl_put_buf_func_ptr)(const void *pBuf, int len, void *pUser);
|
||||||
|
MINIZ_EXPORT int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, tinfl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags);
|
||||||
|
|
||||||
|
struct tinfl_decompressor_tag;
|
||||||
|
typedef struct tinfl_decompressor_tag tinfl_decompressor;
|
||||||
|
|
||||||
|
#ifndef MINIZ_NO_MALLOC
|
||||||
|
/* Allocate the tinfl_decompressor structure in C so that */
|
||||||
|
/* non-C language bindings to tinfl_ API don't need to worry about */
|
||||||
|
/* structure size and allocation mechanism. */
|
||||||
|
MINIZ_EXPORT tinfl_decompressor *tinfl_decompressor_alloc(void);
|
||||||
|
MINIZ_EXPORT void tinfl_decompressor_free(tinfl_decompressor *pDecomp);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Max size of LZ dictionary. */
|
||||||
|
#define TINFL_LZ_DICT_SIZE 32768
|
||||||
|
|
||||||
|
/* Return status. */
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
/* This flags indicates the inflator needs 1 or more input bytes to make forward progress, but the caller is indicating that no more are available. The compressed data */
|
||||||
|
/* is probably corrupted. If you call the inflator again with more bytes it'll try to continue processing the input but this is a BAD sign (either the data is corrupted or you called it incorrectly). */
|
||||||
|
/* If you call it again with no input you'll just get TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS again. */
|
||||||
|
TINFL_STATUS_FAILED_CANNOT_MAKE_PROGRESS = -4,
|
||||||
|
|
||||||
|
/* This flag indicates that one or more of the input parameters was obviously bogus. (You can try calling it again, but if you get this error the calling code is wrong.) */
|
||||||
|
TINFL_STATUS_BAD_PARAM = -3,
|
||||||
|
|
||||||
|
/* This flags indicate the inflator is finished but the adler32 check of the uncompressed data didn't match. If you call it again it'll return TINFL_STATUS_DONE. */
|
||||||
|
TINFL_STATUS_ADLER32_MISMATCH = -2,
|
||||||
|
|
||||||
|
/* This flags indicate the inflator has somehow failed (bad code, corrupted input, etc.). If you call it again without resetting via tinfl_init() it it'll just keep on returning the same status failure code. */
|
||||||
|
TINFL_STATUS_FAILED = -1,
|
||||||
|
|
||||||
|
/* Any status code less than TINFL_STATUS_DONE must indicate a failure. */
|
||||||
|
|
||||||
|
/* This flag indicates the inflator has returned every byte of uncompressed data that it can, has consumed every byte that it needed, has successfully reached the end of the deflate stream, and */
|
||||||
|
/* if zlib headers and adler32 checking enabled that it has successfully checked the uncompressed data's adler32. If you call it again you'll just get TINFL_STATUS_DONE over and over again. */
|
||||||
|
TINFL_STATUS_DONE = 0,
|
||||||
|
|
||||||
|
/* This flag indicates the inflator MUST have more input data (even 1 byte) before it can make any more forward progress, or you need to clear the TINFL_FLAG_HAS_MORE_INPUT */
|
||||||
|
/* flag on the next call if you don't have any more source data. If the source data was somehow corrupted it's also possible (but unlikely) for the inflator to keep on demanding input to */
|
||||||
|
/* proceed, so be sure to properly set the TINFL_FLAG_HAS_MORE_INPUT flag. */
|
||||||
|
TINFL_STATUS_NEEDS_MORE_INPUT = 1,
|
||||||
|
|
||||||
|
/* This flag indicates the inflator definitely has 1 or more bytes of uncompressed data available, but it cannot write this data into the output buffer. */
|
||||||
|
/* Note if the source compressed data was corrupted it's possible for the inflator to return a lot of uncompressed data to the caller. I've been assuming you know how much uncompressed data to expect */
|
||||||
|
/* (either exact or worst case) and will stop calling the inflator and fail after receiving too much. In pure streaming scenarios where you have no idea how many bytes to expect this may not be possible */
|
||||||
|
/* so I may need to add some code to address this. */
|
||||||
|
TINFL_STATUS_HAS_MORE_OUTPUT = 2
|
||||||
|
} tinfl_status;
|
||||||
|
|
||||||
|
/* Initializes the decompressor to its initial state. */
|
||||||
|
#define tinfl_init(r) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
(r)->m_state = 0; \
|
||||||
|
} \
|
||||||
|
MZ_MACRO_END
|
||||||
|
#define tinfl_get_adler32(r) (r)->m_check_adler32
|
||||||
|
|
||||||
|
/* Main low-level decompressor coroutine function. This is the only function actually needed for decompression. All the other functions are just high-level helpers for improved usability. */
|
||||||
|
/* This is a universal API, i.e. it can be used as a building block to build any desired higher level decompression API. In the limit case, it can be called once per every byte input or output. */
|
||||||
|
MINIZ_EXPORT tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags);
|
||||||
|
|
||||||
|
/* Internal/private bits follow. */
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
TINFL_MAX_HUFF_TABLES = 3,
|
||||||
|
TINFL_MAX_HUFF_SYMBOLS_0 = 288,
|
||||||
|
TINFL_MAX_HUFF_SYMBOLS_1 = 32,
|
||||||
|
TINFL_MAX_HUFF_SYMBOLS_2 = 19,
|
||||||
|
TINFL_FAST_LOOKUP_BITS = 10,
|
||||||
|
TINFL_FAST_LOOKUP_SIZE = 1 << TINFL_FAST_LOOKUP_BITS
|
||||||
|
};
|
||||||
|
|
||||||
|
#if MINIZ_HAS_64BIT_REGISTERS
|
||||||
|
#define TINFL_USE_64BIT_BITBUF 1
|
||||||
|
#else
|
||||||
|
#define TINFL_USE_64BIT_BITBUF 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if TINFL_USE_64BIT_BITBUF
|
||||||
|
typedef mz_uint64 tinfl_bit_buf_t;
|
||||||
|
#define TINFL_BITBUF_SIZE (64)
|
||||||
|
#else
|
||||||
|
typedef mz_uint32 tinfl_bit_buf_t;
|
||||||
|
#define TINFL_BITBUF_SIZE (32)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct tinfl_decompressor_tag
|
||||||
|
{
|
||||||
|
mz_uint32 m_state, m_num_bits, m_zhdr0, m_zhdr1, m_z_adler32, m_final, m_type, m_check_adler32, m_dist, m_counter, m_num_extra, m_table_sizes[TINFL_MAX_HUFF_TABLES];
|
||||||
|
tinfl_bit_buf_t m_bit_buf;
|
||||||
|
size_t m_dist_from_out_buf_start;
|
||||||
|
mz_int16 m_look_up[TINFL_MAX_HUFF_TABLES][TINFL_FAST_LOOKUP_SIZE];
|
||||||
|
mz_int16 m_tree_0[TINFL_MAX_HUFF_SYMBOLS_0 * 2];
|
||||||
|
mz_int16 m_tree_1[TINFL_MAX_HUFF_SYMBOLS_1 * 2];
|
||||||
|
mz_int16 m_tree_2[TINFL_MAX_HUFF_SYMBOLS_2 * 2];
|
||||||
|
mz_uint8 m_code_size_0[TINFL_MAX_HUFF_SYMBOLS_0];
|
||||||
|
mz_uint8 m_code_size_1[TINFL_MAX_HUFF_SYMBOLS_1];
|
||||||
|
mz_uint8 m_code_size_2[TINFL_MAX_HUFF_SYMBOLS_2];
|
||||||
|
mz_uint8 m_raw_header[4], m_len_codes[TINFL_MAX_HUFF_SYMBOLS_0 + TINFL_MAX_HUFF_SYMBOLS_1 + 137];
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /*#ifndef MINIZ_NO_INFLATE_APIS*/
|
||||||
4895
libs/miniz/miniz_zip.c
Normal file
454
libs/miniz/miniz_zip.h
Normal file
@@ -0,0 +1,454 @@
|
|||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "miniz_common.h"
|
||||||
|
|
||||||
|
/* ------------------- ZIP archive reading/writing */
|
||||||
|
|
||||||
|
#ifndef MINIZ_NO_ARCHIVE_APIS
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
/* Note: These enums can be reduced as needed to save memory or stack space - they are pretty conservative. */
|
||||||
|
MZ_ZIP_MAX_IO_BUF_SIZE = 64 * 1024,
|
||||||
|
MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE = 512,
|
||||||
|
MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE = 512
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
/* Central directory file index. */
|
||||||
|
mz_uint32 m_file_index;
|
||||||
|
|
||||||
|
/* Byte offset of this entry in the archive's central directory. Note we currently only support up to UINT_MAX or less bytes in the central dir. */
|
||||||
|
mz_uint64 m_central_dir_ofs;
|
||||||
|
|
||||||
|
/* These fields are copied directly from the zip's central dir. */
|
||||||
|
mz_uint16 m_version_made_by;
|
||||||
|
mz_uint16 m_version_needed;
|
||||||
|
mz_uint16 m_bit_flag;
|
||||||
|
mz_uint16 m_method;
|
||||||
|
|
||||||
|
/* CRC-32 of uncompressed data. */
|
||||||
|
mz_uint32 m_crc32;
|
||||||
|
|
||||||
|
/* File's compressed size. */
|
||||||
|
mz_uint64 m_comp_size;
|
||||||
|
|
||||||
|
/* File's uncompressed size. Note, I've seen some old archives where directory entries had 512 bytes for their uncompressed sizes, but when you try to unpack them you actually get 0 bytes. */
|
||||||
|
mz_uint64 m_uncomp_size;
|
||||||
|
|
||||||
|
/* Zip internal and external file attributes. */
|
||||||
|
mz_uint16 m_internal_attr;
|
||||||
|
mz_uint32 m_external_attr;
|
||||||
|
|
||||||
|
/* Entry's local header file offset in bytes. */
|
||||||
|
mz_uint64 m_local_header_ofs;
|
||||||
|
|
||||||
|
/* Size of comment in bytes. */
|
||||||
|
mz_uint32 m_comment_size;
|
||||||
|
|
||||||
|
/* MZ_TRUE if the entry appears to be a directory. */
|
||||||
|
mz_bool m_is_directory;
|
||||||
|
|
||||||
|
/* MZ_TRUE if the entry uses encryption/strong encryption (which miniz_zip doesn't support) */
|
||||||
|
mz_bool m_is_encrypted;
|
||||||
|
|
||||||
|
/* MZ_TRUE if the file is not encrypted, a patch file, and if it uses a compression method we support. */
|
||||||
|
mz_bool m_is_supported;
|
||||||
|
|
||||||
|
/* Filename. If string ends in '/' it's a subdirectory entry. */
|
||||||
|
/* Guaranteed to be zero terminated, may be truncated to fit. */
|
||||||
|
char m_filename[MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE];
|
||||||
|
|
||||||
|
/* Comment field. */
|
||||||
|
/* Guaranteed to be zero terminated, may be truncated to fit. */
|
||||||
|
char m_comment[MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE];
|
||||||
|
|
||||||
|
#ifdef MINIZ_NO_TIME
|
||||||
|
MZ_TIME_T m_padding;
|
||||||
|
#else
|
||||||
|
MZ_TIME_T m_time;
|
||||||
|
#endif
|
||||||
|
} mz_zip_archive_file_stat;
|
||||||
|
|
||||||
|
typedef size_t (*mz_file_read_func)(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n);
|
||||||
|
typedef size_t (*mz_file_write_func)(void *pOpaque, mz_uint64 file_ofs, const void *pBuf, size_t n);
|
||||||
|
typedef mz_bool (*mz_file_needs_keepalive)(void *pOpaque);
|
||||||
|
|
||||||
|
struct mz_zip_internal_state_tag;
|
||||||
|
typedef struct mz_zip_internal_state_tag mz_zip_internal_state;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
MZ_ZIP_MODE_INVALID = 0,
|
||||||
|
MZ_ZIP_MODE_READING = 1,
|
||||||
|
MZ_ZIP_MODE_WRITING = 2,
|
||||||
|
MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED = 3
|
||||||
|
} mz_zip_mode;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
MZ_ZIP_FLAG_CASE_SENSITIVE = 0x0100,
|
||||||
|
MZ_ZIP_FLAG_IGNORE_PATH = 0x0200,
|
||||||
|
MZ_ZIP_FLAG_COMPRESSED_DATA = 0x0400,
|
||||||
|
MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY = 0x0800,
|
||||||
|
MZ_ZIP_FLAG_VALIDATE_LOCATE_FILE_FLAG = 0x1000, /* if enabled, mz_zip_reader_locate_file() will be called on each file as its validated to ensure the func finds the file in the central dir (intended for testing) */
|
||||||
|
MZ_ZIP_FLAG_VALIDATE_HEADERS_ONLY = 0x2000, /* validate the local headers, but don't decompress the entire file and check the crc32 */
|
||||||
|
MZ_ZIP_FLAG_WRITE_ZIP64 = 0x4000, /* always use the zip64 file format, instead of the original zip file format with automatic switch to zip64. Use as flags parameter with mz_zip_writer_init*_v2 */
|
||||||
|
MZ_ZIP_FLAG_WRITE_ALLOW_READING = 0x8000,
|
||||||
|
MZ_ZIP_FLAG_ASCII_FILENAME = 0x10000,
|
||||||
|
/*After adding a compressed file, seek back
|
||||||
|
to local file header and set the correct sizes*/
|
||||||
|
MZ_ZIP_FLAG_WRITE_HEADER_SET_SIZE = 0x20000,
|
||||||
|
MZ_ZIP_FLAG_READ_ALLOW_WRITING = 0x40000
|
||||||
|
} mz_zip_flags;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
MZ_ZIP_TYPE_INVALID = 0,
|
||||||
|
MZ_ZIP_TYPE_USER,
|
||||||
|
MZ_ZIP_TYPE_MEMORY,
|
||||||
|
MZ_ZIP_TYPE_HEAP,
|
||||||
|
MZ_ZIP_TYPE_FILE,
|
||||||
|
MZ_ZIP_TYPE_CFILE,
|
||||||
|
MZ_ZIP_TOTAL_TYPES
|
||||||
|
} mz_zip_type;
|
||||||
|
|
||||||
|
/* miniz error codes. Be sure to update mz_zip_get_error_string() if you add or modify this enum. */
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
MZ_ZIP_NO_ERROR = 0,
|
||||||
|
MZ_ZIP_UNDEFINED_ERROR,
|
||||||
|
MZ_ZIP_TOO_MANY_FILES,
|
||||||
|
MZ_ZIP_FILE_TOO_LARGE,
|
||||||
|
MZ_ZIP_UNSUPPORTED_METHOD,
|
||||||
|
MZ_ZIP_UNSUPPORTED_ENCRYPTION,
|
||||||
|
MZ_ZIP_UNSUPPORTED_FEATURE,
|
||||||
|
MZ_ZIP_FAILED_FINDING_CENTRAL_DIR,
|
||||||
|
MZ_ZIP_NOT_AN_ARCHIVE,
|
||||||
|
MZ_ZIP_INVALID_HEADER_OR_CORRUPTED,
|
||||||
|
MZ_ZIP_UNSUPPORTED_MULTIDISK,
|
||||||
|
MZ_ZIP_DECOMPRESSION_FAILED,
|
||||||
|
MZ_ZIP_COMPRESSION_FAILED,
|
||||||
|
MZ_ZIP_UNEXPECTED_DECOMPRESSED_SIZE,
|
||||||
|
MZ_ZIP_CRC_CHECK_FAILED,
|
||||||
|
MZ_ZIP_UNSUPPORTED_CDIR_SIZE,
|
||||||
|
MZ_ZIP_ALLOC_FAILED,
|
||||||
|
MZ_ZIP_FILE_OPEN_FAILED,
|
||||||
|
MZ_ZIP_FILE_CREATE_FAILED,
|
||||||
|
MZ_ZIP_FILE_WRITE_FAILED,
|
||||||
|
MZ_ZIP_FILE_READ_FAILED,
|
||||||
|
MZ_ZIP_FILE_CLOSE_FAILED,
|
||||||
|
MZ_ZIP_FILE_SEEK_FAILED,
|
||||||
|
MZ_ZIP_FILE_STAT_FAILED,
|
||||||
|
MZ_ZIP_INVALID_PARAMETER,
|
||||||
|
MZ_ZIP_INVALID_FILENAME,
|
||||||
|
MZ_ZIP_BUF_TOO_SMALL,
|
||||||
|
MZ_ZIP_INTERNAL_ERROR,
|
||||||
|
MZ_ZIP_FILE_NOT_FOUND,
|
||||||
|
MZ_ZIP_ARCHIVE_TOO_LARGE,
|
||||||
|
MZ_ZIP_VALIDATION_FAILED,
|
||||||
|
MZ_ZIP_WRITE_CALLBACK_FAILED,
|
||||||
|
MZ_ZIP_TOTAL_ERRORS
|
||||||
|
} mz_zip_error;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
mz_uint64 m_archive_size;
|
||||||
|
mz_uint64 m_central_directory_file_ofs;
|
||||||
|
|
||||||
|
/* We only support up to UINT32_MAX files in zip64 mode. */
|
||||||
|
mz_uint32 m_total_files;
|
||||||
|
mz_zip_mode m_zip_mode;
|
||||||
|
mz_zip_type m_zip_type;
|
||||||
|
mz_zip_error m_last_error;
|
||||||
|
|
||||||
|
mz_uint64 m_file_offset_alignment;
|
||||||
|
|
||||||
|
mz_alloc_func m_pAlloc;
|
||||||
|
mz_free_func m_pFree;
|
||||||
|
mz_realloc_func m_pRealloc;
|
||||||
|
void *m_pAlloc_opaque;
|
||||||
|
|
||||||
|
mz_file_read_func m_pRead;
|
||||||
|
mz_file_write_func m_pWrite;
|
||||||
|
mz_file_needs_keepalive m_pNeeds_keepalive;
|
||||||
|
void *m_pIO_opaque;
|
||||||
|
|
||||||
|
mz_zip_internal_state *m_pState;
|
||||||
|
|
||||||
|
} mz_zip_archive;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
mz_zip_archive *pZip;
|
||||||
|
mz_uint flags;
|
||||||
|
|
||||||
|
int status;
|
||||||
|
|
||||||
|
mz_uint64 read_buf_size, read_buf_ofs, read_buf_avail, comp_remaining, out_buf_ofs, cur_file_ofs;
|
||||||
|
mz_zip_archive_file_stat file_stat;
|
||||||
|
void *pRead_buf;
|
||||||
|
void *pWrite_buf;
|
||||||
|
|
||||||
|
size_t out_blk_remain;
|
||||||
|
|
||||||
|
tinfl_decompressor inflator;
|
||||||
|
|
||||||
|
#ifdef MINIZ_DISABLE_ZIP_READER_CRC32_CHECKS
|
||||||
|
mz_uint padding;
|
||||||
|
#else
|
||||||
|
mz_uint file_crc32;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} mz_zip_reader_extract_iter_state;
|
||||||
|
|
||||||
|
/* -------- ZIP reading */
|
||||||
|
|
||||||
|
/* Inits a ZIP archive reader. */
|
||||||
|
/* These functions read and validate the archive's central directory. */
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_reader_init(mz_zip_archive *pZip, mz_uint64 size, mz_uint flags);
|
||||||
|
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_reader_init_mem(mz_zip_archive *pZip, const void *pMem, size_t size, mz_uint flags);
|
||||||
|
|
||||||
|
#ifndef MINIZ_NO_STDIO
|
||||||
|
/* Read a archive from a disk file. */
|
||||||
|
/* file_start_ofs is the file offset where the archive actually begins, or 0. */
|
||||||
|
/* actual_archive_size is the true total size of the archive, which may be smaller than the file's actual size on disk. If zero the entire file is treated as the archive. */
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_reader_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint32 flags);
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_reader_init_file_v2(mz_zip_archive *pZip, const char *pFilename, mz_uint flags, mz_uint64 file_start_ofs, mz_uint64 archive_size);
|
||||||
|
|
||||||
|
/* Read an archive from an already opened FILE, beginning at the current file position. */
|
||||||
|
/* The archive is assumed to be archive_size bytes long. If archive_size is 0, then the entire rest of the file is assumed to contain the archive. */
|
||||||
|
/* The FILE will NOT be closed when mz_zip_reader_end() is called. */
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_reader_init_cfile(mz_zip_archive *pZip, MZ_FILE *pFile, mz_uint64 archive_size, mz_uint flags);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Ends archive reading, freeing all allocations, and closing the input archive file if mz_zip_reader_init_file() was used. */
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_reader_end(mz_zip_archive *pZip);
|
||||||
|
|
||||||
|
/* -------- ZIP reading or writing */
|
||||||
|
|
||||||
|
/* Clears a mz_zip_archive struct to all zeros. */
|
||||||
|
/* Important: This must be done before passing the struct to any mz_zip functions. */
|
||||||
|
MINIZ_EXPORT void mz_zip_zero_struct(mz_zip_archive *pZip);
|
||||||
|
|
||||||
|
MINIZ_EXPORT mz_zip_mode mz_zip_get_mode(mz_zip_archive *pZip);
|
||||||
|
MINIZ_EXPORT mz_zip_type mz_zip_get_type(mz_zip_archive *pZip);
|
||||||
|
|
||||||
|
/* Returns the total number of files in the archive. */
|
||||||
|
MINIZ_EXPORT mz_uint mz_zip_reader_get_num_files(mz_zip_archive *pZip);
|
||||||
|
|
||||||
|
MINIZ_EXPORT mz_uint64 mz_zip_get_archive_size(mz_zip_archive *pZip);
|
||||||
|
MINIZ_EXPORT mz_uint64 mz_zip_get_archive_file_start_offset(mz_zip_archive *pZip);
|
||||||
|
MINIZ_EXPORT MZ_FILE *mz_zip_get_cfile(mz_zip_archive *pZip);
|
||||||
|
|
||||||
|
/* Reads n bytes of raw archive data, starting at file offset file_ofs, to pBuf. */
|
||||||
|
MINIZ_EXPORT size_t mz_zip_read_archive_data(mz_zip_archive *pZip, mz_uint64 file_ofs, void *pBuf, size_t n);
|
||||||
|
|
||||||
|
/* All mz_zip funcs set the m_last_error field in the mz_zip_archive struct. These functions retrieve/manipulate this field. */
|
||||||
|
/* Note that the m_last_error functionality is not thread safe. */
|
||||||
|
MINIZ_EXPORT mz_zip_error mz_zip_set_last_error(mz_zip_archive *pZip, mz_zip_error err_num);
|
||||||
|
MINIZ_EXPORT mz_zip_error mz_zip_peek_last_error(mz_zip_archive *pZip);
|
||||||
|
MINIZ_EXPORT mz_zip_error mz_zip_clear_last_error(mz_zip_archive *pZip);
|
||||||
|
MINIZ_EXPORT mz_zip_error mz_zip_get_last_error(mz_zip_archive *pZip);
|
||||||
|
MINIZ_EXPORT const char *mz_zip_get_error_string(mz_zip_error mz_err);
|
||||||
|
|
||||||
|
/* MZ_TRUE if the archive file entry is a directory entry. */
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_reader_is_file_a_directory(mz_zip_archive *pZip, mz_uint file_index);
|
||||||
|
|
||||||
|
/* MZ_TRUE if the file is encrypted/strong encrypted. */
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_reader_is_file_encrypted(mz_zip_archive *pZip, mz_uint file_index);
|
||||||
|
|
||||||
|
/* MZ_TRUE if the compression method is supported, and the file is not encrypted, and the file is not a compressed patch file. */
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_reader_is_file_supported(mz_zip_archive *pZip, mz_uint file_index);
|
||||||
|
|
||||||
|
/* Retrieves the filename of an archive file entry. */
|
||||||
|
/* Returns the number of bytes written to pFilename, or if filename_buf_size is 0 this function returns the number of bytes needed to fully store the filename. */
|
||||||
|
MINIZ_EXPORT mz_uint mz_zip_reader_get_filename(mz_zip_archive *pZip, mz_uint file_index, char *pFilename, mz_uint filename_buf_size);
|
||||||
|
|
||||||
|
/* Attempts to locates a file in the archive's central directory. */
|
||||||
|
/* Valid flags: MZ_ZIP_FLAG_CASE_SENSITIVE, MZ_ZIP_FLAG_IGNORE_PATH */
|
||||||
|
/* Returns -1 if the file cannot be found. */
|
||||||
|
MINIZ_EXPORT int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags);
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_reader_locate_file_v2(mz_zip_archive *pZip, const char *pName, const char *pComment, mz_uint flags, mz_uint32 *file_index);
|
||||||
|
|
||||||
|
/* Returns detailed information about an archive file entry. */
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_reader_file_stat(mz_zip_archive *pZip, mz_uint file_index, mz_zip_archive_file_stat *pStat);
|
||||||
|
|
||||||
|
/* MZ_TRUE if the file is in zip64 format. */
|
||||||
|
/* A file is considered zip64 if it contained a zip64 end of central directory marker, or if it contained any zip64 extended file information fields in the central directory. */
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_is_zip64(mz_zip_archive *pZip);
|
||||||
|
|
||||||
|
/* Returns the total central directory size in bytes. */
|
||||||
|
/* The current max supported size is <= MZ_UINT32_MAX. */
|
||||||
|
MINIZ_EXPORT size_t mz_zip_get_central_dir_size(mz_zip_archive *pZip);
|
||||||
|
|
||||||
|
/* Extracts a archive file to a memory buffer using no memory allocation. */
|
||||||
|
/* There must be at least enough room on the stack to store the inflator's state (~34KB or so). */
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size);
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_reader_extract_file_to_mem_no_alloc(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size);
|
||||||
|
|
||||||
|
/* Extracts a archive file to a memory buffer. */
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_reader_extract_to_mem(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags);
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_reader_extract_file_to_mem(mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size, mz_uint flags);
|
||||||
|
|
||||||
|
/* Extracts a archive file to a dynamically allocated heap buffer. */
|
||||||
|
/* The memory will be allocated via the mz_zip_archive's alloc/realloc functions. */
|
||||||
|
/* Returns NULL and sets the last error on failure. */
|
||||||
|
MINIZ_EXPORT void *mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index, size_t *pSize, mz_uint flags);
|
||||||
|
MINIZ_EXPORT void *mz_zip_reader_extract_file_to_heap(mz_zip_archive *pZip, const char *pFilename, size_t *pSize, mz_uint flags);
|
||||||
|
|
||||||
|
/* Extracts a archive file using a callback function to output the file's data. */
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive *pZip, mz_uint file_index, mz_file_write_func pCallback, void *pOpaque, mz_uint flags);
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_reader_extract_file_to_callback(mz_zip_archive *pZip, const char *pFilename, mz_file_write_func pCallback, void *pOpaque, mz_uint flags);
|
||||||
|
|
||||||
|
/* Extract a file iteratively */
|
||||||
|
MINIZ_EXPORT mz_zip_reader_extract_iter_state *mz_zip_reader_extract_iter_new(mz_zip_archive *pZip, mz_uint file_index, mz_uint flags);
|
||||||
|
MINIZ_EXPORT mz_zip_reader_extract_iter_state *mz_zip_reader_extract_file_iter_new(mz_zip_archive *pZip, const char *pFilename, mz_uint flags);
|
||||||
|
MINIZ_EXPORT size_t mz_zip_reader_extract_iter_read(mz_zip_reader_extract_iter_state *pState, void *pvBuf, size_t buf_size);
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_reader_extract_iter_free(mz_zip_reader_extract_iter_state *pState);
|
||||||
|
|
||||||
|
#ifndef MINIZ_NO_STDIO
|
||||||
|
/* Extracts a archive file to a disk file and sets its last accessed and modified times. */
|
||||||
|
/* This function only extracts files, not archive directory records. */
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_reader_extract_to_file(mz_zip_archive *pZip, mz_uint file_index, const char *pDst_filename, mz_uint flags);
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_reader_extract_file_to_file(mz_zip_archive *pZip, const char *pArchive_filename, const char *pDst_filename, mz_uint flags);
|
||||||
|
|
||||||
|
/* Extracts a archive file starting at the current position in the destination FILE stream. */
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_reader_extract_to_cfile(mz_zip_archive *pZip, mz_uint file_index, MZ_FILE *File, mz_uint flags);
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_reader_extract_file_to_cfile(mz_zip_archive *pZip, const char *pArchive_filename, MZ_FILE *pFile, mz_uint flags);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* TODO */
|
||||||
|
typedef void *mz_zip_streaming_extract_state_ptr;
|
||||||
|
mz_zip_streaming_extract_state_ptr mz_zip_streaming_extract_begin(mz_zip_archive *pZip, mz_uint file_index, mz_uint flags);
|
||||||
|
mz_uint64 mz_zip_streaming_extract_get_size(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState);
|
||||||
|
mz_uint64 mz_zip_streaming_extract_get_cur_ofs(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState);
|
||||||
|
mz_bool mz_zip_streaming_extract_seek(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState, mz_uint64 new_ofs);
|
||||||
|
size_t mz_zip_streaming_extract_read(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState, void *pBuf, size_t buf_size);
|
||||||
|
mz_bool mz_zip_streaming_extract_end(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* This function compares the archive's local headers, the optional local zip64 extended information block, and the optional descriptor following the compressed data vs. the data in the central directory. */
|
||||||
|
/* It also validates that each file can be successfully uncompressed unless the MZ_ZIP_FLAG_VALIDATE_HEADERS_ONLY is specified. */
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_validate_file(mz_zip_archive *pZip, mz_uint file_index, mz_uint flags);
|
||||||
|
|
||||||
|
/* Validates an entire archive by calling mz_zip_validate_file() on each file. */
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_validate_archive(mz_zip_archive *pZip, mz_uint flags);
|
||||||
|
|
||||||
|
/* Misc utils/helpers, valid for ZIP reading or writing */
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_validate_mem_archive(const void *pMem, size_t size, mz_uint flags, mz_zip_error *pErr);
|
||||||
|
#ifndef MINIZ_NO_STDIO
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_validate_file_archive(const char *pFilename, mz_uint flags, mz_zip_error *pErr);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Universal end function - calls either mz_zip_reader_end() or mz_zip_writer_end(). */
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_end(mz_zip_archive *pZip);
|
||||||
|
|
||||||
|
/* -------- ZIP writing */
|
||||||
|
|
||||||
|
#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
|
||||||
|
|
||||||
|
/* Inits a ZIP archive writer. */
|
||||||
|
/*Set pZip->m_pWrite (and pZip->m_pIO_opaque) before calling mz_zip_writer_init or mz_zip_writer_init_v2*/
|
||||||
|
/*The output is streamable, i.e. file_ofs in mz_file_write_func always increases only by n*/
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_writer_init(mz_zip_archive *pZip, mz_uint64 existing_size);
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_writer_init_v2(mz_zip_archive *pZip, mz_uint64 existing_size, mz_uint flags);
|
||||||
|
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_writer_init_heap(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size);
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_writer_init_heap_v2(mz_zip_archive *pZip, size_t size_to_reserve_at_beginning, size_t initial_allocation_size, mz_uint flags);
|
||||||
|
|
||||||
|
#ifndef MINIZ_NO_STDIO
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_writer_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint64 size_to_reserve_at_beginning);
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_writer_init_file_v2(mz_zip_archive *pZip, const char *pFilename, mz_uint64 size_to_reserve_at_beginning, mz_uint flags);
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_writer_init_cfile(mz_zip_archive *pZip, MZ_FILE *pFile, mz_uint flags);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Converts a ZIP archive reader object into a writer object, to allow efficient in-place file appends to occur on an existing archive. */
|
||||||
|
/* For archives opened using mz_zip_reader_init_file, pFilename must be the archive's filename so it can be reopened for writing. If the file can't be reopened, mz_zip_reader_end() will be called. */
|
||||||
|
/* For archives opened using mz_zip_reader_init_mem, the memory block must be growable using the realloc callback (which defaults to realloc unless you've overridden it). */
|
||||||
|
/* Finally, for archives opened using mz_zip_reader_init, the mz_zip_archive's user provided m_pWrite function cannot be NULL. */
|
||||||
|
/* Note: In-place archive modification is not recommended unless you know what you're doing, because if execution stops or something goes wrong before */
|
||||||
|
/* the archive is finalized the file's central directory will be hosed. */
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_writer_init_from_reader(mz_zip_archive *pZip, const char *pFilename);
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_writer_init_from_reader_v2(mz_zip_archive *pZip, const char *pFilename, mz_uint flags);
|
||||||
|
|
||||||
|
/* Adds the contents of a memory buffer to an archive. These functions record the current local time into the archive. */
|
||||||
|
/* To add a directory entry, call this method with an archive name ending in a forwardslash with an empty buffer. */
|
||||||
|
/* level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION. */
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_writer_add_mem(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, mz_uint level_and_flags);
|
||||||
|
|
||||||
|
/* Like mz_zip_writer_add_mem(), except you can specify a file comment field, and optionally supply the function with already compressed data. */
|
||||||
|
/* uncomp_size/uncomp_crc32 are only used if the MZ_ZIP_FLAG_COMPRESSED_DATA flag is specified. */
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags,
|
||||||
|
mz_uint64 uncomp_size, mz_uint32 uncomp_crc32);
|
||||||
|
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags,
|
||||||
|
mz_uint64 uncomp_size, mz_uint32 uncomp_crc32, MZ_TIME_T *last_modified, const char *user_extra_data_local, mz_uint user_extra_data_local_len,
|
||||||
|
const char *user_extra_data_central, mz_uint user_extra_data_central_len);
|
||||||
|
|
||||||
|
/* Adds the contents of a file to an archive. This function also records the disk file's modified time into the archive. */
|
||||||
|
/* File data is supplied via a read callback function. User mz_zip_writer_add_(c)file to add a file directly.*/
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pArchive_name, mz_file_read_func read_callback, void *callback_opaque, mz_uint64 max_size,
|
||||||
|
const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, const char *user_extra_data_local, mz_uint user_extra_data_local_len,
|
||||||
|
const char *user_extra_data_central, mz_uint user_extra_data_central_len);
|
||||||
|
|
||||||
|
#ifndef MINIZ_NO_STDIO
|
||||||
|
/* Adds the contents of a disk file to an archive. This function also records the disk file's modified time into the archive. */
|
||||||
|
/* level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION. */
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, const char *pSrc_filename, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags);
|
||||||
|
|
||||||
|
/* Like mz_zip_writer_add_file(), except the file data is read from the specified FILE stream. */
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_writer_add_cfile(mz_zip_archive *pZip, const char *pArchive_name, MZ_FILE *pSrc_file, mz_uint64 max_size,
|
||||||
|
const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, const char *user_extra_data_local, mz_uint user_extra_data_local_len,
|
||||||
|
const char *user_extra_data_central, mz_uint user_extra_data_central_len);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Adds a file to an archive by fully cloning the data from another archive. */
|
||||||
|
/* This function fully clones the source file's compressed data (no recompression), along with its full filename, extra data (it may add or modify the zip64 local header extra data field), and the optional descriptor following the compressed data. */
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, mz_zip_archive *pSource_zip, mz_uint src_file_index);
|
||||||
|
|
||||||
|
/* Finalizes the archive by writing the central directory records followed by the end of central directory record. */
|
||||||
|
/* After an archive is finalized, the only valid call on the mz_zip_archive struct is mz_zip_writer_end(). */
|
||||||
|
/* An archive must be manually finalized by calling this function for it to be valid. */
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_writer_finalize_archive(mz_zip_archive *pZip);
|
||||||
|
|
||||||
|
/* Finalizes a heap archive, returning a pointer to the heap block and its size. */
|
||||||
|
/* The heap block will be allocated using the mz_zip_archive's alloc/realloc callbacks. */
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_writer_finalize_heap_archive(mz_zip_archive *pZip, void **ppBuf, size_t *pSize);
|
||||||
|
|
||||||
|
/* Ends archive writing, freeing all allocations, and closing the output file if mz_zip_writer_init_file() was used. */
|
||||||
|
/* Note for the archive to be valid, it *must* have been finalized before ending (this function will not do it for you). */
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_writer_end(mz_zip_archive *pZip);
|
||||||
|
|
||||||
|
/* -------- Misc. high-level helper functions: */
|
||||||
|
|
||||||
|
/* mz_zip_add_mem_to_archive_file_in_place() efficiently (but not atomically) appends a memory blob to a ZIP archive. */
|
||||||
|
/* Note this is NOT a fully safe operation. If it crashes or dies in some way your archive can be left in a screwed up state (without a central directory). */
|
||||||
|
/* level_and_flags - compression level (0-10, see MZ_BEST_SPEED, MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or just set to MZ_DEFAULT_COMPRESSION. */
|
||||||
|
/* TODO: Perhaps add an option to leave the existing central dir in place in case the add dies? We could then truncate the file (so the old central dir would be at the end) if something goes wrong. */
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags);
|
||||||
|
MINIZ_EXPORT mz_bool mz_zip_add_mem_to_archive_file_in_place_v2(const char *pZip_filename, const char *pArchive_name, const void *pBuf, size_t buf_size, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, mz_zip_error *pErr);
|
||||||
|
|
||||||
|
#ifndef MINIZ_NO_STDIO
|
||||||
|
/* Reads a single file from an archive into a heap block. */
|
||||||
|
/* If pComment is not NULL, only the file with the specified comment will be extracted. */
|
||||||
|
/* Returns NULL on failure. */
|
||||||
|
MINIZ_EXPORT void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const char *pArchive_name, size_t *pSize, mz_uint flags);
|
||||||
|
MINIZ_EXPORT void *mz_zip_extract_archive_file_to_heap_v2(const char *pZip_filename, const char *pArchive_name, const char *pComment, size_t *pSize, mz_uint flags, mz_zip_error *pErr);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* MINIZ_NO_ARCHIVE_APIS */
|
||||||
41
libs/qrcode/BitBuffer.cpp
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* QR Code generator library (C++)
|
||||||
|
*
|
||||||
|
* Copyright (c) Project Nayuki. (MIT License)
|
||||||
|
* https://www.nayuki.io/page/qr-code-generator-library
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
#include "BitBuffer.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
namespace qrcodegen {
|
||||||
|
|
||||||
|
BitBuffer::BitBuffer()
|
||||||
|
: std::vector<bool>() {}
|
||||||
|
|
||||||
|
|
||||||
|
void BitBuffer::appendBits(std::uint32_t val, int len) {
|
||||||
|
if (len < 0 || len > 31 || val >> len != 0)
|
||||||
|
throw std::domain_error("Value out of range");
|
||||||
|
for (int i = len - 1; i >= 0; i--) // Append bit by bit
|
||||||
|
this->push_back(((val >> i) & 1) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
52
libs/qrcode/BitBuffer.hpp
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* QR Code generator library (C++)
|
||||||
|
*
|
||||||
|
* Copyright (c) Project Nayuki. (MIT License)
|
||||||
|
* https://www.nayuki.io/page/qr-code-generator-library
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
|
namespace qrcodegen {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* An appendable sequence of bits (0s and 1s). Mainly used by QrSegment.
|
||||||
|
*/
|
||||||
|
class BitBuffer final : public std::vector<bool> {
|
||||||
|
|
||||||
|
/*---- Constructor ----*/
|
||||||
|
|
||||||
|
// Creates an empty bit buffer (length 0).
|
||||||
|
public: BitBuffer();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*---- Method ----*/
|
||||||
|
|
||||||
|
// Appends the given number of low-order bits of the given value
|
||||||
|
// to this buffer. Requires 0 <= len <= 31 and val < 2^len.
|
||||||
|
public: void appendBits(std::uint32_t val, int len);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
620
libs/qrcode/QrCode.cpp
Normal file
@@ -0,0 +1,620 @@
|
|||||||
|
/*
|
||||||
|
* QR Code generator library (C++)
|
||||||
|
*
|
||||||
|
* Copyright (c) Project Nayuki. (MIT License)
|
||||||
|
* https://www.nayuki.io/page/qr-code-generator-library
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <climits>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <sstream>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <utility>
|
||||||
|
#include "BitBuffer.hpp"
|
||||||
|
#include "QrCode.hpp"
|
||||||
|
|
||||||
|
using std::int8_t;
|
||||||
|
using std::uint8_t;
|
||||||
|
using std::size_t;
|
||||||
|
using std::vector;
|
||||||
|
|
||||||
|
|
||||||
|
namespace qrcodegen {
|
||||||
|
|
||||||
|
int QrCode::getFormatBits(Ecc ecl) {
|
||||||
|
switch (ecl) {
|
||||||
|
case Ecc::LOW : return 1;
|
||||||
|
case Ecc::MEDIUM : return 0;
|
||||||
|
case Ecc::QUARTILE: return 3;
|
||||||
|
case Ecc::HIGH : return 2;
|
||||||
|
default: throw std::logic_error("Assertion error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QrCode QrCode::encodeText(const char *text, Ecc ecl) {
|
||||||
|
vector<QrSegment> segs = QrSegment::makeSegments(text);
|
||||||
|
return encodeSegments(segs, ecl);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QrCode QrCode::encodeBinary(const vector<uint8_t> &data, Ecc ecl) {
|
||||||
|
vector<QrSegment> segs{QrSegment::makeBytes(data)};
|
||||||
|
return encodeSegments(segs, ecl);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QrCode QrCode::encodeSegments(const vector<QrSegment> &segs, Ecc ecl,
|
||||||
|
int minVersion, int maxVersion, int mask, bool boostEcl) {
|
||||||
|
if (!(MIN_VERSION <= minVersion && minVersion <= maxVersion && maxVersion <= MAX_VERSION) || mask < -1 || mask > 7)
|
||||||
|
throw std::invalid_argument("Invalid value");
|
||||||
|
|
||||||
|
// Find the minimal version number to use
|
||||||
|
int version, dataUsedBits;
|
||||||
|
for (version = minVersion; ; version++) {
|
||||||
|
int dataCapacityBits = getNumDataCodewords(version, ecl) * 8; // Number of data bits available
|
||||||
|
dataUsedBits = QrSegment::getTotalBits(segs, version);
|
||||||
|
if (dataUsedBits != -1 && dataUsedBits <= dataCapacityBits)
|
||||||
|
break; // This version number is found to be suitable
|
||||||
|
if (version >= maxVersion) // All versions in the range could not fit the given data
|
||||||
|
throw std::length_error("Data too long");
|
||||||
|
}
|
||||||
|
if (dataUsedBits == -1)
|
||||||
|
throw std::logic_error("Assertion error");
|
||||||
|
|
||||||
|
// Increase the error correction level while the data still fits in the current version number
|
||||||
|
for (Ecc newEcl : vector<Ecc>{Ecc::MEDIUM, Ecc::QUARTILE, Ecc::HIGH}) { // From low to high
|
||||||
|
if (boostEcl && dataUsedBits <= getNumDataCodewords(version, newEcl) * 8)
|
||||||
|
ecl = newEcl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Concatenate all segments to create the data bit string
|
||||||
|
BitBuffer bb;
|
||||||
|
for (const QrSegment &seg : segs) {
|
||||||
|
bb.appendBits(seg.getMode().getModeBits(), 4);
|
||||||
|
bb.appendBits(seg.getNumChars(), seg.getMode().numCharCountBits(version));
|
||||||
|
bb.insert(bb.end(), seg.getData().begin(), seg.getData().end());
|
||||||
|
}
|
||||||
|
if (bb.size() != static_cast<unsigned int>(dataUsedBits))
|
||||||
|
throw std::logic_error("Assertion error");
|
||||||
|
|
||||||
|
// Add terminator and pad up to a byte if applicable
|
||||||
|
size_t dataCapacityBits = getNumDataCodewords(version, ecl) * 8;
|
||||||
|
if (bb.size() > dataCapacityBits)
|
||||||
|
throw std::logic_error("Assertion error");
|
||||||
|
bb.appendBits(0, std::min<size_t>(4, dataCapacityBits - bb.size()));
|
||||||
|
bb.appendBits(0, (8 - bb.size() % 8) % 8);
|
||||||
|
if (bb.size() % 8 != 0)
|
||||||
|
throw std::logic_error("Assertion error");
|
||||||
|
|
||||||
|
// Pad with alternating bytes until data capacity is reached
|
||||||
|
for (uint8_t padByte = 0xEC; bb.size() < dataCapacityBits; padByte ^= 0xEC ^ 0x11)
|
||||||
|
bb.appendBits(padByte, 8);
|
||||||
|
|
||||||
|
// Pack bits into bytes in big endian
|
||||||
|
vector<uint8_t> dataCodewords(bb.size() / 8);
|
||||||
|
for (size_t i = 0; i < bb.size(); i++)
|
||||||
|
dataCodewords[i >> 3] |= (bb.at(i) ? 1 : 0) << (7 - (i & 7));
|
||||||
|
|
||||||
|
// Create the QR Code object
|
||||||
|
return QrCode(version, ecl, dataCodewords, mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QrCode::QrCode(int ver, Ecc ecl, const vector<uint8_t> &dataCodewords, int mask) :
|
||||||
|
// Initialize fields and check arguments
|
||||||
|
version(ver),
|
||||||
|
errorCorrectionLevel(ecl) {
|
||||||
|
if (ver < MIN_VERSION || ver > MAX_VERSION)
|
||||||
|
throw std::domain_error("Version value out of range");
|
||||||
|
if (mask < -1 || mask > 7)
|
||||||
|
throw std::domain_error("Mask value out of range");
|
||||||
|
size = ver * 4 + 17;
|
||||||
|
modules = vector<vector<bool> >(size, vector<bool>(size)); // Initially all white
|
||||||
|
isFunction = vector<vector<bool> >(size, vector<bool>(size));
|
||||||
|
|
||||||
|
// Compute ECC, draw modules, do masking
|
||||||
|
drawFunctionPatterns();
|
||||||
|
const vector<uint8_t> allCodewords = addEccAndInterleave(dataCodewords);
|
||||||
|
drawCodewords(allCodewords);
|
||||||
|
this->mask = handleConstructorMasking(mask);
|
||||||
|
isFunction.clear();
|
||||||
|
isFunction.shrink_to_fit();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int QrCode::getVersion() const {
|
||||||
|
return version;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int QrCode::getSize() const {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QrCode::Ecc QrCode::getErrorCorrectionLevel() const {
|
||||||
|
return errorCorrectionLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int QrCode::getMask() const {
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool QrCode::getModule(int x, int y) const {
|
||||||
|
return 0 <= x && x < size && 0 <= y && y < size && module(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string QrCode::toSvgString(int border) const {
|
||||||
|
if (border < 0)
|
||||||
|
throw std::domain_error("Border must be non-negative");
|
||||||
|
if (border > INT_MAX / 2 || border * 2 > INT_MAX - size)
|
||||||
|
throw std::overflow_error("Border too large");
|
||||||
|
|
||||||
|
std::ostringstream sb;
|
||||||
|
sb << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
|
||||||
|
sb << "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n";
|
||||||
|
sb << "<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" viewBox=\"0 0 ";
|
||||||
|
sb << (size + border * 2) << " " << (size + border * 2) << "\" stroke=\"none\">\n";
|
||||||
|
sb << "\t<rect width=\"100%\" height=\"100%\" fill=\"#FFFFFF\"/>\n";
|
||||||
|
sb << "\t<path d=\"";
|
||||||
|
for (int y = 0; y < size; y++) {
|
||||||
|
for (int x = 0; x < size; x++) {
|
||||||
|
if (getModule(x, y)) {
|
||||||
|
if (x != 0 || y != 0)
|
||||||
|
sb << " ";
|
||||||
|
sb << "M" << (x + border) << "," << (y + border) << "h1v1h-1z";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sb << "\" fill=\"#000000\"/>\n";
|
||||||
|
sb << "</svg>\n";
|
||||||
|
return sb.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void QrCode::drawFunctionPatterns() {
|
||||||
|
// Draw horizontal and vertical timing patterns
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
setFunctionModule(6, i, i % 2 == 0);
|
||||||
|
setFunctionModule(i, 6, i % 2 == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw 3 finder patterns (all corners except bottom right; overwrites some timing modules)
|
||||||
|
drawFinderPattern(3, 3);
|
||||||
|
drawFinderPattern(size - 4, 3);
|
||||||
|
drawFinderPattern(3, size - 4);
|
||||||
|
|
||||||
|
// Draw numerous alignment patterns
|
||||||
|
const vector<int> alignPatPos = getAlignmentPatternPositions();
|
||||||
|
int numAlign = alignPatPos.size();
|
||||||
|
for (int i = 0; i < numAlign; i++) {
|
||||||
|
for (int j = 0; j < numAlign; j++) {
|
||||||
|
// Don't draw on the three finder corners
|
||||||
|
if (!((i == 0 && j == 0) || (i == 0 && j == numAlign - 1) || (i == numAlign - 1 && j == 0)))
|
||||||
|
drawAlignmentPattern(alignPatPos.at(i), alignPatPos.at(j));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw configuration data
|
||||||
|
drawFormatBits(0); // Dummy mask value; overwritten later in the constructor
|
||||||
|
drawVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void QrCode::drawFormatBits(int mask) {
|
||||||
|
// Calculate error correction code and pack bits
|
||||||
|
int data = getFormatBits(errorCorrectionLevel) << 3 | mask; // errCorrLvl is uint2, mask is uint3
|
||||||
|
int rem = data;
|
||||||
|
for (int i = 0; i < 10; i++)
|
||||||
|
rem = (rem << 1) ^ ((rem >> 9) * 0x537);
|
||||||
|
int bits = (data << 10 | rem) ^ 0x5412; // uint15
|
||||||
|
if (bits >> 15 != 0)
|
||||||
|
throw std::logic_error("Assertion error");
|
||||||
|
|
||||||
|
// Draw first copy
|
||||||
|
for (int i = 0; i <= 5; i++)
|
||||||
|
setFunctionModule(8, i, getBit(bits, i));
|
||||||
|
setFunctionModule(8, 7, getBit(bits, 6));
|
||||||
|
setFunctionModule(8, 8, getBit(bits, 7));
|
||||||
|
setFunctionModule(7, 8, getBit(bits, 8));
|
||||||
|
for (int i = 9; i < 15; i++)
|
||||||
|
setFunctionModule(14 - i, 8, getBit(bits, i));
|
||||||
|
|
||||||
|
// Draw second copy
|
||||||
|
for (int i = 0; i <= 7; i++)
|
||||||
|
setFunctionModule(size - 1 - i, 8, getBit(bits, i));
|
||||||
|
for (int i = 8; i < 15; i++)
|
||||||
|
setFunctionModule(8, size - 15 + i, getBit(bits, i));
|
||||||
|
setFunctionModule(8, size - 8, true); // Always black
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void QrCode::drawVersion() {
|
||||||
|
if (version < 7)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Calculate error correction code and pack bits
|
||||||
|
int rem = version; // version is uint6, in the range [7, 40]
|
||||||
|
for (int i = 0; i < 12; i++)
|
||||||
|
rem = (rem << 1) ^ ((rem >> 11) * 0x1F25);
|
||||||
|
long bits = (long)version << 12 | rem; // uint18
|
||||||
|
if (bits >> 18 != 0)
|
||||||
|
throw std::logic_error("Assertion error");
|
||||||
|
|
||||||
|
// Draw two copies
|
||||||
|
for (int i = 0; i < 18; i++) {
|
||||||
|
bool bit = getBit(bits, i);
|
||||||
|
int a = size - 11 + i % 3;
|
||||||
|
int b = i / 3;
|
||||||
|
setFunctionModule(a, b, bit);
|
||||||
|
setFunctionModule(b, a, bit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void QrCode::drawFinderPattern(int x, int y) {
|
||||||
|
for (int dy = -4; dy <= 4; dy++) {
|
||||||
|
for (int dx = -4; dx <= 4; dx++) {
|
||||||
|
int dist = std::max(std::abs(dx), std::abs(dy)); // Chebyshev/infinity norm
|
||||||
|
int xx = x + dx, yy = y + dy;
|
||||||
|
if (0 <= xx && xx < size && 0 <= yy && yy < size)
|
||||||
|
setFunctionModule(xx, yy, dist != 2 && dist != 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void QrCode::drawAlignmentPattern(int x, int y) {
|
||||||
|
for (int dy = -2; dy <= 2; dy++) {
|
||||||
|
for (int dx = -2; dx <= 2; dx++)
|
||||||
|
setFunctionModule(x + dx, y + dy, std::max(std::abs(dx), std::abs(dy)) != 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void QrCode::setFunctionModule(int x, int y, bool isBlack) {
|
||||||
|
modules.at(y).at(x) = isBlack;
|
||||||
|
isFunction.at(y).at(x) = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool QrCode::module(int x, int y) const {
|
||||||
|
return modules.at(y).at(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
vector<uint8_t> QrCode::addEccAndInterleave(const vector<uint8_t> &data) const {
|
||||||
|
if (data.size() != static_cast<unsigned int>(getNumDataCodewords(version, errorCorrectionLevel)))
|
||||||
|
throw std::invalid_argument("Invalid argument");
|
||||||
|
|
||||||
|
// Calculate parameter numbers
|
||||||
|
int numBlocks = NUM_ERROR_CORRECTION_BLOCKS[static_cast<int>(errorCorrectionLevel)][version];
|
||||||
|
int blockEccLen = ECC_CODEWORDS_PER_BLOCK [static_cast<int>(errorCorrectionLevel)][version];
|
||||||
|
int rawCodewords = getNumRawDataModules(version) / 8;
|
||||||
|
int numShortBlocks = numBlocks - rawCodewords % numBlocks;
|
||||||
|
int shortBlockLen = rawCodewords / numBlocks;
|
||||||
|
|
||||||
|
// Split data into blocks and append ECC to each block
|
||||||
|
vector<vector<uint8_t> > blocks;
|
||||||
|
const ReedSolomonGenerator rs(blockEccLen);
|
||||||
|
for (int i = 0, k = 0; i < numBlocks; i++) {
|
||||||
|
vector<uint8_t> dat(data.cbegin() + k, data.cbegin() + (k + shortBlockLen - blockEccLen + (i < numShortBlocks ? 0 : 1)));
|
||||||
|
k += dat.size();
|
||||||
|
const vector<uint8_t> ecc = rs.getRemainder(dat);
|
||||||
|
if (i < numShortBlocks)
|
||||||
|
dat.push_back(0);
|
||||||
|
dat.insert(dat.end(), ecc.cbegin(), ecc.cend());
|
||||||
|
blocks.push_back(std::move(dat));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Interleave (not concatenate) the bytes from every block into a single sequence
|
||||||
|
vector<uint8_t> result;
|
||||||
|
for (size_t i = 0; i < blocks.at(0).size(); i++) {
|
||||||
|
for (size_t j = 0; j < blocks.size(); j++) {
|
||||||
|
// Skip the padding byte in short blocks
|
||||||
|
if (i != static_cast<unsigned int>(shortBlockLen - blockEccLen) || j >= static_cast<unsigned int>(numShortBlocks))
|
||||||
|
result.push_back(blocks.at(j).at(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (result.size() != static_cast<unsigned int>(rawCodewords))
|
||||||
|
throw std::logic_error("Assertion error");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void QrCode::drawCodewords(const vector<uint8_t> &data) {
|
||||||
|
if (data.size() != static_cast<unsigned int>(getNumRawDataModules(version) / 8))
|
||||||
|
throw std::invalid_argument("Invalid argument");
|
||||||
|
|
||||||
|
size_t i = 0; // Bit index into the data
|
||||||
|
// Do the funny zigzag scan
|
||||||
|
for (int right = size - 1; right >= 1; right -= 2) { // Index of right column in each column pair
|
||||||
|
if (right == 6)
|
||||||
|
right = 5;
|
||||||
|
for (int vert = 0; vert < size; vert++) { // Vertical counter
|
||||||
|
for (int j = 0; j < 2; j++) {
|
||||||
|
int x = right - j; // Actual x coordinate
|
||||||
|
bool upward = ((right + 1) & 2) == 0;
|
||||||
|
int y = upward ? size - 1 - vert : vert; // Actual y coordinate
|
||||||
|
if (!isFunction.at(y).at(x) && i < data.size() * 8) {
|
||||||
|
modules.at(y).at(x) = getBit(data.at(i >> 3), 7 - static_cast<int>(i & 7));
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
// If this QR Code has any remainder bits (0 to 7), they were assigned as
|
||||||
|
// 0/false/white by the constructor and are left unchanged by this method
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i != data.size() * 8)
|
||||||
|
throw std::logic_error("Assertion error");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void QrCode::applyMask(int mask) {
|
||||||
|
if (mask < 0 || mask > 7)
|
||||||
|
throw std::domain_error("Mask value out of range");
|
||||||
|
for (int y = 0; y < size; y++) {
|
||||||
|
for (int x = 0; x < size; x++) {
|
||||||
|
bool invert;
|
||||||
|
switch (mask) {
|
||||||
|
case 0: invert = (x + y) % 2 == 0; break;
|
||||||
|
case 1: invert = y % 2 == 0; break;
|
||||||
|
case 2: invert = x % 3 == 0; break;
|
||||||
|
case 3: invert = (x + y) % 3 == 0; break;
|
||||||
|
case 4: invert = (x / 3 + y / 2) % 2 == 0; break;
|
||||||
|
case 5: invert = x * y % 2 + x * y % 3 == 0; break;
|
||||||
|
case 6: invert = (x * y % 2 + x * y % 3) % 2 == 0; break;
|
||||||
|
case 7: invert = ((x + y) % 2 + x * y % 3) % 2 == 0; break;
|
||||||
|
default: throw std::logic_error("Assertion error");
|
||||||
|
}
|
||||||
|
modules.at(y).at(x) = modules.at(y).at(x) ^ (invert & !isFunction.at(y).at(x));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int QrCode::handleConstructorMasking(int mask) {
|
||||||
|
if (mask == -1) { // Automatically choose best mask
|
||||||
|
long minPenalty = LONG_MAX;
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
drawFormatBits(i);
|
||||||
|
applyMask(i);
|
||||||
|
long penalty = getPenaltyScore();
|
||||||
|
if (penalty < minPenalty) {
|
||||||
|
mask = i;
|
||||||
|
minPenalty = penalty;
|
||||||
|
}
|
||||||
|
applyMask(i); // Undoes the mask due to XOR
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mask < 0 || mask > 7)
|
||||||
|
throw std::logic_error("Assertion error");
|
||||||
|
drawFormatBits(mask); // Overwrite old format bits
|
||||||
|
applyMask(mask); // Apply the final choice of mask
|
||||||
|
return mask; // The caller shall assign this value to the final-declared field
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long QrCode::getPenaltyScore() const {
|
||||||
|
long result = 0;
|
||||||
|
|
||||||
|
// Adjacent modules in row having same color
|
||||||
|
for (int y = 0; y < size; y++) {
|
||||||
|
bool colorX = false;
|
||||||
|
for (int x = 0, runX = -1; x < size; x++) {
|
||||||
|
if (x == 0 || module(x, y) != colorX) {
|
||||||
|
colorX = module(x, y);
|
||||||
|
runX = 1;
|
||||||
|
} else {
|
||||||
|
runX++;
|
||||||
|
if (runX == 5)
|
||||||
|
result += PENALTY_N1;
|
||||||
|
else if (runX > 5)
|
||||||
|
result++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Adjacent modules in column having same color
|
||||||
|
for (int x = 0; x < size; x++) {
|
||||||
|
bool colorY = false;
|
||||||
|
for (int y = 0, runY = -1; y < size; y++) {
|
||||||
|
if (y == 0 || module(x, y) != colorY) {
|
||||||
|
colorY = module(x, y);
|
||||||
|
runY = 1;
|
||||||
|
} else {
|
||||||
|
runY++;
|
||||||
|
if (runY == 5)
|
||||||
|
result += PENALTY_N1;
|
||||||
|
else if (runY > 5)
|
||||||
|
result++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2*2 blocks of modules having same color
|
||||||
|
for (int y = 0; y < size - 1; y++) {
|
||||||
|
for (int x = 0; x < size - 1; x++) {
|
||||||
|
bool color = module(x, y);
|
||||||
|
if ( color == module(x + 1, y) &&
|
||||||
|
color == module(x, y + 1) &&
|
||||||
|
color == module(x + 1, y + 1))
|
||||||
|
result += PENALTY_N2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finder-like pattern in rows
|
||||||
|
for (int y = 0; y < size; y++) {
|
||||||
|
for (int x = 0, bits = 0; x < size; x++) {
|
||||||
|
bits = ((bits << 1) & 0x7FF) | (module(x, y) ? 1 : 0);
|
||||||
|
if (x >= 10 && (bits == 0x05D || bits == 0x5D0)) // Needs 11 bits accumulated
|
||||||
|
result += PENALTY_N3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Finder-like pattern in columns
|
||||||
|
for (int x = 0; x < size; x++) {
|
||||||
|
for (int y = 0, bits = 0; y < size; y++) {
|
||||||
|
bits = ((bits << 1) & 0x7FF) | (module(x, y) ? 1 : 0);
|
||||||
|
if (y >= 10 && (bits == 0x05D || bits == 0x5D0)) // Needs 11 bits accumulated
|
||||||
|
result += PENALTY_N3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Balance of black and white modules
|
||||||
|
int black = 0;
|
||||||
|
for (const vector<bool> &row : modules) {
|
||||||
|
for (bool color : row) {
|
||||||
|
if (color)
|
||||||
|
black++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int total = size * size; // Note that size is odd, so black/total != 1/2
|
||||||
|
// Compute the smallest integer k >= 0 such that (45-5k)% <= black/total <= (55+5k)%
|
||||||
|
int k = static_cast<int>((std::abs(black * 20L - total * 10L) + total - 1) / total) - 1;
|
||||||
|
result += k * PENALTY_N4;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
vector<int> QrCode::getAlignmentPatternPositions() const {
|
||||||
|
if (version == 1)
|
||||||
|
return vector<int>();
|
||||||
|
else {
|
||||||
|
int numAlign = version / 7 + 2;
|
||||||
|
int step = (version == 32) ? 26 :
|
||||||
|
(version*4 + numAlign*2 + 1) / (numAlign*2 - 2) * 2;
|
||||||
|
vector<int> result;
|
||||||
|
for (int i = 0, pos = size - 7; i < numAlign - 1; i++, pos -= step)
|
||||||
|
result.insert(result.begin(), pos);
|
||||||
|
result.insert(result.begin(), 6);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int QrCode::getNumRawDataModules(int ver) {
|
||||||
|
if (ver < MIN_VERSION || ver > MAX_VERSION)
|
||||||
|
throw std::domain_error("Version number out of range");
|
||||||
|
int result = (16 * ver + 128) * ver + 64;
|
||||||
|
if (ver >= 2) {
|
||||||
|
int numAlign = ver / 7 + 2;
|
||||||
|
result -= (25 * numAlign - 10) * numAlign - 55;
|
||||||
|
if (ver >= 7)
|
||||||
|
result -= 36;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int QrCode::getNumDataCodewords(int ver, Ecc ecl) {
|
||||||
|
return getNumRawDataModules(ver) / 8
|
||||||
|
- ECC_CODEWORDS_PER_BLOCK [static_cast<int>(ecl)][ver]
|
||||||
|
* NUM_ERROR_CORRECTION_BLOCKS[static_cast<int>(ecl)][ver];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool QrCode::getBit(long x, int i) {
|
||||||
|
return ((x >> i) & 1) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*---- Tables of constants ----*/
|
||||||
|
|
||||||
|
const int QrCode::PENALTY_N1 = 3;
|
||||||
|
const int QrCode::PENALTY_N2 = 3;
|
||||||
|
const int QrCode::PENALTY_N3 = 40;
|
||||||
|
const int QrCode::PENALTY_N4 = 10;
|
||||||
|
|
||||||
|
|
||||||
|
const int8_t QrCode::ECC_CODEWORDS_PER_BLOCK[4][41] = {
|
||||||
|
// Version: (note that index 0 is for padding, and is set to an illegal value)
|
||||||
|
//0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 Error correction level
|
||||||
|
{-1, 7, 10, 15, 20, 26, 18, 20, 24, 30, 18, 20, 24, 26, 30, 22, 24, 28, 30, 28, 28, 28, 28, 30, 30, 26, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30}, // Low
|
||||||
|
{-1, 10, 16, 26, 18, 24, 16, 18, 22, 22, 26, 30, 22, 22, 24, 24, 28, 28, 26, 26, 26, 26, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28}, // Medium
|
||||||
|
{-1, 13, 22, 18, 26, 18, 24, 18, 22, 20, 24, 28, 26, 24, 20, 30, 24, 28, 28, 26, 30, 28, 30, 30, 30, 30, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30}, // Quartile
|
||||||
|
{-1, 17, 28, 22, 16, 22, 28, 26, 26, 24, 28, 24, 28, 22, 24, 24, 30, 28, 28, 26, 28, 30, 24, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30}, // High
|
||||||
|
};
|
||||||
|
|
||||||
|
const int8_t QrCode::NUM_ERROR_CORRECTION_BLOCKS[4][41] = {
|
||||||
|
// Version: (note that index 0 is for padding, and is set to an illegal value)
|
||||||
|
//0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 Error correction level
|
||||||
|
{-1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4, 4, 4, 4, 4, 6, 6, 6, 6, 7, 8, 8, 9, 9, 10, 12, 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 24, 25}, // Low
|
||||||
|
{-1, 1, 1, 1, 2, 2, 4, 4, 4, 5, 5, 5, 8, 9, 9, 10, 10, 11, 13, 14, 16, 17, 17, 18, 20, 21, 23, 25, 26, 28, 29, 31, 33, 35, 37, 38, 40, 43, 45, 47, 49}, // Medium
|
||||||
|
{-1, 1, 1, 2, 2, 4, 4, 6, 6, 8, 8, 8, 10, 12, 16, 12, 17, 16, 18, 21, 20, 23, 23, 25, 27, 29, 34, 34, 35, 38, 40, 43, 45, 48, 51, 53, 56, 59, 62, 65, 68}, // Quartile
|
||||||
|
{-1, 1, 1, 2, 4, 4, 4, 5, 6, 8, 8, 11, 11, 16, 16, 18, 16, 19, 21, 25, 25, 25, 34, 30, 32, 35, 37, 40, 42, 45, 48, 51, 54, 57, 60, 63, 66, 70, 74, 77, 81}, // High
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
QrCode::ReedSolomonGenerator::ReedSolomonGenerator(int degree) :
|
||||||
|
coefficients() {
|
||||||
|
if (degree < 1 || degree > 255)
|
||||||
|
throw std::domain_error("Degree out of range");
|
||||||
|
|
||||||
|
// Start with the monomial x^0
|
||||||
|
coefficients.resize(degree);
|
||||||
|
coefficients.at(degree - 1) = 1;
|
||||||
|
|
||||||
|
// Compute the product polynomial (x - r^0) * (x - r^1) * (x - r^2) * ... * (x - r^{degree-1}),
|
||||||
|
// drop the highest term, and store the rest of the coefficients in order of descending powers.
|
||||||
|
// Note that r = 0x02, which is a generator element of this field GF(2^8/0x11D).
|
||||||
|
uint8_t root = 1;
|
||||||
|
for (int i = 0; i < degree; i++) {
|
||||||
|
// Multiply the current product by (x - r^i)
|
||||||
|
for (size_t j = 0; j < coefficients.size(); j++) {
|
||||||
|
coefficients.at(j) = multiply(coefficients.at(j), root);
|
||||||
|
if (j + 1 < coefficients.size())
|
||||||
|
coefficients.at(j) ^= coefficients.at(j + 1);
|
||||||
|
}
|
||||||
|
root = multiply(root, 0x02);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
vector<uint8_t> QrCode::ReedSolomonGenerator::getRemainder(const vector<uint8_t> &data) const {
|
||||||
|
// Compute the remainder by performing polynomial division
|
||||||
|
vector<uint8_t> result(coefficients.size());
|
||||||
|
for (uint8_t b : data) {
|
||||||
|
uint8_t factor = b ^ result.at(0);
|
||||||
|
result.erase(result.begin());
|
||||||
|
result.push_back(0);
|
||||||
|
for (size_t j = 0; j < result.size(); j++)
|
||||||
|
result.at(j) ^= multiply(coefficients.at(j), factor);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t QrCode::ReedSolomonGenerator::multiply(uint8_t x, uint8_t y) {
|
||||||
|
// Russian peasant multiplication
|
||||||
|
int z = 0;
|
||||||
|
for (int i = 7; i >= 0; i--) {
|
||||||
|
z = (z << 1) ^ ((z >> 7) * 0x11D);
|
||||||
|
z ^= ((y >> i) & 1) * x;
|
||||||
|
}
|
||||||
|
if (z >> 8 != 0)
|
||||||
|
throw std::logic_error("Assertion error");
|
||||||
|
return static_cast<uint8_t>(z);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
351
libs/qrcode/QrCode.hpp
Normal file
@@ -0,0 +1,351 @@
|
|||||||
|
/*
|
||||||
|
* QR Code generator library (C++)
|
||||||
|
*
|
||||||
|
* Copyright (c) Project Nayuki. (MIT License)
|
||||||
|
* https://www.nayuki.io/page/qr-code-generator-library
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include "QrSegment.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
namespace qrcodegen {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A QR Code symbol, which is a type of two-dimension barcode.
|
||||||
|
* Invented by Denso Wave and described in the ISO/IEC 18004 standard.
|
||||||
|
* Instances of this class represent an immutable square grid of black and white cells.
|
||||||
|
* The class provides static factory functions to create a QR Code from text or binary data.
|
||||||
|
* The class covers the QR Code Model 2 specification, supporting all versions (sizes)
|
||||||
|
* from 1 to 40, all 4 error correction levels, and 4 character encoding modes.
|
||||||
|
*
|
||||||
|
* Ways to create a QR Code object:
|
||||||
|
* - High level: Take the payload data and call QrCode::encodeText() or QrCode::encodeBinary().
|
||||||
|
* - Mid level: Custom-make the list of segments and call QrCode::encodeSegments().
|
||||||
|
* - Low level: Custom-make the array of data codeword bytes (including
|
||||||
|
* segment headers and final padding, excluding error correction codewords),
|
||||||
|
* supply the appropriate version number, and call the QrCode() constructor.
|
||||||
|
* (Note that all ways require supplying the desired error correction level.)
|
||||||
|
*/
|
||||||
|
class QrCode final {
|
||||||
|
|
||||||
|
/*---- Public helper enumeration ----*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The error correction level in a QR Code symbol.
|
||||||
|
*/
|
||||||
|
public: enum class Ecc {
|
||||||
|
LOW = 0 , // The QR Code can tolerate about 7% erroneous codewords
|
||||||
|
MEDIUM , // The QR Code can tolerate about 15% erroneous codewords
|
||||||
|
QUARTILE, // The QR Code can tolerate about 25% erroneous codewords
|
||||||
|
HIGH , // The QR Code can tolerate about 30% erroneous codewords
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Returns a value in the range 0 to 3 (unsigned 2-bit integer).
|
||||||
|
private: static int getFormatBits(Ecc ecl);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*---- Static factory functions (high level) ----*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a QR Code representing the given Unicode text string at the given error correction level.
|
||||||
|
* As a conservative upper bound, this function is guaranteed to succeed for strings that have 2953 or fewer
|
||||||
|
* UTF-8 code units (not Unicode code points) if the low error correction level is used. The smallest possible
|
||||||
|
* QR Code version is automatically chosen for the output. The ECC level of the result may be higher than
|
||||||
|
* the ecl argument if it can be done without increasing the version.
|
||||||
|
*/
|
||||||
|
public: static QrCode encodeText(const char *text, Ecc ecl);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a QR Code representing the given binary data at the given error correction level.
|
||||||
|
* This function always encodes using the binary segment mode, not any text mode. The maximum number of
|
||||||
|
* bytes allowed is 2953. The smallest possible QR Code version is automatically chosen for the output.
|
||||||
|
* The ECC level of the result may be higher than the ecl argument if it can be done without increasing the version.
|
||||||
|
*/
|
||||||
|
public: static QrCode encodeBinary(const std::vector<std::uint8_t> &data, Ecc ecl);
|
||||||
|
|
||||||
|
|
||||||
|
/*---- Static factory functions (mid level) ----*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a QR Code representing the given segments with the given encoding parameters.
|
||||||
|
* The smallest possible QR Code version within the given range is automatically
|
||||||
|
* chosen for the output. Iff boostEcl is true, then the ECC level of the result
|
||||||
|
* may be higher than the ecl argument if it can be done without increasing the
|
||||||
|
* version. The mask number is either between 0 to 7 (inclusive) to force that
|
||||||
|
* mask, or -1 to automatically choose an appropriate mask (which may be slow).
|
||||||
|
* This function allows the user to create a custom sequence of segments that switches
|
||||||
|
* between modes (such as alphanumeric and byte) to encode text in less space.
|
||||||
|
* This is a mid-level API; the high-level API is encodeText() and encodeBinary().
|
||||||
|
*/
|
||||||
|
public: static QrCode encodeSegments(const std::vector<QrSegment> &segs, Ecc ecl,
|
||||||
|
int minVersion=1, int maxVersion=40, int mask=-1, bool boostEcl=true); // All optional parameters
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*---- Instance fields ----*/
|
||||||
|
|
||||||
|
// Immutable scalar parameters:
|
||||||
|
|
||||||
|
/* The version number of this QR Code, which is between 1 and 40 (inclusive).
|
||||||
|
* This determines the size of this barcode. */
|
||||||
|
private: int version;
|
||||||
|
|
||||||
|
/* The width and height of this QR Code, measured in modules, between
|
||||||
|
* 21 and 177 (inclusive). This is equal to version * 4 + 17. */
|
||||||
|
private: int size;
|
||||||
|
|
||||||
|
/* The error correction level used in this QR Code. */
|
||||||
|
private: Ecc errorCorrectionLevel;
|
||||||
|
|
||||||
|
/* The index of the mask pattern used in this QR Code, which is between 0 and 7 (inclusive).
|
||||||
|
* Even if a QR Code is created with automatic masking requested (mask = -1),
|
||||||
|
* the resulting object still has a mask value between 0 and 7. */
|
||||||
|
private: int mask;
|
||||||
|
|
||||||
|
// Private grids of modules/pixels, with dimensions of size*size:
|
||||||
|
|
||||||
|
// The modules of this QR Code (false = white, true = black).
|
||||||
|
// Immutable after constructor finishes. Accessed through getModule().
|
||||||
|
private: std::vector<std::vector<bool> > modules;
|
||||||
|
|
||||||
|
// Indicates function modules that are not subjected to masking. Discarded when constructor finishes.
|
||||||
|
private: std::vector<std::vector<bool> > isFunction;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*---- Constructor (low level) ----*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Creates a new QR Code with the given version number,
|
||||||
|
* error correction level, data codeword bytes, and mask number.
|
||||||
|
* This is a low-level API that most users should not use directly.
|
||||||
|
* A mid-level API is the encodeSegments() function.
|
||||||
|
*/
|
||||||
|
public: QrCode(int ver, Ecc ecl, const std::vector<std::uint8_t> &dataCodewords, int mask);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*---- Public instance methods ----*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns this QR Code's version, in the range [1, 40].
|
||||||
|
*/
|
||||||
|
public: int getVersion() const;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns this QR Code's size, in the range [21, 177].
|
||||||
|
*/
|
||||||
|
public: int getSize() const;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns this QR Code's error correction level.
|
||||||
|
*/
|
||||||
|
public: Ecc getErrorCorrectionLevel() const;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns this QR Code's mask, in the range [0, 7].
|
||||||
|
*/
|
||||||
|
public: int getMask() const;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the color of the module (pixel) at the given coordinates, which is false
|
||||||
|
* for white or true for black. The top left corner has the coordinates (x=0, y=0).
|
||||||
|
* If the given coordinates are out of bounds, then false (white) is returned.
|
||||||
|
*/
|
||||||
|
public: bool getModule(int x, int y) const;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a string of SVG code for an image depicting this QR Code, with the given number
|
||||||
|
* of border modules. The string always uses Unix newlines (\n), regardless of the platform.
|
||||||
|
*/
|
||||||
|
public: std::string toSvgString(int border) const;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*---- Private helper methods for constructor: Drawing function modules ----*/
|
||||||
|
|
||||||
|
// Reads this object's version field, and draws and marks all function modules.
|
||||||
|
private: void drawFunctionPatterns();
|
||||||
|
|
||||||
|
|
||||||
|
// Draws two copies of the format bits (with its own error correction code)
|
||||||
|
// based on the given mask and this object's error correction level field.
|
||||||
|
private: void drawFormatBits(int mask);
|
||||||
|
|
||||||
|
|
||||||
|
// Draws two copies of the version bits (with its own error correction code),
|
||||||
|
// based on this object's version field, iff 7 <= version <= 40.
|
||||||
|
private: void drawVersion();
|
||||||
|
|
||||||
|
|
||||||
|
// Draws a 9*9 finder pattern including the border separator,
|
||||||
|
// with the center module at (x, y). Modules can be out of bounds.
|
||||||
|
private: void drawFinderPattern(int x, int y);
|
||||||
|
|
||||||
|
|
||||||
|
// Draws a 5*5 alignment pattern, with the center module
|
||||||
|
// at (x, y). All modules must be in bounds.
|
||||||
|
private: void drawAlignmentPattern(int x, int y);
|
||||||
|
|
||||||
|
|
||||||
|
// Sets the color of a module and marks it as a function module.
|
||||||
|
// Only used by the constructor. Coordinates must be in bounds.
|
||||||
|
private: void setFunctionModule(int x, int y, bool isBlack);
|
||||||
|
|
||||||
|
|
||||||
|
// Returns the color of the module at the given coordinates, which must be in range.
|
||||||
|
private: bool module(int x, int y) const;
|
||||||
|
|
||||||
|
|
||||||
|
/*---- Private helper methods for constructor: Codewords and masking ----*/
|
||||||
|
|
||||||
|
// Returns a new byte string representing the given data with the appropriate error correction
|
||||||
|
// codewords appended to it, based on this object's version and error correction level.
|
||||||
|
private: std::vector<std::uint8_t> addEccAndInterleave(const std::vector<std::uint8_t> &data) const;
|
||||||
|
|
||||||
|
|
||||||
|
// Draws the given sequence of 8-bit codewords (data and error correction) onto the entire
|
||||||
|
// data area of this QR Code. Function modules need to be marked off before this is called.
|
||||||
|
private: void drawCodewords(const std::vector<std::uint8_t> &data);
|
||||||
|
|
||||||
|
|
||||||
|
// XORs the codeword modules in this QR Code with the given mask pattern.
|
||||||
|
// The function modules must be marked and the codeword bits must be drawn
|
||||||
|
// before masking. Due to the arithmetic of XOR, calling applyMask() with
|
||||||
|
// the same mask value a second time will undo the mask. A final well-formed
|
||||||
|
// QR Code needs exactly one (not zero, two, etc.) mask applied.
|
||||||
|
private: void applyMask(int mask);
|
||||||
|
|
||||||
|
|
||||||
|
// A messy helper function for the constructors. This QR Code must be in an unmasked state when this
|
||||||
|
// method is called. The given argument is the requested mask, which is -1 for auto or 0 to 7 for fixed.
|
||||||
|
// This method applies and returns the actual mask chosen, from 0 to 7.
|
||||||
|
private: int handleConstructorMasking(int mask);
|
||||||
|
|
||||||
|
|
||||||
|
// Calculates and returns the penalty score based on state of this QR Code's current modules.
|
||||||
|
// This is used by the automatic mask choice algorithm to find the mask pattern that yields the lowest score.
|
||||||
|
private: long getPenaltyScore() const;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*---- Private helper functions ----*/
|
||||||
|
|
||||||
|
// Returns an ascending list of positions of alignment patterns for this version number.
|
||||||
|
// Each position is in the range [0,177), and are used on both the x and y axes.
|
||||||
|
// This could be implemented as lookup table of 40 variable-length lists of unsigned bytes.
|
||||||
|
private: std::vector<int> getAlignmentPatternPositions() const;
|
||||||
|
|
||||||
|
|
||||||
|
// Returns the number of data bits that can be stored in a QR Code of the given version number, after
|
||||||
|
// all function modules are excluded. This includes remainder bits, so it might not be a multiple of 8.
|
||||||
|
// The result is in the range [208, 29648]. This could be implemented as a 40-entry lookup table.
|
||||||
|
private: static int getNumRawDataModules(int ver);
|
||||||
|
|
||||||
|
|
||||||
|
// Returns the number of 8-bit data (i.e. not error correction) codewords contained in any
|
||||||
|
// QR Code of the given version number and error correction level, with remainder bits discarded.
|
||||||
|
// This stateless pure function could be implemented as a (40*4)-cell lookup table.
|
||||||
|
private: static int getNumDataCodewords(int ver, Ecc ecl);
|
||||||
|
|
||||||
|
|
||||||
|
// Returns true iff the i'th bit of x is set to 1.
|
||||||
|
private: static bool getBit(long x, int i);
|
||||||
|
|
||||||
|
|
||||||
|
/*---- Constants and tables ----*/
|
||||||
|
|
||||||
|
// The minimum version number supported in the QR Code Model 2 standard.
|
||||||
|
public: static constexpr int MIN_VERSION = 1;
|
||||||
|
|
||||||
|
// The maximum version number supported in the QR Code Model 2 standard.
|
||||||
|
public: static constexpr int MAX_VERSION = 40;
|
||||||
|
|
||||||
|
|
||||||
|
// For use in getPenaltyScore(), when evaluating which mask is best.
|
||||||
|
private: static const int PENALTY_N1;
|
||||||
|
private: static const int PENALTY_N2;
|
||||||
|
private: static const int PENALTY_N3;
|
||||||
|
private: static const int PENALTY_N4;
|
||||||
|
|
||||||
|
|
||||||
|
private: static const std::int8_t ECC_CODEWORDS_PER_BLOCK[4][41];
|
||||||
|
private: static const std::int8_t NUM_ERROR_CORRECTION_BLOCKS[4][41];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*---- Private helper class ----*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Computes the Reed-Solomon error correction codewords for a sequence of data codewords
|
||||||
|
* at a given degree. Objects are immutable, and the state only depends on the degree.
|
||||||
|
* This class exists because each data block in a QR Code shares the same the divisor polynomial.
|
||||||
|
*/
|
||||||
|
private: class ReedSolomonGenerator final {
|
||||||
|
|
||||||
|
/*-- Immutable field --*/
|
||||||
|
|
||||||
|
// Coefficients of the divisor polynomial, stored from highest to lowest power, excluding the leading term which
|
||||||
|
// is always 1. For example the polynomial x^3 + 255x^2 + 8x + 93 is stored as the uint8 array {255, 8, 93}.
|
||||||
|
private: std::vector<std::uint8_t> coefficients;
|
||||||
|
|
||||||
|
|
||||||
|
/*-- Constructor --*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Creates a Reed-Solomon ECC generator for the given degree. This could be implemented
|
||||||
|
* as a lookup table over all possible parameter values, instead of as an algorithm.
|
||||||
|
*/
|
||||||
|
public: explicit ReedSolomonGenerator(int degree);
|
||||||
|
|
||||||
|
|
||||||
|
/*-- Method --*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Computes and returns the Reed-Solomon error correction codewords for the given
|
||||||
|
* sequence of data codewords. The returned object is always a new byte array.
|
||||||
|
* This method does not alter this object's state (because it is immutable).
|
||||||
|
*/
|
||||||
|
public: std::vector<std::uint8_t> getRemainder(const std::vector<std::uint8_t> &data) const;
|
||||||
|
|
||||||
|
|
||||||
|
/*-- Static function --*/
|
||||||
|
|
||||||
|
// Returns the product of the two given field elements modulo GF(2^8/0x11D).
|
||||||
|
// All inputs are valid. This could be implemented as a 256*256 lookup table.
|
||||||
|
private: static std::uint8_t multiply(std::uint8_t x, std::uint8_t y);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
225
libs/qrcode/QrSegment.cpp
Normal file
@@ -0,0 +1,225 @@
|
|||||||
|
/*
|
||||||
|
* QR Code generator library (C++)
|
||||||
|
*
|
||||||
|
* Copyright (c) Project Nayuki. (MIT License)
|
||||||
|
* https://www.nayuki.io/page/qr-code-generator-library
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <climits>
|
||||||
|
#include <cstring>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <utility>
|
||||||
|
#include "QrSegment.hpp"
|
||||||
|
|
||||||
|
using std::uint8_t;
|
||||||
|
using std::vector;
|
||||||
|
|
||||||
|
|
||||||
|
namespace qrcodegen {
|
||||||
|
|
||||||
|
QrSegment::Mode::Mode(int mode, int cc0, int cc1, int cc2) :
|
||||||
|
modeBits(mode) {
|
||||||
|
numBitsCharCount[0] = cc0;
|
||||||
|
numBitsCharCount[1] = cc1;
|
||||||
|
numBitsCharCount[2] = cc2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int QrSegment::Mode::getModeBits() const {
|
||||||
|
return modeBits;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int QrSegment::Mode::numCharCountBits(int ver) const {
|
||||||
|
return numBitsCharCount[(ver + 7) / 17];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const QrSegment::Mode QrSegment::Mode::NUMERIC (0x1, 10, 12, 14);
|
||||||
|
const QrSegment::Mode QrSegment::Mode::ALPHANUMERIC(0x2, 9, 11, 13);
|
||||||
|
const QrSegment::Mode QrSegment::Mode::BYTE (0x4, 8, 16, 16);
|
||||||
|
const QrSegment::Mode QrSegment::Mode::KANJI (0x8, 8, 10, 12);
|
||||||
|
const QrSegment::Mode QrSegment::Mode::ECI (0x7, 0, 0, 0);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
QrSegment QrSegment::makeBytes(const vector<uint8_t> &data) {
|
||||||
|
if (data.size() > static_cast<unsigned int>(INT_MAX))
|
||||||
|
throw std::length_error("Data too long");
|
||||||
|
BitBuffer bb;
|
||||||
|
for (uint8_t b : data)
|
||||||
|
bb.appendBits(b, 8);
|
||||||
|
return QrSegment(Mode::BYTE, static_cast<int>(data.size()), std::move(bb));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QrSegment QrSegment::makeNumeric(const char *digits) {
|
||||||
|
BitBuffer bb;
|
||||||
|
int accumData = 0;
|
||||||
|
int accumCount = 0;
|
||||||
|
int charCount = 0;
|
||||||
|
for (; *digits != '\0'; digits++, charCount++) {
|
||||||
|
char c = *digits;
|
||||||
|
if (c < '0' || c > '9')
|
||||||
|
throw std::domain_error("String contains non-numeric characters");
|
||||||
|
accumData = accumData * 10 + (c - '0');
|
||||||
|
accumCount++;
|
||||||
|
if (accumCount == 3) {
|
||||||
|
bb.appendBits(accumData, 10);
|
||||||
|
accumData = 0;
|
||||||
|
accumCount = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (accumCount > 0) // 1 or 2 digits remaining
|
||||||
|
bb.appendBits(accumData, accumCount * 3 + 1);
|
||||||
|
return QrSegment(Mode::NUMERIC, charCount, std::move(bb));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QrSegment QrSegment::makeAlphanumeric(const char *text) {
|
||||||
|
BitBuffer bb;
|
||||||
|
int accumData = 0;
|
||||||
|
int accumCount = 0;
|
||||||
|
int charCount = 0;
|
||||||
|
for (; *text != '\0'; text++, charCount++) {
|
||||||
|
const char *temp = std::strchr(ALPHANUMERIC_CHARSET, *text);
|
||||||
|
if (temp == nullptr)
|
||||||
|
throw std::domain_error("String contains unencodable characters in alphanumeric mode");
|
||||||
|
accumData = accumData * 45 + (temp - ALPHANUMERIC_CHARSET);
|
||||||
|
accumCount++;
|
||||||
|
if (accumCount == 2) {
|
||||||
|
bb.appendBits(accumData, 11);
|
||||||
|
accumData = 0;
|
||||||
|
accumCount = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (accumCount > 0) // 1 character remaining
|
||||||
|
bb.appendBits(accumData, 6);
|
||||||
|
return QrSegment(Mode::ALPHANUMERIC, charCount, std::move(bb));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
vector<QrSegment> QrSegment::makeSegments(const char *text) {
|
||||||
|
// Select the most efficient segment encoding automatically
|
||||||
|
vector<QrSegment> result;
|
||||||
|
if (*text == '\0'); // Leave result empty
|
||||||
|
else if (isNumeric(text))
|
||||||
|
result.push_back(makeNumeric(text));
|
||||||
|
else if (isAlphanumeric(text))
|
||||||
|
result.push_back(makeAlphanumeric(text));
|
||||||
|
else {
|
||||||
|
vector<uint8_t> bytes;
|
||||||
|
for (; *text != '\0'; text++)
|
||||||
|
bytes.push_back(static_cast<uint8_t>(*text));
|
||||||
|
result.push_back(makeBytes(bytes));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QrSegment QrSegment::makeEci(long assignVal) {
|
||||||
|
BitBuffer bb;
|
||||||
|
if (assignVal < 0)
|
||||||
|
throw std::domain_error("ECI assignment value out of range");
|
||||||
|
else if (assignVal < (1 << 7))
|
||||||
|
bb.appendBits(assignVal, 8);
|
||||||
|
else if (assignVal < (1 << 14)) {
|
||||||
|
bb.appendBits(2, 2);
|
||||||
|
bb.appendBits(assignVal, 14);
|
||||||
|
} else if (assignVal < 1000000L) {
|
||||||
|
bb.appendBits(6, 3);
|
||||||
|
bb.appendBits(assignVal, 21);
|
||||||
|
} else
|
||||||
|
throw std::domain_error("ECI assignment value out of range");
|
||||||
|
return QrSegment(Mode::ECI, 0, std::move(bb));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QrSegment::QrSegment(Mode md, int numCh, const std::vector<bool> &dt) :
|
||||||
|
mode(md),
|
||||||
|
numChars(numCh),
|
||||||
|
data(dt) {
|
||||||
|
if (numCh < 0)
|
||||||
|
throw std::domain_error("Invalid value");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QrSegment::QrSegment(Mode md, int numCh, std::vector<bool> &&dt) :
|
||||||
|
mode(md),
|
||||||
|
numChars(numCh),
|
||||||
|
data(std::move(dt)) {
|
||||||
|
if (numCh < 0)
|
||||||
|
throw std::domain_error("Invalid value");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int QrSegment::getTotalBits(const vector<QrSegment> &segs, int version) {
|
||||||
|
int result = 0;
|
||||||
|
for (const QrSegment &seg : segs) {
|
||||||
|
int ccbits = seg.mode.numCharCountBits(version);
|
||||||
|
if (seg.numChars >= (1L << ccbits))
|
||||||
|
return -1; // The segment's length doesn't fit the field's bit width
|
||||||
|
if (4 + ccbits > INT_MAX - result)
|
||||||
|
return -1; // The sum will overflow an int type
|
||||||
|
result += 4 + ccbits;
|
||||||
|
if (seg.data.size() > static_cast<unsigned int>(INT_MAX - result))
|
||||||
|
return -1; // The sum will overflow an int type
|
||||||
|
result += static_cast<int>(seg.data.size());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool QrSegment::isAlphanumeric(const char *text) {
|
||||||
|
for (; *text != '\0'; text++) {
|
||||||
|
if (std::strchr(ALPHANUMERIC_CHARSET, *text) == nullptr)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool QrSegment::isNumeric(const char *text) {
|
||||||
|
for (; *text != '\0'; text++) {
|
||||||
|
char c = *text;
|
||||||
|
if (c < '0' || c > '9')
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QrSegment::Mode QrSegment::getMode() const {
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int QrSegment::getNumChars() const {
|
||||||
|
return numChars;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const std::vector<bool> &QrSegment::getData() const {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const char *QrSegment::ALPHANUMERIC_CHARSET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:";
|
||||||
|
|
||||||
|
}
|
||||||
216
libs/qrcode/QrSegment.hpp
Normal file
@@ -0,0 +1,216 @@
|
|||||||
|
/*
|
||||||
|
* QR Code generator library (C++)
|
||||||
|
*
|
||||||
|
* Copyright (c) Project Nayuki. (MIT License)
|
||||||
|
* https://www.nayuki.io/page/qr-code-generator-library
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <vector>
|
||||||
|
#include "BitBuffer.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
namespace qrcodegen {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A segment of character/binary/control data in a QR Code symbol.
|
||||||
|
* Instances of this class are immutable.
|
||||||
|
* The mid-level way to create a segment is to take the payload data
|
||||||
|
* and call a static factory function such as QrSegment::makeNumeric().
|
||||||
|
* The low-level way to create a segment is to custom-make the bit buffer
|
||||||
|
* and call the QrSegment() constructor with appropriate values.
|
||||||
|
* This segment class imposes no length restrictions, but QR Codes have restrictions.
|
||||||
|
* Even in the most favorable conditions, a QR Code can only hold 7089 characters of data.
|
||||||
|
* Any segment longer than this is meaningless for the purpose of generating QR Codes.
|
||||||
|
*/
|
||||||
|
class QrSegment final {
|
||||||
|
|
||||||
|
/*---- Public helper enumeration ----*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Describes how a segment's data bits are interpreted. Immutable.
|
||||||
|
*/
|
||||||
|
public: class Mode final {
|
||||||
|
|
||||||
|
/*-- Constants --*/
|
||||||
|
|
||||||
|
public: static const Mode NUMERIC;
|
||||||
|
public: static const Mode ALPHANUMERIC;
|
||||||
|
public: static const Mode BYTE;
|
||||||
|
public: static const Mode KANJI;
|
||||||
|
public: static const Mode ECI;
|
||||||
|
|
||||||
|
|
||||||
|
/*-- Fields --*/
|
||||||
|
|
||||||
|
// The mode indicator bits, which is a uint4 value (range 0 to 15).
|
||||||
|
private: int modeBits;
|
||||||
|
|
||||||
|
// Number of character count bits for three different version ranges.
|
||||||
|
private: int numBitsCharCount[3];
|
||||||
|
|
||||||
|
|
||||||
|
/*-- Constructor --*/
|
||||||
|
|
||||||
|
private: Mode(int mode, int cc0, int cc1, int cc2);
|
||||||
|
|
||||||
|
|
||||||
|
/*-- Methods --*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (Package-private) Returns the mode indicator bits, which is an unsigned 4-bit value (range 0 to 15).
|
||||||
|
*/
|
||||||
|
public: int getModeBits() const;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (Package-private) Returns the bit width of the character count field for a segment in
|
||||||
|
* this mode in a QR Code at the given version number. The result is in the range [0, 16].
|
||||||
|
*/
|
||||||
|
public: int numCharCountBits(int ver) const;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*---- Static factory functions (mid level) ----*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a segment representing the given binary data encoded in
|
||||||
|
* byte mode. All input byte vectors are acceptable. Any text string
|
||||||
|
* can be converted to UTF-8 bytes and encoded as a byte mode segment.
|
||||||
|
*/
|
||||||
|
public: static QrSegment makeBytes(const std::vector<std::uint8_t> &data);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a segment representing the given string of decimal digits encoded in numeric mode.
|
||||||
|
*/
|
||||||
|
public: static QrSegment makeNumeric(const char *digits);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a segment representing the given text string encoded in alphanumeric mode.
|
||||||
|
* The characters allowed are: 0 to 9, A to Z (uppercase only), space,
|
||||||
|
* dollar, percent, asterisk, plus, hyphen, period, slash, colon.
|
||||||
|
*/
|
||||||
|
public: static QrSegment makeAlphanumeric(const char *text);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a list of zero or more segments to represent the given text string. The result
|
||||||
|
* may use various segment modes and switch modes to optimize the length of the bit stream.
|
||||||
|
*/
|
||||||
|
public: static std::vector<QrSegment> makeSegments(const char *text);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a segment representing an Extended Channel Interpretation
|
||||||
|
* (ECI) designator with the given assignment value.
|
||||||
|
*/
|
||||||
|
public: static QrSegment makeEci(long assignVal);
|
||||||
|
|
||||||
|
|
||||||
|
/*---- Public static helper functions ----*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tests whether the given string can be encoded as a segment in alphanumeric mode.
|
||||||
|
* A string is encodable iff each character is in the following set: 0 to 9, A to Z
|
||||||
|
* (uppercase only), space, dollar, percent, asterisk, plus, hyphen, period, slash, colon.
|
||||||
|
*/
|
||||||
|
public: static bool isAlphanumeric(const char *text);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Tests whether the given string can be encoded as a segment in numeric mode.
|
||||||
|
* A string is encodable iff each character is in the range 0 to 9.
|
||||||
|
*/
|
||||||
|
public: static bool isNumeric(const char *text);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*---- Instance fields ----*/
|
||||||
|
|
||||||
|
/* The mode indicator of this segment. Accessed through getMode(). */
|
||||||
|
private: Mode mode;
|
||||||
|
|
||||||
|
/* The length of this segment's unencoded data. Measured in characters for
|
||||||
|
* numeric/alphanumeric/kanji mode, bytes for byte mode, and 0 for ECI mode.
|
||||||
|
* Always zero or positive. Not the same as the data's bit length.
|
||||||
|
* Accessed through getNumChars(). */
|
||||||
|
private: int numChars;
|
||||||
|
|
||||||
|
/* The data bits of this segment. Accessed through getData(). */
|
||||||
|
private: std::vector<bool> data;
|
||||||
|
|
||||||
|
|
||||||
|
/*---- Constructors (low level) ----*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Creates a new QR Code segment with the given attributes and data.
|
||||||
|
* The character count (numCh) must agree with the mode and the bit buffer length,
|
||||||
|
* but the constraint isn't checked. The given bit buffer is copied and stored.
|
||||||
|
*/
|
||||||
|
public: QrSegment(Mode md, int numCh, const std::vector<bool> &dt);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Creates a new QR Code segment with the given parameters and data.
|
||||||
|
* The character count (numCh) must agree with the mode and the bit buffer length,
|
||||||
|
* but the constraint isn't checked. The given bit buffer is moved and stored.
|
||||||
|
*/
|
||||||
|
public: QrSegment(Mode md, int numCh, std::vector<bool> &&dt);
|
||||||
|
|
||||||
|
|
||||||
|
/*---- Methods ----*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the mode field of this segment.
|
||||||
|
*/
|
||||||
|
public: Mode getMode() const;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the character count field of this segment.
|
||||||
|
*/
|
||||||
|
public: int getNumChars() const;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the data bits of this segment.
|
||||||
|
*/
|
||||||
|
public: const std::vector<bool> &getData() const;
|
||||||
|
|
||||||
|
|
||||||
|
// (Package-private) Calculates the number of bits needed to encode the given segments at
|
||||||
|
// the given version. Returns a non-negative number if successful. Otherwise returns -1 if a
|
||||||
|
// segment has too many characters to fit its length field, or the total bits exceeds INT_MAX.
|
||||||
|
public: static int getTotalBits(const std::vector<QrSegment> &segs, int version);
|
||||||
|
|
||||||
|
|
||||||
|
/*---- Private constant ----*/
|
||||||
|
|
||||||
|
/* The set of all legal characters in alphanumeric mode, where
|
||||||
|
* each character value maps to the index in the string. */
|
||||||
|
private: static const char *ALPHANUMERIC_CHARSET;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
7988
libs/stb_image.h
Normal file
0
prebuilt-binaries/dragonxd-linux/.gitkeep
Normal file
0
prebuilt-binaries/dragonxd-mac/.gitkeep
Normal file
0
prebuilt-binaries/dragonxd-win/.gitkeep
Normal file
0
prebuilt-binaries/xmrig-hac/.gitkeep
Normal file
41
res/ObsidianDragon.rc
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
// ObsidianDragon Windows Resource File
|
||||||
|
// Application icon — shown in Explorer, taskbar, and Alt-Tab
|
||||||
|
// Path configured by CMake (absolute path for cross-compilation)
|
||||||
|
// Use numeric ordinal 1 so LoadIcon(hInst, MAKEINTRESOURCE(1)) finds it.
|
||||||
|
1 ICON "@OBSIDIAN_ICO_PATH@"
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// VERSIONINFO — sets the description shown in Task Manager, Explorer
|
||||||
|
// "Details" tab, and other Windows tools. Without this, MinGW-w64
|
||||||
|
// fills in its own runtime description ("POSIX WinThreads for Windows").
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
#include <winver.h>
|
||||||
|
|
||||||
|
VS_VERSION_INFO VERSIONINFO
|
||||||
|
FILEVERSION @DRAGONX_VER_MAJOR@,@DRAGONX_VER_MINOR@,@DRAGONX_VER_PATCH@,0
|
||||||
|
PRODUCTVERSION @DRAGONX_VER_MAJOR@,@DRAGONX_VER_MINOR@,@DRAGONX_VER_PATCH@,0
|
||||||
|
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
|
||||||
|
FILEFLAGS 0x0L
|
||||||
|
FILEOS VOS_NT_WINDOWS32
|
||||||
|
FILETYPE VFT_APP
|
||||||
|
FILESUBTYPE VFT2_UNKNOWN
|
||||||
|
BEGIN
|
||||||
|
BLOCK "StringFileInfo"
|
||||||
|
BEGIN
|
||||||
|
BLOCK "040904B0" // US-English, Unicode
|
||||||
|
BEGIN
|
||||||
|
VALUE "CompanyName", "The Hush Developers\0"
|
||||||
|
VALUE "FileDescription", "ObsidianDragon Wallet\0"
|
||||||
|
VALUE "FileVersion", "@DRAGONX_VERSION@\0"
|
||||||
|
VALUE "InternalName", "ObsidianDragon\0"
|
||||||
|
VALUE "LegalCopyright", "Copyright 2024-2026 The Hush Developers. GPLv3.\0"
|
||||||
|
VALUE "OriginalFilename", "ObsidianDragon.exe\0"
|
||||||
|
VALUE "ProductName", "ObsidianDragon\0"
|
||||||
|
VALUE "ProductVersion", "@DRAGONX_VERSION@\0"
|
||||||
|
END
|
||||||
|
END
|
||||||
|
BLOCK "VarFileInfo"
|
||||||
|
BEGIN
|
||||||
|
VALUE "Translation", 0x409, 1200 // US-English, Unicode
|
||||||
|
END
|
||||||
|
END
|
||||||
BIN
res/fonts/MaterialIcons-Regular.ttf
Normal file
BIN
res/fonts/Ubuntu-Light.ttf
Normal file
BIN
res/fonts/Ubuntu-Medium.ttf
Normal file
BIN
res/fonts/Ubuntu-R.ttf
Normal file
BIN
res/img/ObsidianDragon.ico
Normal file
|
After Width: | Height: | Size: 4.5 KiB |
BIN
res/img/backgrounds/gradient/dark_gradient.png
Normal file
|
After Width: | Height: | Size: 149 KiB |
BIN
res/img/backgrounds/gradient/gradient_dark_bg.png
Normal file
|
After Width: | Height: | Size: 109 KiB |
BIN
res/img/backgrounds/gradient/gradient_drgx_bg.png
Normal file
|
After Width: | Height: | Size: 127 KiB |
BIN
res/img/backgrounds/gradient/gradient_dune_bg.png
Normal file
|
After Width: | Height: | Size: 82 KiB |
BIN
res/img/backgrounds/gradient/gradient_iridescent_bg.png
Normal file
|
After Width: | Height: | Size: 210 KiB |
BIN
res/img/backgrounds/gradient/gradient_light_bg.png
Normal file
|
After Width: | Height: | Size: 121 KiB |
BIN
res/img/backgrounds/gradient/gradient_marble_bg.png
Normal file
|
After Width: | Height: | Size: 83 KiB |
BIN
res/img/backgrounds/gradient/gradient_obsidian_bg.png
Normal file
|
After Width: | Height: | Size: 129 KiB |
BIN
res/img/backgrounds/gradient/gradient_pop-dark_bg.png
Normal file
|
After Width: | Height: | Size: 149 KiB |
BIN
res/img/backgrounds/gradient/gradient_pop-light_bg.png
Normal file
|
After Width: | Height: | Size: 231 KiB |
BIN
res/img/backgrounds/gradient/light_gradient.png
Normal file
|
After Width: | Height: | Size: 267 KiB |
BIN
res/img/backgrounds/texture/dark_bg.png
Normal file
|
After Width: | Height: | Size: 688 KiB |
BIN
res/img/backgrounds/texture/drgx_bg.png
Normal file
|
After Width: | Height: | Size: 121 KiB |
BIN
res/img/backgrounds/texture/dune_bg.png
Normal file
|
After Width: | Height: | Size: 223 KiB |
BIN
res/img/backgrounds/texture/iridescent_bg.png
Normal file
|
After Width: | Height: | Size: 1.6 MiB |
BIN
res/img/backgrounds/texture/light_bg.png
Normal file
|
After Width: | Height: | Size: 598 KiB |
BIN
res/img/backgrounds/texture/marble_bg.png
Normal file
|
After Width: | Height: | Size: 732 KiB |
BIN
res/img/backgrounds/texture/obsidian_bg.png
Normal file
|
After Width: | Height: | Size: 556 KiB |
BIN
res/img/backgrounds/texture/pop-dark_bg.png
Normal file
|
After Width: | Height: | Size: 1.8 MiB |
BIN
res/img/backgrounds/texture/pop-light_bg.png
Normal file
|
After Width: | Height: | Size: 1.9 MiB |
BIN
res/img/logos/logo_ObsidianDragon.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
res/img/logos/logo_ObsidianDragon_dark.png
Normal file
|
After Width: | Height: | Size: 3.4 KiB |
BIN
res/img/logos/logo_ObsidianDragon_light.png
Normal file
|
After Width: | Height: | Size: 3.7 KiB |
BIN
res/img/logos/logo_dragonx_128.png
Normal file
|
After Width: | Height: | Size: 6.9 KiB |
139
res/lang/de.json
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
{
|
||||||
|
"balance": "Kontostand",
|
||||||
|
"send": "Senden",
|
||||||
|
"receive": "Empfangen",
|
||||||
|
"transactions": "Transaktionen",
|
||||||
|
"mining": "Mining",
|
||||||
|
"peers": "Knoten",
|
||||||
|
"market": "Markt",
|
||||||
|
"settings": "Einstellungen",
|
||||||
|
|
||||||
|
"summary": "Übersicht",
|
||||||
|
"shielded": "Geschützt",
|
||||||
|
"transparent": "Transparent",
|
||||||
|
"total": "Gesamt",
|
||||||
|
"unconfirmed": "Unbestätigt",
|
||||||
|
"your_addresses": "Ihre Adressen",
|
||||||
|
"z_addresses": "Z-Adressen",
|
||||||
|
"t_addresses": "T-Adressen",
|
||||||
|
"no_addresses": "Keine Adressen gefunden. Erstellen Sie eine mit den Schaltflächen oben.",
|
||||||
|
"new_z_address": "Neue Z-Adresse",
|
||||||
|
"new_t_address": "Neue T-Adresse",
|
||||||
|
"type": "Typ",
|
||||||
|
"address": "Adresse",
|
||||||
|
"copy_address": "Vollständige Adresse kopieren",
|
||||||
|
"send_from_this_address": "Von dieser Adresse senden",
|
||||||
|
"export_private_key": "Privaten Schlüssel exportieren",
|
||||||
|
"export_viewing_key": "Ansichtsschlüssel exportieren",
|
||||||
|
"show_qr_code": "QR-Code anzeigen",
|
||||||
|
"not_connected": "Nicht mit Daemon verbunden...",
|
||||||
|
|
||||||
|
"pay_from": "Zahlen von",
|
||||||
|
"send_to": "Senden an",
|
||||||
|
"amount": "Betrag",
|
||||||
|
"memo": "Memo (optional, verschlüsselt)",
|
||||||
|
"miner_fee": "Miner-Gebühr",
|
||||||
|
"fee": "Gebühr",
|
||||||
|
"send_transaction": "Transaktion senden",
|
||||||
|
"clear": "Löschen",
|
||||||
|
"select_address": "Adresse auswählen...",
|
||||||
|
"paste": "Einfügen",
|
||||||
|
"max": "Max",
|
||||||
|
"available": "Verfügbar",
|
||||||
|
"invalid_address": "Ungültiges Adressformat",
|
||||||
|
"memo_z_only": "Hinweis: Memos sind nur beim Senden an geschützte (z) Adressen verfügbar",
|
||||||
|
"characters": "Zeichen",
|
||||||
|
"from": "Von",
|
||||||
|
"to": "An",
|
||||||
|
"sending": "Transaktion wird gesendet",
|
||||||
|
"confirm_send": "Senden bestätigen",
|
||||||
|
"confirm_transaction": "Transaktion bestätigen",
|
||||||
|
"confirm_and_send": "Bestätigen & Senden",
|
||||||
|
"cancel": "Abbrechen",
|
||||||
|
|
||||||
|
"receiving_addresses": "Ihre Empfangsadressen",
|
||||||
|
"new_z_shielded": "Neue z-Adresse (geschützt)",
|
||||||
|
"new_t_transparent": "Neue t-Adresse (transparent)",
|
||||||
|
"address_details": "Adressdetails",
|
||||||
|
"view_on_explorer": "Im Explorer ansehen",
|
||||||
|
"qr_code": "QR-Code",
|
||||||
|
"request_payment": "Zahlung anfordern",
|
||||||
|
|
||||||
|
"date": "Datum",
|
||||||
|
"status": "Status",
|
||||||
|
"confirmations": "Bestätigungen",
|
||||||
|
"confirmed": "Bestätigt",
|
||||||
|
"pending": "Ausstehend",
|
||||||
|
"sent": "gesendet",
|
||||||
|
"received": "empfangen",
|
||||||
|
"mined": "geschürft",
|
||||||
|
|
||||||
|
"mining_control": "Mining-Steuerung",
|
||||||
|
"start_mining": "Mining starten",
|
||||||
|
"stop_mining": "Mining stoppen",
|
||||||
|
"mining_threads": "Mining-Threads",
|
||||||
|
"mining_statistics": "Mining-Statistiken",
|
||||||
|
"local_hashrate": "Lokale Hashrate",
|
||||||
|
"network_hashrate": "Netzwerk-Hashrate",
|
||||||
|
"difficulty": "Schwierigkeit",
|
||||||
|
"est_time_to_block": "Gesch. Zeit bis Block",
|
||||||
|
"mining_off": "Mining ist AUS",
|
||||||
|
"mining_on": "Mining ist AN",
|
||||||
|
|
||||||
|
"connected_peers": "Verbundene Knoten",
|
||||||
|
"banned_peers": "Gesperrte Knoten",
|
||||||
|
"ip_address": "IP-Adresse",
|
||||||
|
"version": "Version",
|
||||||
|
"height": "Höhe",
|
||||||
|
"ping": "Ping",
|
||||||
|
"ban": "Sperren",
|
||||||
|
"unban": "Entsperren",
|
||||||
|
"clear_all_bans": "Alle Sperren aufheben",
|
||||||
|
|
||||||
|
"price_chart": "Preisdiagramm",
|
||||||
|
"current_price": "Aktueller Preis",
|
||||||
|
"24h_change": "24h-Änderung",
|
||||||
|
"24h_volume": "24h-Volumen",
|
||||||
|
"market_cap": "Marktkapitalisierung",
|
||||||
|
|
||||||
|
"general": "Allgemein",
|
||||||
|
"display": "Anzeige",
|
||||||
|
"network": "Netzwerk",
|
||||||
|
"theme": "Design",
|
||||||
|
"language": "Sprache",
|
||||||
|
"dragonx_green": "DragonX (Grün)",
|
||||||
|
"dark": "Dunkel",
|
||||||
|
"light": "Hell",
|
||||||
|
"allow_custom_fees": "Benutzerdefinierte Gebühren erlauben",
|
||||||
|
"use_embedded_daemon": "Integrierten dragonxd verwenden",
|
||||||
|
"save": "Speichern",
|
||||||
|
"close": "Schließen",
|
||||||
|
|
||||||
|
"file": "Datei",
|
||||||
|
"edit": "Bearbeiten",
|
||||||
|
"view": "Ansicht",
|
||||||
|
"help": "Hilfe",
|
||||||
|
"import_private_key": "Privaten Schlüssel importieren...",
|
||||||
|
"backup_wallet": "Wallet sichern...",
|
||||||
|
"exit": "Beenden",
|
||||||
|
"about_dragonx": "Über ObsidianDragon",
|
||||||
|
"refresh_now": "Jetzt aktualisieren",
|
||||||
|
|
||||||
|
"about": "Über",
|
||||||
|
"import": "Importieren",
|
||||||
|
"export": "Exportieren",
|
||||||
|
"copy_to_clipboard": "In Zwischenablage kopieren",
|
||||||
|
|
||||||
|
"connected": "Verbunden",
|
||||||
|
"disconnected": "Getrennt",
|
||||||
|
"connecting": "Verbinde...",
|
||||||
|
"syncing": "Synchronisiere...",
|
||||||
|
"block": "Block",
|
||||||
|
"no_addresses_available": "Keine Adressen verfügbar",
|
||||||
|
|
||||||
|
"error": "Fehler",
|
||||||
|
"success": "Erfolg",
|
||||||
|
"warning": "Warnung",
|
||||||
|
"amount_exceeds_balance": "Betrag übersteigt Kontostand",
|
||||||
|
"transaction_sent": "Transaktion erfolgreich gesendet"
|
||||||
|
}
|
||||||
139
res/lang/es.json
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
{
|
||||||
|
"balance": "Saldo",
|
||||||
|
"send": "Enviar",
|
||||||
|
"receive": "Recibir",
|
||||||
|
"transactions": "Transacciones",
|
||||||
|
"mining": "Minería",
|
||||||
|
"peers": "Nodos",
|
||||||
|
"market": "Mercado",
|
||||||
|
"settings": "Configuración",
|
||||||
|
|
||||||
|
"summary": "Resumen",
|
||||||
|
"shielded": "Protegido",
|
||||||
|
"transparent": "Transparente",
|
||||||
|
"total": "Total",
|
||||||
|
"unconfirmed": "Sin Confirmar",
|
||||||
|
"your_addresses": "Tus Direcciones",
|
||||||
|
"z_addresses": "Direcciones-Z",
|
||||||
|
"t_addresses": "Direcciones-T",
|
||||||
|
"no_addresses": "No se encontraron direcciones. Crea una usando los botones de arriba.",
|
||||||
|
"new_z_address": "Nueva Dir-Z",
|
||||||
|
"new_t_address": "Nueva Dir-T",
|
||||||
|
"type": "Tipo",
|
||||||
|
"address": "Dirección",
|
||||||
|
"copy_address": "Copiar Dirección Completa",
|
||||||
|
"send_from_this_address": "Enviar Desde Esta Dirección",
|
||||||
|
"export_private_key": "Exportar Clave Privada",
|
||||||
|
"export_viewing_key": "Exportar Clave de Vista",
|
||||||
|
"show_qr_code": "Mostrar Código QR",
|
||||||
|
"not_connected": "No conectado al daemon...",
|
||||||
|
|
||||||
|
"pay_from": "Pagar Desde",
|
||||||
|
"send_to": "Enviar A",
|
||||||
|
"amount": "Cantidad",
|
||||||
|
"memo": "Memo (opcional, encriptado)",
|
||||||
|
"miner_fee": "Comisión de Minero",
|
||||||
|
"fee": "Comisión",
|
||||||
|
"send_transaction": "Enviar Transacción",
|
||||||
|
"clear": "Limpiar",
|
||||||
|
"select_address": "Seleccionar dirección...",
|
||||||
|
"paste": "Pegar",
|
||||||
|
"max": "Máximo",
|
||||||
|
"available": "Disponible",
|
||||||
|
"invalid_address": "Formato de dirección inválido",
|
||||||
|
"memo_z_only": "Nota: Los memos solo están disponibles al enviar a direcciones protegidas (z)",
|
||||||
|
"characters": "caracteres",
|
||||||
|
"from": "Desde",
|
||||||
|
"to": "A",
|
||||||
|
"sending": "Enviando transacción",
|
||||||
|
"confirm_send": "Confirmar Envío",
|
||||||
|
"confirm_transaction": "Confirmar Transacción",
|
||||||
|
"confirm_and_send": "Confirmar y Enviar",
|
||||||
|
"cancel": "Cancelar",
|
||||||
|
|
||||||
|
"receiving_addresses": "Tus Direcciones de Recepción",
|
||||||
|
"new_z_shielded": "Nueva Dirección-z (Protegida)",
|
||||||
|
"new_t_transparent": "Nueva Dirección-t (Transparente)",
|
||||||
|
"address_details": "Detalles de Dirección",
|
||||||
|
"view_on_explorer": "Ver en Explorador",
|
||||||
|
"qr_code": "Código QR",
|
||||||
|
"request_payment": "Solicitar Pago",
|
||||||
|
|
||||||
|
"date": "Fecha",
|
||||||
|
"status": "Estado",
|
||||||
|
"confirmations": "Confirmaciones",
|
||||||
|
"confirmed": "Confirmada",
|
||||||
|
"pending": "Pendiente",
|
||||||
|
"sent": "enviado",
|
||||||
|
"received": "recibido",
|
||||||
|
"mined": "minado",
|
||||||
|
|
||||||
|
"mining_control": "Control de Minería",
|
||||||
|
"start_mining": "Iniciar Minería",
|
||||||
|
"stop_mining": "Detener Minería",
|
||||||
|
"mining_threads": "Hilos de Minería",
|
||||||
|
"mining_statistics": "Estadísticas de Minería",
|
||||||
|
"local_hashrate": "Tasa Hash Local",
|
||||||
|
"network_hashrate": "Tasa Hash de Red",
|
||||||
|
"difficulty": "Dificultad",
|
||||||
|
"est_time_to_block": "Tiempo Est. al Bloque",
|
||||||
|
"mining_off": "Minería APAGADA",
|
||||||
|
"mining_on": "Minería ENCENDIDA",
|
||||||
|
|
||||||
|
"connected_peers": "Nodos Conectados",
|
||||||
|
"banned_peers": "Nodos Bloqueados",
|
||||||
|
"ip_address": "Dirección IP",
|
||||||
|
"version": "Versión",
|
||||||
|
"height": "Altura",
|
||||||
|
"ping": "Ping",
|
||||||
|
"ban": "Bloquear",
|
||||||
|
"unban": "Desbloquear",
|
||||||
|
"clear_all_bans": "Limpiar Todos los Bloqueos",
|
||||||
|
|
||||||
|
"price_chart": "Gráfico de Precio",
|
||||||
|
"current_price": "Precio Actual",
|
||||||
|
"24h_change": "Cambio 24h",
|
||||||
|
"24h_volume": "Volumen 24h",
|
||||||
|
"market_cap": "Cap. de Mercado",
|
||||||
|
|
||||||
|
"general": "General",
|
||||||
|
"display": "Pantalla",
|
||||||
|
"network": "Red",
|
||||||
|
"theme": "Tema",
|
||||||
|
"language": "Idioma",
|
||||||
|
"dragonx_green": "DragonX (Verde)",
|
||||||
|
"dark": "Oscuro",
|
||||||
|
"light": "Claro",
|
||||||
|
"allow_custom_fees": "Permitir comisiones personalizadas",
|
||||||
|
"use_embedded_daemon": "Usar dragonxd integrado",
|
||||||
|
"save": "Guardar",
|
||||||
|
"close": "Cerrar",
|
||||||
|
|
||||||
|
"file": "Archivo",
|
||||||
|
"edit": "Editar",
|
||||||
|
"view": "Ver",
|
||||||
|
"help": "Ayuda",
|
||||||
|
"import_private_key": "Importar Clave Privada...",
|
||||||
|
"backup_wallet": "Respaldar Cartera...",
|
||||||
|
"exit": "Salir",
|
||||||
|
"about_dragonx": "Acerca de DragonX",
|
||||||
|
"refresh_now": "Actualizar Ahora",
|
||||||
|
|
||||||
|
"about": "Acerca de",
|
||||||
|
"import": "Importar",
|
||||||
|
"export": "Exportar",
|
||||||
|
"copy_to_clipboard": "Copiar al Portapapeles",
|
||||||
|
|
||||||
|
"connected": "Conectado",
|
||||||
|
"disconnected": "Desconectado",
|
||||||
|
"connecting": "Conectando...",
|
||||||
|
"syncing": "Sincronizando...",
|
||||||
|
"block": "Bloque",
|
||||||
|
"no_addresses_available": "No hay direcciones disponibles",
|
||||||
|
|
||||||
|
"error": "Error",
|
||||||
|
"success": "Éxito",
|
||||||
|
"warning": "Advertencia",
|
||||||
|
"amount_exceeds_balance": "La cantidad excede el saldo",
|
||||||
|
"transaction_sent": "Transacción enviada exitosamente"
|
||||||
|
}
|
||||||
139
res/lang/fr.json
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
{
|
||||||
|
"balance": "Solde",
|
||||||
|
"send": "Envoyer",
|
||||||
|
"receive": "Recevoir",
|
||||||
|
"transactions": "Transactions",
|
||||||
|
"mining": "Minage",
|
||||||
|
"peers": "Nœuds",
|
||||||
|
"market": "Marché",
|
||||||
|
"settings": "Paramètres",
|
||||||
|
|
||||||
|
"summary": "Résumé",
|
||||||
|
"shielded": "Protégé",
|
||||||
|
"transparent": "Transparent",
|
||||||
|
"total": "Total",
|
||||||
|
"unconfirmed": "Non confirmé",
|
||||||
|
"your_addresses": "Vos adresses",
|
||||||
|
"z_addresses": "Adresses-Z",
|
||||||
|
"t_addresses": "Adresses-T",
|
||||||
|
"no_addresses": "Aucune adresse trouvée. Créez-en une avec les boutons ci-dessus.",
|
||||||
|
"new_z_address": "Nouvelle adresse-Z",
|
||||||
|
"new_t_address": "Nouvelle adresse-T",
|
||||||
|
"type": "Type",
|
||||||
|
"address": "Adresse",
|
||||||
|
"copy_address": "Copier l'adresse complète",
|
||||||
|
"send_from_this_address": "Envoyer depuis cette adresse",
|
||||||
|
"export_private_key": "Exporter la clé privée",
|
||||||
|
"export_viewing_key": "Exporter la clé de visualisation",
|
||||||
|
"show_qr_code": "Afficher le QR code",
|
||||||
|
"not_connected": "Non connecté au démon...",
|
||||||
|
|
||||||
|
"pay_from": "Payer depuis",
|
||||||
|
"send_to": "Envoyer à",
|
||||||
|
"amount": "Montant",
|
||||||
|
"memo": "Mémo (optionnel, chiffré)",
|
||||||
|
"miner_fee": "Frais de mineur",
|
||||||
|
"fee": "Frais",
|
||||||
|
"send_transaction": "Envoyer la transaction",
|
||||||
|
"clear": "Effacer",
|
||||||
|
"select_address": "Sélectionner une adresse...",
|
||||||
|
"paste": "Coller",
|
||||||
|
"max": "Max",
|
||||||
|
"available": "Disponible",
|
||||||
|
"invalid_address": "Format d'adresse invalide",
|
||||||
|
"memo_z_only": "Note : les mémos ne sont disponibles qu'en envoyant vers des adresses protégées (z)",
|
||||||
|
"characters": "caractères",
|
||||||
|
"from": "De",
|
||||||
|
"to": "À",
|
||||||
|
"sending": "Envoi de la transaction",
|
||||||
|
"confirm_send": "Confirmer l'envoi",
|
||||||
|
"confirm_transaction": "Confirmer la transaction",
|
||||||
|
"confirm_and_send": "Confirmer et envoyer",
|
||||||
|
"cancel": "Annuler",
|
||||||
|
|
||||||
|
"receiving_addresses": "Vos adresses de réception",
|
||||||
|
"new_z_shielded": "Nouvelle adresse-z (protégée)",
|
||||||
|
"new_t_transparent": "Nouvelle adresse-t (transparente)",
|
||||||
|
"address_details": "Détails de l'adresse",
|
||||||
|
"view_on_explorer": "Voir sur l'explorateur",
|
||||||
|
"qr_code": "QR Code",
|
||||||
|
"request_payment": "Demander un paiement",
|
||||||
|
|
||||||
|
"date": "Date",
|
||||||
|
"status": "Statut",
|
||||||
|
"confirmations": "Confirmations",
|
||||||
|
"confirmed": "Confirmée",
|
||||||
|
"pending": "En attente",
|
||||||
|
"sent": "envoyé",
|
||||||
|
"received": "reçu",
|
||||||
|
"mined": "miné",
|
||||||
|
|
||||||
|
"mining_control": "Contrôle du minage",
|
||||||
|
"start_mining": "Démarrer le minage",
|
||||||
|
"stop_mining": "Arrêter le minage",
|
||||||
|
"mining_threads": "Threads de minage",
|
||||||
|
"mining_statistics": "Statistiques de minage",
|
||||||
|
"local_hashrate": "Hashrate local",
|
||||||
|
"network_hashrate": "Hashrate du réseau",
|
||||||
|
"difficulty": "Difficulté",
|
||||||
|
"est_time_to_block": "Temps est. avant bloc",
|
||||||
|
"mining_off": "Minage DÉSACTIVÉ",
|
||||||
|
"mining_on": "Minage ACTIVÉ",
|
||||||
|
|
||||||
|
"connected_peers": "Nœuds connectés",
|
||||||
|
"banned_peers": "Nœuds bannis",
|
||||||
|
"ip_address": "Adresse IP",
|
||||||
|
"version": "Version",
|
||||||
|
"height": "Hauteur",
|
||||||
|
"ping": "Ping",
|
||||||
|
"ban": "Bannir",
|
||||||
|
"unban": "Débannir",
|
||||||
|
"clear_all_bans": "Lever tous les bannissements",
|
||||||
|
|
||||||
|
"price_chart": "Graphique des prix",
|
||||||
|
"current_price": "Prix actuel",
|
||||||
|
"24h_change": "Variation 24h",
|
||||||
|
"24h_volume": "Volume 24h",
|
||||||
|
"market_cap": "Capitalisation",
|
||||||
|
|
||||||
|
"general": "Général",
|
||||||
|
"display": "Affichage",
|
||||||
|
"network": "Réseau",
|
||||||
|
"theme": "Thème",
|
||||||
|
"language": "Langue",
|
||||||
|
"dragonx_green": "DragonX (Vert)",
|
||||||
|
"dark": "Sombre",
|
||||||
|
"light": "Clair",
|
||||||
|
"allow_custom_fees": "Autoriser les frais personnalisés",
|
||||||
|
"use_embedded_daemon": "Utiliser le dragonxd intégré",
|
||||||
|
"save": "Enregistrer",
|
||||||
|
"close": "Fermer",
|
||||||
|
|
||||||
|
"file": "Fichier",
|
||||||
|
"edit": "Édition",
|
||||||
|
"view": "Affichage",
|
||||||
|
"help": "Aide",
|
||||||
|
"import_private_key": "Importer une clé privée...",
|
||||||
|
"backup_wallet": "Sauvegarder le portefeuille...",
|
||||||
|
"exit": "Quitter",
|
||||||
|
"about_dragonx": "À propos d'ObsidianDragon",
|
||||||
|
"refresh_now": "Actualiser maintenant",
|
||||||
|
|
||||||
|
"about": "À propos",
|
||||||
|
"import": "Importer",
|
||||||
|
"export": "Exporter",
|
||||||
|
"copy_to_clipboard": "Copier dans le presse-papiers",
|
||||||
|
|
||||||
|
"connected": "Connecté",
|
||||||
|
"disconnected": "Déconnecté",
|
||||||
|
"connecting": "Connexion...",
|
||||||
|
"syncing": "Synchronisation...",
|
||||||
|
"block": "Bloc",
|
||||||
|
"no_addresses_available": "Aucune adresse disponible",
|
||||||
|
|
||||||
|
"error": "Erreur",
|
||||||
|
"success": "Succès",
|
||||||
|
"warning": "Avertissement",
|
||||||
|
"amount_exceeds_balance": "Le montant dépasse le solde",
|
||||||
|
"transaction_sent": "Transaction envoyée avec succès"
|
||||||
|
}
|
||||||
139
res/lang/ja.json
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
{
|
||||||
|
"balance": "残高",
|
||||||
|
"send": "送金",
|
||||||
|
"receive": "受取",
|
||||||
|
"transactions": "取引履歴",
|
||||||
|
"mining": "マイニング",
|
||||||
|
"peers": "ノード",
|
||||||
|
"market": "マーケット",
|
||||||
|
"settings": "設定",
|
||||||
|
|
||||||
|
"summary": "概要",
|
||||||
|
"shielded": "シールド",
|
||||||
|
"transparent": "トランスパレント",
|
||||||
|
"total": "合計",
|
||||||
|
"unconfirmed": "未確認",
|
||||||
|
"your_addresses": "アドレス一覧",
|
||||||
|
"z_addresses": "Z-アドレス",
|
||||||
|
"t_addresses": "T-アドレス",
|
||||||
|
"no_addresses": "アドレスが見つかりません。上のボタンで作成してください。",
|
||||||
|
"new_z_address": "新規 Z-アドレス",
|
||||||
|
"new_t_address": "新規 T-アドレス",
|
||||||
|
"type": "タイプ",
|
||||||
|
"address": "アドレス",
|
||||||
|
"copy_address": "アドレスをコピー",
|
||||||
|
"send_from_this_address": "このアドレスから送金",
|
||||||
|
"export_private_key": "秘密鍵をエクスポート",
|
||||||
|
"export_viewing_key": "閲覧鍵をエクスポート",
|
||||||
|
"show_qr_code": "QRコードを表示",
|
||||||
|
"not_connected": "デーモンに未接続...",
|
||||||
|
|
||||||
|
"pay_from": "支払元",
|
||||||
|
"send_to": "送金先",
|
||||||
|
"amount": "金額",
|
||||||
|
"memo": "メモ(任意、暗号化)",
|
||||||
|
"miner_fee": "マイナー手数料",
|
||||||
|
"fee": "手数料",
|
||||||
|
"send_transaction": "送金する",
|
||||||
|
"clear": "クリア",
|
||||||
|
"select_address": "アドレスを選択...",
|
||||||
|
"paste": "貼り付け",
|
||||||
|
"max": "最大",
|
||||||
|
"available": "利用可能",
|
||||||
|
"invalid_address": "無効なアドレス形式",
|
||||||
|
"memo_z_only": "注:メモはシールド(z)アドレスへの送金時のみ利用可能です",
|
||||||
|
"characters": "文字",
|
||||||
|
"from": "送金元",
|
||||||
|
"to": "送金先",
|
||||||
|
"sending": "送金中",
|
||||||
|
"confirm_send": "送金確認",
|
||||||
|
"confirm_transaction": "取引確認",
|
||||||
|
"confirm_and_send": "確認して送金",
|
||||||
|
"cancel": "キャンセル",
|
||||||
|
|
||||||
|
"receiving_addresses": "受取アドレス",
|
||||||
|
"new_z_shielded": "新規 z-アドレス(シールド)",
|
||||||
|
"new_t_transparent": "新規 t-アドレス(トランスパレント)",
|
||||||
|
"address_details": "アドレス詳細",
|
||||||
|
"view_on_explorer": "エクスプローラーで表示",
|
||||||
|
"qr_code": "QRコード",
|
||||||
|
"request_payment": "支払いを要求",
|
||||||
|
|
||||||
|
"date": "日付",
|
||||||
|
"status": "ステータス",
|
||||||
|
"confirmations": "確認数",
|
||||||
|
"confirmed": "確認済み",
|
||||||
|
"pending": "保留中",
|
||||||
|
"sent": "送金済",
|
||||||
|
"received": "受取済",
|
||||||
|
"mined": "採掘済",
|
||||||
|
|
||||||
|
"mining_control": "マイニング制御",
|
||||||
|
"start_mining": "マイニング開始",
|
||||||
|
"stop_mining": "マイニング停止",
|
||||||
|
"mining_threads": "マイニングスレッド",
|
||||||
|
"mining_statistics": "マイニング統計",
|
||||||
|
"local_hashrate": "ローカルハッシュレート",
|
||||||
|
"network_hashrate": "ネットワークハッシュレート",
|
||||||
|
"difficulty": "難易度",
|
||||||
|
"est_time_to_block": "推定ブロック発見時間",
|
||||||
|
"mining_off": "マイニング停止中",
|
||||||
|
"mining_on": "マイニング稼働中",
|
||||||
|
|
||||||
|
"connected_peers": "接続中のノード",
|
||||||
|
"banned_peers": "ブロック済みノード",
|
||||||
|
"ip_address": "IPアドレス",
|
||||||
|
"version": "バージョン",
|
||||||
|
"height": "ブロック高",
|
||||||
|
"ping": "Ping",
|
||||||
|
"ban": "ブロック",
|
||||||
|
"unban": "ブロック解除",
|
||||||
|
"clear_all_bans": "すべてのブロックを解除",
|
||||||
|
|
||||||
|
"price_chart": "価格チャート",
|
||||||
|
"current_price": "現在価格",
|
||||||
|
"24h_change": "24時間変動",
|
||||||
|
"24h_volume": "24時間取引量",
|
||||||
|
"market_cap": "時価総額",
|
||||||
|
|
||||||
|
"general": "一般",
|
||||||
|
"display": "表示",
|
||||||
|
"network": "ネットワーク",
|
||||||
|
"theme": "テーマ",
|
||||||
|
"language": "言語",
|
||||||
|
"dragonx_green": "DragonX(グリーン)",
|
||||||
|
"dark": "ダーク",
|
||||||
|
"light": "ライト",
|
||||||
|
"allow_custom_fees": "カスタム手数料を許可",
|
||||||
|
"use_embedded_daemon": "内蔵 dragonxd を使用",
|
||||||
|
"save": "保存",
|
||||||
|
"close": "閉じる",
|
||||||
|
|
||||||
|
"file": "ファイル",
|
||||||
|
"edit": "編集",
|
||||||
|
"view": "表示",
|
||||||
|
"help": "ヘルプ",
|
||||||
|
"import_private_key": "秘密鍵をインポート...",
|
||||||
|
"backup_wallet": "ウォレットをバックアップ...",
|
||||||
|
"exit": "終了",
|
||||||
|
"about_dragonx": "ObsidianDragonについて",
|
||||||
|
"refresh_now": "今すぐ更新",
|
||||||
|
|
||||||
|
"about": "このアプリについて",
|
||||||
|
"import": "インポート",
|
||||||
|
"export": "エクスポート",
|
||||||
|
"copy_to_clipboard": "クリップボードにコピー",
|
||||||
|
|
||||||
|
"connected": "接続済み",
|
||||||
|
"disconnected": "切断",
|
||||||
|
"connecting": "接続中...",
|
||||||
|
"syncing": "同期中...",
|
||||||
|
"block": "ブロック",
|
||||||
|
"no_addresses_available": "利用可能なアドレスがありません",
|
||||||
|
|
||||||
|
"error": "エラー",
|
||||||
|
"success": "成功",
|
||||||
|
"warning": "警告",
|
||||||
|
"amount_exceeds_balance": "金額が残高を超えています",
|
||||||
|
"transaction_sent": "送金が完了しました"
|
||||||
|
}
|
||||||
139
res/lang/ko.json
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
{
|
||||||
|
"balance": "잔액",
|
||||||
|
"send": "보내기",
|
||||||
|
"receive": "받기",
|
||||||
|
"transactions": "거래 내역",
|
||||||
|
"mining": "채굴",
|
||||||
|
"peers": "노드",
|
||||||
|
"market": "시장",
|
||||||
|
"settings": "설정",
|
||||||
|
|
||||||
|
"summary": "요약",
|
||||||
|
"shielded": "차폐됨",
|
||||||
|
"transparent": "투명",
|
||||||
|
"total": "합계",
|
||||||
|
"unconfirmed": "미확인",
|
||||||
|
"your_addresses": "내 주소",
|
||||||
|
"z_addresses": "Z-주소",
|
||||||
|
"t_addresses": "T-주소",
|
||||||
|
"no_addresses": "주소를 찾을 수 없습니다. 위의 버튼을 사용하여 생성하세요.",
|
||||||
|
"new_z_address": "새 Z-주소",
|
||||||
|
"new_t_address": "새 T-주소",
|
||||||
|
"type": "유형",
|
||||||
|
"address": "주소",
|
||||||
|
"copy_address": "전체 주소 복사",
|
||||||
|
"send_from_this_address": "이 주소에서 보내기",
|
||||||
|
"export_private_key": "개인키 내보내기",
|
||||||
|
"export_viewing_key": "조회키 내보내기",
|
||||||
|
"show_qr_code": "QR 코드 표시",
|
||||||
|
"not_connected": "데몬에 연결되지 않음...",
|
||||||
|
|
||||||
|
"pay_from": "출금 주소",
|
||||||
|
"send_to": "받는 주소",
|
||||||
|
"amount": "금액",
|
||||||
|
"memo": "메모 (선택사항, 암호화됨)",
|
||||||
|
"miner_fee": "채굴자 수수료",
|
||||||
|
"fee": "수수료",
|
||||||
|
"send_transaction": "거래 보내기",
|
||||||
|
"clear": "지우기",
|
||||||
|
"select_address": "주소 선택...",
|
||||||
|
"paste": "붙여넣기",
|
||||||
|
"max": "최대",
|
||||||
|
"available": "사용 가능",
|
||||||
|
"invalid_address": "잘못된 주소 형식",
|
||||||
|
"memo_z_only": "참고: 메모는 차폐(z) 주소로 보낼 때만 사용할 수 있습니다",
|
||||||
|
"characters": "글자",
|
||||||
|
"from": "보낸 사람",
|
||||||
|
"to": "받는 사람",
|
||||||
|
"sending": "거래 전송 중",
|
||||||
|
"confirm_send": "보내기 확인",
|
||||||
|
"confirm_transaction": "거래 확인",
|
||||||
|
"confirm_and_send": "확인 및 보내기",
|
||||||
|
"cancel": "취소",
|
||||||
|
|
||||||
|
"receiving_addresses": "수신 주소",
|
||||||
|
"new_z_shielded": "새 z-주소 (차폐)",
|
||||||
|
"new_t_transparent": "새 t-주소 (투명)",
|
||||||
|
"address_details": "주소 상세",
|
||||||
|
"view_on_explorer": "탐색기에서 보기",
|
||||||
|
"qr_code": "QR 코드",
|
||||||
|
"request_payment": "결제 요청",
|
||||||
|
|
||||||
|
"date": "날짜",
|
||||||
|
"status": "상태",
|
||||||
|
"confirmations": "확인 수",
|
||||||
|
"confirmed": "확인됨",
|
||||||
|
"pending": "대기 중",
|
||||||
|
"sent": "보냄",
|
||||||
|
"received": "받음",
|
||||||
|
"mined": "채굴됨",
|
||||||
|
|
||||||
|
"mining_control": "채굴 제어",
|
||||||
|
"start_mining": "채굴 시작",
|
||||||
|
"stop_mining": "채굴 중지",
|
||||||
|
"mining_threads": "채굴 스레드",
|
||||||
|
"mining_statistics": "채굴 통계",
|
||||||
|
"local_hashrate": "로컬 해시레이트",
|
||||||
|
"network_hashrate": "네트워크 해시레이트",
|
||||||
|
"difficulty": "난이도",
|
||||||
|
"est_time_to_block": "예상 블록 발견 시간",
|
||||||
|
"mining_off": "채굴 꺼짐",
|
||||||
|
"mining_on": "채굴 켜짐",
|
||||||
|
|
||||||
|
"connected_peers": "연결된 노드",
|
||||||
|
"banned_peers": "차단된 노드",
|
||||||
|
"ip_address": "IP 주소",
|
||||||
|
"version": "버전",
|
||||||
|
"height": "블록 높이",
|
||||||
|
"ping": "핑",
|
||||||
|
"ban": "차단",
|
||||||
|
"unban": "차단 해제",
|
||||||
|
"clear_all_bans": "모든 차단 해제",
|
||||||
|
|
||||||
|
"price_chart": "가격 차트",
|
||||||
|
"current_price": "현재 가격",
|
||||||
|
"24h_change": "24시간 변동",
|
||||||
|
"24h_volume": "24시간 거래량",
|
||||||
|
"market_cap": "시가총액",
|
||||||
|
|
||||||
|
"general": "일반",
|
||||||
|
"display": "화면",
|
||||||
|
"network": "네트워크",
|
||||||
|
"theme": "테마",
|
||||||
|
"language": "언어",
|
||||||
|
"dragonx_green": "DragonX (녹색)",
|
||||||
|
"dark": "다크",
|
||||||
|
"light": "라이트",
|
||||||
|
"allow_custom_fees": "사용자 수수료 허용",
|
||||||
|
"use_embedded_daemon": "내장 dragonxd 사용",
|
||||||
|
"save": "저장",
|
||||||
|
"close": "닫기",
|
||||||
|
|
||||||
|
"file": "파일",
|
||||||
|
"edit": "편집",
|
||||||
|
"view": "보기",
|
||||||
|
"help": "도움말",
|
||||||
|
"import_private_key": "개인키 가져오기...",
|
||||||
|
"backup_wallet": "지갑 백업...",
|
||||||
|
"exit": "종료",
|
||||||
|
"about_dragonx": "ObsidianDragon 정보",
|
||||||
|
"refresh_now": "지금 새로고침",
|
||||||
|
|
||||||
|
"about": "정보",
|
||||||
|
"import": "가져오기",
|
||||||
|
"export": "내보내기",
|
||||||
|
"copy_to_clipboard": "클립보드에 복사",
|
||||||
|
|
||||||
|
"connected": "연결됨",
|
||||||
|
"disconnected": "연결 끊김",
|
||||||
|
"connecting": "연결 중...",
|
||||||
|
"syncing": "동기화 중...",
|
||||||
|
"block": "블록",
|
||||||
|
"no_addresses_available": "사용 가능한 주소 없음",
|
||||||
|
|
||||||
|
"error": "오류",
|
||||||
|
"success": "성공",
|
||||||
|
"warning": "경고",
|
||||||
|
"amount_exceeds_balance": "금액이 잔액을 초과합니다",
|
||||||
|
"transaction_sent": "거래가 성공적으로 전송되었습니다"
|
||||||
|
}
|
||||||
139
res/lang/pt.json
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
{
|
||||||
|
"balance": "Saldo",
|
||||||
|
"send": "Enviar",
|
||||||
|
"receive": "Receber",
|
||||||
|
"transactions": "Transações",
|
||||||
|
"mining": "Mineração",
|
||||||
|
"peers": "Nós",
|
||||||
|
"market": "Mercado",
|
||||||
|
"settings": "Configurações",
|
||||||
|
|
||||||
|
"summary": "Resumo",
|
||||||
|
"shielded": "Protegido",
|
||||||
|
"transparent": "Transparente",
|
||||||
|
"total": "Total",
|
||||||
|
"unconfirmed": "Não confirmado",
|
||||||
|
"your_addresses": "Seus endereços",
|
||||||
|
"z_addresses": "Endereços-Z",
|
||||||
|
"t_addresses": "Endereços-T",
|
||||||
|
"no_addresses": "Nenhum endereço encontrado. Crie um usando os botões acima.",
|
||||||
|
"new_z_address": "Novo endereço-Z",
|
||||||
|
"new_t_address": "Novo endereço-T",
|
||||||
|
"type": "Tipo",
|
||||||
|
"address": "Endereço",
|
||||||
|
"copy_address": "Copiar endereço completo",
|
||||||
|
"send_from_this_address": "Enviar deste endereço",
|
||||||
|
"export_private_key": "Exportar chave privada",
|
||||||
|
"export_viewing_key": "Exportar chave de visualização",
|
||||||
|
"show_qr_code": "Mostrar código QR",
|
||||||
|
"not_connected": "Não conectado ao daemon...",
|
||||||
|
|
||||||
|
"pay_from": "Pagar de",
|
||||||
|
"send_to": "Enviar para",
|
||||||
|
"amount": "Valor",
|
||||||
|
"memo": "Memo (opcional, criptografado)",
|
||||||
|
"miner_fee": "Taxa do minerador",
|
||||||
|
"fee": "Taxa",
|
||||||
|
"send_transaction": "Enviar transação",
|
||||||
|
"clear": "Limpar",
|
||||||
|
"select_address": "Selecionar endereço...",
|
||||||
|
"paste": "Colar",
|
||||||
|
"max": "Máx.",
|
||||||
|
"available": "Disponível",
|
||||||
|
"invalid_address": "Formato de endereço inválido",
|
||||||
|
"memo_z_only": "Nota: memos só estão disponíveis ao enviar para endereços protegidos (z)",
|
||||||
|
"characters": "caracteres",
|
||||||
|
"from": "De",
|
||||||
|
"to": "Para",
|
||||||
|
"sending": "Enviando transação",
|
||||||
|
"confirm_send": "Confirmar envio",
|
||||||
|
"confirm_transaction": "Confirmar transação",
|
||||||
|
"confirm_and_send": "Confirmar e enviar",
|
||||||
|
"cancel": "Cancelar",
|
||||||
|
|
||||||
|
"receiving_addresses": "Seus endereços de recebimento",
|
||||||
|
"new_z_shielded": "Novo endereço-z (protegido)",
|
||||||
|
"new_t_transparent": "Novo endereço-t (transparente)",
|
||||||
|
"address_details": "Detalhes do endereço",
|
||||||
|
"view_on_explorer": "Ver no explorador",
|
||||||
|
"qr_code": "Código QR",
|
||||||
|
"request_payment": "Solicitar pagamento",
|
||||||
|
|
||||||
|
"date": "Data",
|
||||||
|
"status": "Status",
|
||||||
|
"confirmations": "Confirmações",
|
||||||
|
"confirmed": "Confirmada",
|
||||||
|
"pending": "Pendente",
|
||||||
|
"sent": "enviado",
|
||||||
|
"received": "recebido",
|
||||||
|
"mined": "minerado",
|
||||||
|
|
||||||
|
"mining_control": "Controle de mineração",
|
||||||
|
"start_mining": "Iniciar mineração",
|
||||||
|
"stop_mining": "Parar mineração",
|
||||||
|
"mining_threads": "Threads de mineração",
|
||||||
|
"mining_statistics": "Estatísticas de mineração",
|
||||||
|
"local_hashrate": "Hashrate local",
|
||||||
|
"network_hashrate": "Hashrate da rede",
|
||||||
|
"difficulty": "Dificuldade",
|
||||||
|
"est_time_to_block": "Tempo est. até o bloco",
|
||||||
|
"mining_off": "Mineração DESLIGADA",
|
||||||
|
"mining_on": "Mineração LIGADA",
|
||||||
|
|
||||||
|
"connected_peers": "Nós conectados",
|
||||||
|
"banned_peers": "Nós banidos",
|
||||||
|
"ip_address": "Endereço IP",
|
||||||
|
"version": "Versão",
|
||||||
|
"height": "Altura",
|
||||||
|
"ping": "Ping",
|
||||||
|
"ban": "Banir",
|
||||||
|
"unban": "Desbanir",
|
||||||
|
"clear_all_bans": "Remover todos os banimentos",
|
||||||
|
|
||||||
|
"price_chart": "Gráfico de preço",
|
||||||
|
"current_price": "Preço atual",
|
||||||
|
"24h_change": "Variação 24h",
|
||||||
|
"24h_volume": "Volume 24h",
|
||||||
|
"market_cap": "Cap. de mercado",
|
||||||
|
|
||||||
|
"general": "Geral",
|
||||||
|
"display": "Exibição",
|
||||||
|
"network": "Rede",
|
||||||
|
"theme": "Tema",
|
||||||
|
"language": "Idioma",
|
||||||
|
"dragonx_green": "DragonX (Verde)",
|
||||||
|
"dark": "Escuro",
|
||||||
|
"light": "Claro",
|
||||||
|
"allow_custom_fees": "Permitir taxas personalizadas",
|
||||||
|
"use_embedded_daemon": "Usar dragonxd embutido",
|
||||||
|
"save": "Salvar",
|
||||||
|
"close": "Fechar",
|
||||||
|
|
||||||
|
"file": "Arquivo",
|
||||||
|
"edit": "Editar",
|
||||||
|
"view": "Exibir",
|
||||||
|
"help": "Ajuda",
|
||||||
|
"import_private_key": "Importar chave privada...",
|
||||||
|
"backup_wallet": "Fazer backup da carteira...",
|
||||||
|
"exit": "Sair",
|
||||||
|
"about_dragonx": "Sobre ObsidianDragon",
|
||||||
|
"refresh_now": "Atualizar agora",
|
||||||
|
|
||||||
|
"about": "Sobre",
|
||||||
|
"import": "Importar",
|
||||||
|
"export": "Exportar",
|
||||||
|
"copy_to_clipboard": "Copiar para área de transferência",
|
||||||
|
|
||||||
|
"connected": "Conectado",
|
||||||
|
"disconnected": "Desconectado",
|
||||||
|
"connecting": "Conectando...",
|
||||||
|
"syncing": "Sincronizando...",
|
||||||
|
"block": "Bloco",
|
||||||
|
"no_addresses_available": "Nenhum endereço disponível",
|
||||||
|
|
||||||
|
"error": "Erro",
|
||||||
|
"success": "Sucesso",
|
||||||
|
"warning": "Aviso",
|
||||||
|
"amount_exceeds_balance": "Valor excede o saldo",
|
||||||
|
"transaction_sent": "Transação enviada com sucesso"
|
||||||
|
}
|
||||||