Jackalope / jrf (public) (License: GPLv3 or later version) (since 2019-11-21) (hash sha1)
Libriary for reading and writing resource files: vertices, indices, meshes, images, models and scene data.
Supports reading from filesystem as well as from zip files.
It uses unique binary container format for those resources.
It is used in tool for converting popular formats like wavefront .obj file, TARGA image to this container and also used in resource loader as part of graphics framework.

It requires jlib libriary (see my user repositories) and libzip.
It is possible to remove libzip dependency.
List of commits:
Subject Hash Author Date (UTC)
convert image from tga and add alpha channel functions 4541972149b6b19afda05c608d4abe88a72098bb Jackalope 2020-05-11 07:49:43
more image formats 77bf7ec016cfb604e4a8e06734a4eb71bb299df0 Jackalope 2020-05-11 07:48:46
added license d7c63a0b6199c7f5c1680559953eef1699ec9a48 Jackalope 2020-05-10 01:01:00
refactoring 66f541c32f51d6ed6f90fba1f3b58561726e8659 Jackalope 2020-05-10 00:55:34
extra vertices check c3bd2141d2eaeb96beb5c8ad29e3333c015db4c8 jp.larry 2019-12-26 14:38:29
removed dead code f4ddde689122f1b96fda5292e69f612bf2ca327d jp.larry 2019-12-26 14:38:06
removed forgotten vertex data_size writing 25244188b395b6cca35502f4156d3e78cc1e74ec jp.larry 2019-12-26 13:19:31
better read errors d6d7bc5df695d694ea0dee225905212ef1dfe41b jp.larry 2019-12-26 13:18:55
changed vertices file structure to prevent undefined behaviour 603e283ccf234f87f6e8c38a669280be36a5aafb jp.larry 2019-12-26 12:35:05
vertex attributes is separated, not inteleaved now d3e7b79c74e9fae7b8b788d1a55db2e664feb107 jp.larry 2019-12-26 01:19:17
compiled on windows with mingw 51eacaf02dd542415cea1edd615d88234fb5b344 Jackalope 2019-12-15 07:05:58
added mesh to read and write functions 173144a8516441420feb4327a66d26fa3f57376d Your Name 2019-12-07 22:09:04
warning hidden by implicit cast f49b32439aa1e8719bd340da9fc3bb7e9b906d0d Your Name 2019-12-07 21:01:08
Vertices have vertices count value cf3b63932cdcdb88b72e70df93a4dd8b478d163b jp.larry 2019-12-07 16:02:55
removed IndicesArrays, added Mesh resource and Vertices attributes is not dynamically allocated a54a61cfc285bbec4246b1affdc5fe9251c059d0 jp.larry 2019-12-06 17:04:06
new obj file error f4385161fdd1ad8038e2d0924e1d3de2a6506cc9 Your Name 2019-12-01 10:26:18
scene issues solved cef4ba84d44cbdc6690c87e553df9fbfba60059f Your Name 2019-12-01 04:19:29
changed transformation matrix to 4x4 from 3x3 5b5728dabefb471cf126bf4b524f5079a14c0735 Your Name 2019-11-30 15:16:50
added missing return 94644ed6f61207f664ac4675fa015afbe017ddea jp.larry 2019-11-29 09:03:14
scene improvements, changed shift type to unsigned, set default-value funtions, model must be path a2708b94b88eb0ede73b9aab396e7a13f13baa52 Your Name 2019-11-29 09:27:32
Commit 4541972149b6b19afda05c608d4abe88a72098bb - convert image from tga and add alpha channel functions
Author: Jackalope
Author date (UTC): 2020-05-11 07:49
Committer name: Jackalope
Committer date (UTC): 2020-05-11 07:49
Parent(s): 77bf7ec016cfb604e4a8e06734a4eb71bb299df0
Signing key:
Tree: 903b90e84ad51c614703f5b9146e7e1d59197803
File Lines added Lines deleted
CMakeLists.txt 5 2
include/jrf/convert.h 14 0
include/jrf/result.h 1 0
src/convert.cpp 97 0
File CMakeLists.txt changed (mode: 100644) (index 96f88e8..84ba957)
1 1 cmake_minimum_required(VERSION 3.5) cmake_minimum_required(VERSION 3.5)
2 2 set(JRF_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/include PARENT_SCOPE) set(JRF_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/include PARENT_SCOPE)
3 add_library(JRF STATIC src/result.cpp)
4 target_include_directories(JRF PUBLIC include ${LIBZIP_INCLUDE_DIR})
3 add_library(JRF STATIC src/result.cpp src/convert.cpp)
4 target_include_directories(JRF PUBLIC include
5 ${JLIB_INCLUDE_DIRS}
6 ${LIBZIP_INCLUDE_DIR}
7 )
5 8 target_link_libraries(JRF ${LIBZIP_INCLUDE_LIBS}) target_link_libraries(JRF ${LIBZIP_INCLUDE_LIBS})
File include/jrf/convert.h added (mode: 100644) (index 0000000..a1daf82)
1 #pragma once
2 #include "image.h"
3 #include <jlib/rarray.h>
4
5 namespace jrf::convert {
6 /// @return possible values: SUCCESS, FILE_UNEXPECTED_EOF,
7 /// COLOR_MAP_UNSUPPORTED, IMAGE_DATA_TYPE_UNSUPPORTED
8 /// TGA_RLE_UNSUPPORTED, PIXEL_SIZE_UNSUPPORTED
9 [[nodiscard]] Result
10 from_tga(const jl::byte_array_ro &data, Image* p_dst);
11
12 [[nodiscard]] Result
13 add_alpha_channel(const Image &src, Image *p_dst);
14 }
File include/jrf/result.h changed (mode: 100644) (index a8ae8e3..e06fb51)
... ... namespace jrf
87 87 ALLOCATION_FAIL, ALLOCATION_FAIL,
88 88
89 89 //image //image
90 FORMAT_UNSUPPORTED,
90 91 COLOR_MAP_UNSUPPORTED, COLOR_MAP_UNSUPPORTED,
91 92 IMAGE_DATA_TYPE_UNSUPPORTED, IMAGE_DATA_TYPE_UNSUPPORTED,
92 93 PIXEL_SIZE_UNSUPPORTED, PIXEL_SIZE_UNSUPPORTED,
File src/convert.cpp added (mode: 100644) (index 0000000..5534b9a)
1 #include <jrf/convert.h>
2
3 struct TGA_header {
4 enum DataType : uint8_t {
5 NO_IMAGE_DATA = 0b0000, ///< no image data is present
6 COLOR_MAPPED = 0b0001, ///< uncompressed color-mapped
7 TRUE_COLOR = 0b0010, ///< uncompressed true-color
8 BLACK_AND_WHITE = 0b0011, ///< uncompressed black-and-white (grayscale)
9 RLE_BIT = 0b1000, ///< run-length encoded
10
11 TYPE_MASK = 0b0011, ///< for type check without RLE filter
12 };
13
14 uint8_t id_length;
15 uint8_t colormap_type;
16 DataType data_type;
17 uint8_t colormap_specification[5];
18 uint8_t x_origin[2];
19 uint8_t y_origin[2];
20 uint16_t width;
21 uint16_t height;
22 uint8_t pixel_size_reversed;
23 uint8_t descriptor;
24 };
25 static_assert (offsetof(TGA_header,width) == 8+4, "for correct bytes reading");
26 static_assert (sizeof(TGA_header) == 18, "for correct bytes reading");
27
28 [[nodiscard]] jrf::Result jrf::convert::
29 from_tga(const jl::byte_array_ro &data, Image *p_dst) {
30 TGA_header header;
31 constexpr static const uint64_t HEADER_SIZE = sizeof(header);
32 if (data.count() < HEADER_SIZE)
33 return Result::FILE_UNEXPECTED_EOF;
34 memcpy(&header, data.begin(), sizeof(header));
35
36 if (header.colormap_type != 0) // if image file has color map
37 return Result::COLOR_MAP_UNSUPPORTED;
38 if ((header.data_type & TGA_header::TYPE_MASK) != TGA_header::TRUE_COLOR)
39 return Result::IMAGE_DATA_TYPE_UNSUPPORTED;
40 if (header.data_type & TGA_header::RLE_BIT)
41 return Result::TGA_RLE_UNSUPPORTED;
42 auto reverseByte = [](uint8_t byte) {
43 byte = uint8_t((byte & 0xF0) >> 4 | (byte & 0x0F) << 4); // NOLINT
44 byte = uint8_t((byte & 0xCC) >> 2 | (byte & 0x33) << 2); // NOLINT
45 byte = uint8_t((byte & 0xAA) >> 1 | (byte & 0x55) << 1); // NOLINT
46 return byte;
47 };
48 Image::Extent extent;
49 extent.width = header.width;
50 extent.height = header.height;
51 extent.depth = 1;
52 extent.pixelSize = reverseByte(header.pixel_size_reversed);
53 if (extent.pixelSize >= 8)
54 extent.pixelSize /= 8;
55 Image::Format format;
56 switch (extent.pixelSize) {
57 case 3: format = Image::Format::B8G8R8_UINT;
58 break;
59 case 4: format = Image::Format::B8G8R8A8_UINT;
60 break;
61 default: return Result::PIXEL_SIZE_UNSUPPORTED;
62 }
63 uint64_t pixels_size = extent.size();
64 if (data.count() - HEADER_SIZE < pixels_size)
65 return Result::FILE_UNEXPECTED_EOF;
66 if (not p_dst->init(extent, format))
67 return Result::ALLOCATION_FAIL;
68 memcpy(p_dst->p_pixels, data.begin() + HEADER_SIZE, pixels_size);
69 return Result::SUCCESS;
70 }
71 [[nodiscard]] jrf::Result jrf::convert::
72 add_alpha_channel(const Image &src, Image *p_dst) {
73 Image::Format result_format;
74 switch(src.format) {
75 case Image::Format::B8G8R8_SRGB:
76 result_format = Image::Format::B8G8R8A8_SRGB; break;
77 case Image::Format::B8G8R8_UINT:
78 result_format = Image::Format::B8G8R8A8_UINT; break;
79 default: return FORMAT_UNSUPPORTED;
80 }
81 *p_dst = src;
82 p_dst->format = result_format;
83 p_dst->extent.pixelSize += 1;
84 p_dst->size = p_dst->extent.size();
85 if (not jl::allocate_bytes(&p_dst->p_pixels, p_dst->size))
86 return Result::ALLOCATION_FAIL;
87 uint8_t *p_src = src.p_pixels;
88 for (uint8_t *p_dst_pixels = p_dst->p_pixels;
89 p_dst_pixels < p_dst->p_pixels + p_dst->size;) {
90 memcpy(p_dst_pixels, p_src, 3);
91 p_src += 3;
92 p_dst_pixels += 3;
93 memset(p_dst_pixels, 255, 1);
94 p_dst_pixels += 1;
95 }
96 return Result::SUCCESS;
97 }
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/Jackalope/jrf

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/Jackalope/jrf

Clone this repository using git:
git clone git://git.rocketgit.com/user/Jackalope/jrf

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main