File include/jrf/convert.h changed (mode: 100644) (index e6b5751..386cc29) |
20 |
20 |
#include "image.h" |
#include "image.h" |
21 |
21 |
#include "result.h" |
#include "result.h" |
22 |
22 |
#include <jlib/rarray.h> |
#include <jlib/rarray.h> |
|
23 |
|
#include <jlib/string.h> |
23 |
24 |
|
|
24 |
25 |
namespace jrf::convert { |
namespace jrf::convert { |
25 |
26 |
/// @return possible values: SUCCESS, FILE_UNEXPECTED_EOF, |
/// @return possible values: SUCCESS, FILE_UNEXPECTED_EOF, |
26 |
27 |
/// COLOR_MAP_UNSUPPORTED, IMAGE_DATA_TYPE_UNSUPPORTED |
/// COLOR_MAP_UNSUPPORTED, IMAGE_DATA_TYPE_UNSUPPORTED |
27 |
28 |
/// TGA_RLE_UNSUPPORTED, PIXEL_SIZE_UNSUPPORTED |
/// TGA_RLE_UNSUPPORTED, PIXEL_SIZE_UNSUPPORTED |
28 |
29 |
[[nodiscard]] Result |
[[nodiscard]] Result |
29 |
|
from_tga(const jl::byte_array_ro &data, Image* p_dst); |
|
|
30 |
|
from_tga(jl::byte_array_ro data, Image* p_out_image); |
30 |
31 |
|
|
|
32 |
|
/// @brief Convert array of images to image array. |
|
33 |
|
/// @param src Images with equal extent and equal format. |
31 |
34 |
[[nodiscard]] Result |
[[nodiscard]] Result |
32 |
|
add_alpha_channel(const Image &src, Image *p_dst); |
|
|
35 |
|
to_array(jl::rarray<const Image> src, Image *p_out_image); |
|
36 |
|
|
|
37 |
|
[[nodiscard]] Result |
|
38 |
|
from_tga(jl::rarray<const char*> file_paths, Image *p_out_image, |
|
39 |
|
size_t *p_out_err_file_i); |
|
40 |
|
|
|
41 |
|
|
|
42 |
|
[[nodiscard]] Result |
|
43 |
|
add_alpha_channel(const Image &src, Image *p_out_image); |
33 |
44 |
} |
} |
File src/convert.cpp changed (mode: 100644) (index 1c78579..2874c2a) |
17 |
17 |
* along with this library. If not, see <https://www.gnu.org/licenses/> |
* along with this library. If not, see <https://www.gnu.org/licenses/> |
18 |
18 |
*/ |
*/ |
19 |
19 |
#include <jrf/convert.h> |
#include <jrf/convert.h> |
|
20 |
|
#include <jlib/fs.h> |
20 |
21 |
|
|
21 |
22 |
struct TGA_header { |
struct TGA_header { |
22 |
23 |
enum DataType : uint8_t { |
enum DataType : uint8_t { |
|
... |
... |
static_assert (offsetof(TGA_header,width) == 8+4, "for correct bytes reading"); |
44 |
45 |
static_assert (sizeof(TGA_header) == 18, "for correct bytes reading"); |
static_assert (sizeof(TGA_header) == 18, "for correct bytes reading"); |
45 |
46 |
|
|
46 |
47 |
[[nodiscard]] jrf::Result jrf::convert:: |
[[nodiscard]] jrf::Result jrf::convert:: |
47 |
|
from_tga(const jl::byte_array_ro &data, Image *p_dst) { |
|
|
48 |
|
from_tga(jl::byte_array_ro data, Image *p_dst) { |
48 |
49 |
TGA_header header; |
TGA_header header; |
49 |
50 |
constexpr static const uint64_t HEADER_SIZE = sizeof(header); |
constexpr static const uint64_t HEADER_SIZE = sizeof(header); |
50 |
51 |
if (data.count() < HEADER_SIZE) |
if (data.count() < HEADER_SIZE) |
|
... |
... |
from_tga(const jl::byte_array_ro &data, Image *p_dst) { |
100 |
101 |
} while (p_p < p_end); |
} while (p_p < p_end); |
101 |
102 |
return Result::SUCCESS; |
return Result::SUCCESS; |
102 |
103 |
} |
} |
|
104 |
|
|
103 |
105 |
[[nodiscard]] jrf::Result jrf::convert:: |
[[nodiscard]] jrf::Result jrf::convert:: |
104 |
106 |
add_alpha_channel(const Image &src, Image *p_dst) { |
add_alpha_channel(const Image &src, Image *p_dst) { |
105 |
107 |
Image::Format result_format; |
Image::Format result_format; |
|
... |
... |
add_alpha_channel(const Image &src, Image *p_dst) { |
125 |
127 |
} |
} |
126 |
128 |
return Result::SUCCESS; |
return Result::SUCCESS; |
127 |
129 |
} |
} |
|
130 |
|
|
|
131 |
|
[[nodiscard]] jrf::Result jrf::convert:: |
|
132 |
|
to_array(const jl::rarray<const Image> src, Image *p_dst) { |
|
133 |
|
auto fin_extent = src[0].extent; |
|
134 |
|
fin_extent.depth = uint16_t(src.count()); |
|
135 |
|
if (not p_dst->init(fin_extent, src[0].format)) |
|
136 |
|
return Result::ALLOCATION_FAIL; |
|
137 |
|
auto p = reinterpret_cast<uint8_t*>(p_dst->p_pixels); |
|
138 |
|
for(uint16_t j = 0; j < src.count(); ++j) { |
|
139 |
|
auto &image = src[j]; |
|
140 |
|
memcpy(p, image.p_pixels, image.size); |
|
141 |
|
p = &p[image.size]; |
|
142 |
|
} |
|
143 |
|
return Result::SUCCESS; |
|
144 |
|
} |
|
145 |
|
|
|
146 |
|
[[nodiscard]] jrf::Result jrf::convert:: |
|
147 |
|
from_tga(jl::rarray<const char*> files, Image *p_dst, size_t *p_err_i) { |
|
148 |
|
Result res; |
|
149 |
|
*p_err_i = 0; |
|
150 |
|
|
|
151 |
|
if (files.count() == 0) |
|
152 |
|
return Result::MISSING_ARGUMENTS; |
|
153 |
|
if (files.count() > jrf::Image::DEPTH_LIMIT) |
|
154 |
|
return Result::TOO_MANY_ARGUMENTS; |
|
155 |
|
|
|
156 |
|
Image *p_ims_tmp; |
|
157 |
|
if (not jl::allocate(&p_ims_tmp, files.count())) |
|
158 |
|
return Result::ALLOCATION_FAIL; |
|
159 |
|
|
|
160 |
|
size_t i = 0; |
|
161 |
|
for (; i < files.count(); ++i) { |
|
162 |
|
uint8_t *p_data; |
|
163 |
|
uint64_t size; |
|
164 |
|
if (not jfs::read_file(files[i], &p_data, &size)) { |
|
165 |
|
fprintf(stderr, "Error while reading file: %s", jfs::error_str()); |
|
166 |
|
res = Result::FILE_OPEN_ERROR; |
|
167 |
|
*p_err_i = i; |
|
168 |
|
goto CANCEL_IM; |
|
169 |
|
} |
|
170 |
|
res = convert::from_tga({p_data,size}, &p_ims_tmp[uint16_t(i)]); |
|
171 |
|
jl::deallocate(&p_data); |
|
172 |
|
if (res != Result::SUCCESS) { |
|
173 |
|
*p_err_i = i; |
|
174 |
|
goto CANCEL_IM; |
|
175 |
|
} |
|
176 |
|
} |
|
177 |
|
for (uint32_t j = 1; j < files.count(); ++j) { |
|
178 |
|
auto &cim = p_ims_tmp[j]; |
|
179 |
|
auto &fim = p_ims_tmp[0]; |
|
180 |
|
if (cim.extent.width != fim.extent.width |
|
181 |
|
or |
|
182 |
|
cim.extent.height != fim.extent.height) { |
|
183 |
|
res = Result::IMAGE_LAYERS_EXTENT_MISMATCH; |
|
184 |
|
*p_err_i = i; |
|
185 |
|
goto CANCEL_IM; |
|
186 |
|
} |
|
187 |
|
if (cim.format != fim.format) { |
|
188 |
|
res = Result::IMAGE_LAYERS_FORMAT_MISMATCH; |
|
189 |
|
*p_err_i = i; |
|
190 |
|
goto CANCEL_IM; |
|
191 |
|
} |
|
192 |
|
}{ |
|
193 |
|
auto fin_extent = p_ims_tmp[0].extent; |
|
194 |
|
fin_extent.depth = uint16_t(files.count()); |
|
195 |
|
if (not p_dst->init(fin_extent, p_ims_tmp[0].format)) { |
|
196 |
|
res = jrf::Result::ALLOCATION_FAIL; |
|
197 |
|
goto CANCEL_IM; |
|
198 |
|
}{ |
|
199 |
|
auto p = reinterpret_cast<uint8_t*>(p_dst->p_pixels); |
|
200 |
|
for(uint16_t j = 0; j < files.count(); ++j) { |
|
201 |
|
auto &src = p_ims_tmp[j]; |
|
202 |
|
memcpy(p, src.p_pixels, src.size); |
|
203 |
|
p = &p[src.size]; |
|
204 |
|
} |
|
205 |
|
} |
|
206 |
|
} |
|
207 |
|
res = jrf::Result::SUCCESS; |
|
208 |
|
CANCEL_IM: |
|
209 |
|
for (uint32_t j = 0; j < i; ++j) |
|
210 |
|
p_ims_tmp[j].destroy(); |
|
211 |
|
jl::deallocate(&p_ims_tmp); |
|
212 |
|
return res; |
|
213 |
|
} |