Divide Framework 0.1
A free and open-source 3D Framework under heavy development
Loading...
Searching...
No Matches
ImageTools.h
Go to the documentation of this file.
1/*
2 Copyright (c) 2018 DIVIDE-Studio
3 Copyright (c) 2009 Ionut Cava
4
5 This file is part of DIVIDE Framework.
6
7 Permission is hereby granted, free of charge, to any person obtaining a copy
8 of this software
9 and associated documentation files (the "Software"), to deal in the Software
10 without restriction,
11 including without limitation the rights to use, copy, modify, merge, publish,
12 distribute, sublicense,
13 and/or sell copies of the Software, and to permit persons to whom the
14 Software is furnished to do so,
15 subject to the following conditions:
16
17 The above copyright notice and this permission notice shall be included in
18 all copies or substantial portions of the Software.
19
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 IMPLIED,
22 INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
23 PARTICULAR PURPOSE AND NONINFRINGEMENT.
24 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
25 DAMAGES OR OTHER LIABILITY,
26 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
27 IN CONNECTION WITH THE SOFTWARE
28 OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29
30 */
31
32#pragma once
33#ifndef DVD_UTILITY_IMAGETOOLS_H
34#define DVD_UTILITY_IMAGETOOLS_H
35
36#include "ImageToolsFwd.h"
37
38namespace Divide {
39namespace ImageTools {
40
41struct LayerData {
42 virtual ~LayerData() = default;
43 [[nodiscard]] virtual bufferPtr data() const = 0;
44
46 size_t _size = 0u;
48 vec3<U16> _dimensions = { 0, 0, 1 };
49};
50
51template<typename T>
52struct ImageMip final : LayerData {
53
54 explicit ImageMip(const T* data, size_t len, const U16 width, const U16 height, const U16 depth, const U8 numComponents)
55 {
56 const size_t totalSizeTest = to_size(width) * height * depth * numComponents;
57 const size_t actualSize = std::max(len, totalSizeTest);
58
59 _data.resize(actualSize, T{ 0u });
60
61 if (len > 0u)
62 {
63 if ( data != nullptr )
64 {
65 std::memcpy( _data.data(), data, len == 0u ? totalSizeTest : len * sizeof( T ) );
66 }
67 else
68 {
69 std::memset(_data.data(), 0u, len == 0u ? totalSizeTest : len * sizeof ( T ));
70 }
71 }
72
73 _size = actualSize;
74 _dimensions.set(width, height, depth);
75 }
76
77 [[nodiscard]] bufferPtr data() const noexcept override { return (bufferPtr)_data.data(); }
78
79protected:
81};
82
83struct ImageLayer {
84 template<typename T>
85 [[nodiscard]] T* allocateMip(const T* data, size_t len, U16 width, U16 height, U16 depth, const U8 numComponents) {
86 assert(_mips.size() < U8_MAX - 1);
87
88 _mips.emplace_back(std::make_unique<ImageMip<T>>(data, len, width, height, depth, numComponents));
89 return static_cast<T*>(_mips.back()->data());
90 }
91
92 template<typename T>
93 [[nodiscard]] T* allocateMip(const size_t len, const U16 width, const U16 height, const U16 depth, const U8 numComponents) {
94 return allocateMip<T>(nullptr, len, width, height, depth, numComponents);
95 }
96
97 [[nodiscard]] bufferPtr data(const U8 mip) const {
98 if (_mips.size() <= mip) {
99 return nullptr;
100 }
101
102 return _mips[mip]->data();
103 }
104
105 [[nodiscard]] LayerData* getMip(const U8 mip) const {
106 if (mip < _mips.size()) {
107 return _mips[mip].get();
108 }
109
110 return nullptr;
111 }
112
113 [[nodiscard]] U8 mipCount() const noexcept {
114 return to_U8(_mips.size());
115 }
116
117private:
119};
120
121struct ImageData final : NonCopyable
122{
125
127 [[nodiscard]] bufferPtr data(const U32 layer, const U8 mipLevel) const {
128 if (layer < _layers.size() && mipLevel < mipCount()) {
129 // triple data-ception
130 return _layers[layer].data(mipLevel);
131 }
132
133 return nullptr;
134 }
135
136 [[nodiscard]] const vector<ImageLayer>& imageLayers() const noexcept {
137 return _layers;
138 }
139
141 [[nodiscard]] const vec3<U16>& dimensions(const U32 layer, const U8 mipLevel = 0u) const {
142 assert(mipLevel < mipCount());
143 assert(layer < _layers.size());
144
145 return _layers[layer].getMip(mipLevel)->_dimensions;
146 }
147
149 [[nodiscard]] U8 mipCount() const { return _layers.empty() ? 0u : _layers.front().mipCount(); }
151 [[nodiscard]] U16 layerCount() const noexcept { return to_U16(_layers.size()); }
153 [[nodiscard]] U8 bpp() const noexcept { return _bpp; }
155 [[nodiscard]] const std::string_view name() const noexcept { return _name; }
157 [[nodiscard]] GFXImageFormat format() const noexcept { return _format; }
158
159 [[nodiscard]] GFXDataFormat dataType() const noexcept { return _dataType; }
161 [[nodiscard]] UColour4 getColour(I32 x, I32 y, U32 layer = 0u, U8 mipLevel = 0u) const;
162 void getColour(I32 x, I32 y, U8& r, U8& g, U8& b, U8& a, U32 layer = 0u, U8 mipLevel = 0u) const;
163
164 void getColourComponent(const I32 x, const I32 y, const U8 comp, U8& c, const U32 layer, const U8 mipLevel = 0) const;
165 FORCE_INLINE void getRed(const I32 x, const I32 y, U8& r, const U32 layer, const U8 mipLevel = 0) const { getColourComponent(x, y, 0, r, layer, mipLevel); }
166 FORCE_INLINE void getGreen(const I32 x, const I32 y, U8& g, const U32 layer, const U8 mipLevel = 0) const { getColourComponent(x, y, 1, g, layer, mipLevel); }
167 FORCE_INLINE void getBlue(const I32 x, const I32 y, U8& b, const U32 layer, const U8 mipLevel = 0) const { getColourComponent(x, y, 2, b, layer, mipLevel); }
168 FORCE_INLINE void getAlpha(const I32 x, const I32 y, U8& a, const U32 layer, const U8 mipLevel = 0) const { getColourComponent(x, y, 3, a, layer, mipLevel); }
169
170 [[nodiscard]] bool loadFromMemory(const Byte* data, size_t size, U16 width, U16 height, U16 depth, U8 numComponents);
172 [[nodiscard]] bool loadFromFile(PlatformContext& context, bool srgb, U16 refWidth, U16 refHeight, const ResourcePath& path, std::string_view name);
173 [[nodiscard]] bool loadFromFile( PlatformContext& context, bool srgb, U16 refWidth, U16 refHeight, const ResourcePath& path, std::string_view name, ImportOptions& options, bool isRetry = false);
174
175
176 [[nodiscard]] FORCE_INLINE ResourcePath fullPath() const noexcept { return _path / _name; }
177
179 PROPERTY_RW(bool, ignoreAlphaChannelTransparency, false);
181 PROPERTY_RW(bool, hasDummyAlphaChannel, false);
182
183 protected:
184 friend class ImageDataInterface;
185 [[nodiscard]] bool loadDDS_NVTT(bool srgb, U16 refWidth, U16 refHeight, const ResourcePath& path, std::string_view name);
186 [[nodiscard]] bool loadDDS_IL(bool srgb, U16 refWidth, U16 refHeight, const ResourcePath& path, std::string_view name);
187
188 private:
190 {
192 bool _loadedDDSData = false;
193 bool _createdDDSData = false;
194 };
195
196 //Each entry is a separate mip map.
211 U8 _bpp = 0;
212
213 enum class SourceDataType : U8
214 {
215 BYTE,
216 SHORT,
217 HALF,
218 FLOAT,
219 UINT
221};
222
223} // namespace ImageTools
224} // namespace Divide
225
226#endif //DVD_UTILITY_IMAGETOOLS_H
227
#define FORCE_INLINE
void set(const T *v) noexcept
set the 3 components of the vector manually using a source pointer to a (large enough) array
Definition: MathVectors.h:707
Handle console commands that start with a forward slash.
Definition: AIProcessor.cpp:7
std::byte Byte
constexpr U16 to_U16(const T value)
int32_t I32
uint8_t U8
eastl::vector< Type > vector
Definition: Vector.h:42
uint16_t U16
constexpr U8 U8_MAX
constexpr U8 to_U8(const T value)
constexpr size_t to_size(const T value)
uint32_t U32
void * bufferPtr
U8 bpp() const noexcept
image depth information
Definition: ImageTools.h:153
U8 mipCount() const
get the number of pre-loaded mip maps (same number for each layer)
Definition: ImageTools.h:149
const std::string_view name() const noexcept
the filename from which the image is created
Definition: ImageTools.h:155
const vec3< U16 > & dimensions(const U32 layer, const U8 mipLevel=0u) const
image width, height and depth
Definition: ImageTools.h:141
GFXDataFormat dataType() const noexcept
Definition: ImageTools.h:159
enum Divide::ImageTools::ImageData::SourceDataType _sourceDataType
GFXDataFormat _requestedDataFormat
the image requested data type. COUNT == AUTO
Definition: ImageTools.h:209
GFXImageFormat _format
the image format
Definition: ImageTools.h:205
FORCE_INLINE void getRed(const I32 x, const I32 y, U8 &r, const U32 layer, const U8 mipLevel=0) const
Definition: ImageTools.h:165
Str< 256 > _name
the actual image filename
Definition: ImageTools.h:203
U8 _bpp
image's bits per pixel
Definition: ImageTools.h:211
bufferPtr data(const U32 layer, const U8 mipLevel) const
set and get the image's actual data
Definition: ImageTools.h:127
ResourcePath _path
the image path
Definition: ImageTools.h:201
void getColourComponent(const I32 x, const I32 y, const U8 comp, U8 &c, const U32 layer, const U8 mipLevel=0) const
bool loadFromMemory(const Byte *data, size_t size, U16 width, U16 height, U16 depth, U8 numComponents)
Definition: ImageTools.cpp:206
GFXImageFormat format() const noexcept
the image format as given by STB
Definition: ImageTools.h:157
bool loadDDS_NVTT(bool srgb, U16 refWidth, U16 refHeight, const ResourcePath &path, std::string_view name)
Definition: ImageTools.cpp:986
PROPERTY_RW(bool, hasDummyAlphaChannel, false)
If true, then the source image was probably RGB and we loaded it as RGBA.
bool loadFromFile(PlatformContext &context, bool srgb, U16 refWidth, U16 refHeight, const ResourcePath &path, std::string_view name)
creates this image instance from the specified data
Definition: ImageTools.cpp:212
UColour4 getColour(I32 x, I32 y, U32 layer=0u, U8 mipLevel=0u) const
get the texel colour at the specified offset from the origin
U16 layerCount() const noexcept
get the total number of image layers
Definition: ImageTools.h:151
PROPERTY_RW(bool, ignoreAlphaChannelTransparency, false)
If true, then the source image's alpha channel is used for data and not opacity (so skip mip-filterin...
FORCE_INLINE void getGreen(const I32 x, const I32 y, U8 &g, const U32 layer, const U8 mipLevel=0) const
Definition: ImageTools.h:166
bool loadDDS_IL(bool srgb, U16 refWidth, U16 refHeight, const ResourcePath &path, std::string_view name)
Definition: ImageTools.cpp:992
vector< ImageLayer > _layers
Definition: ImageTools.h:197
FORCE_INLINE void getBlue(const I32 x, const I32 y, U8 &b, const U32 layer, const U8 mipLevel=0) const
Definition: ImageTools.h:167
const vector< ImageLayer > & imageLayers() const noexcept
Definition: ImageTools.h:136
void requestedFormat(const GFXDataFormat format) noexcept
image origin information
Definition: ImageTools.h:124
FORCE_INLINE ResourcePath fullPath() const noexcept
Definition: ImageTools.h:176
FORCE_INLINE void getAlpha(const I32 x, const I32 y, U8 &a, const U32 layer, const U8 mipLevel=0) const
Definition: ImageTools.h:168
GFXDataFormat _dataType
the image data type
Definition: ImageTools.h:207
T * allocateMip(const size_t len, const U16 width, const U16 height, const U16 depth, const U8 numComponents)
Definition: ImageTools.h:93
U8 mipCount() const noexcept
Definition: ImageTools.h:113
vector< LayerData_uptr > _mips
Definition: ImageTools.h:118
LayerData * getMip(const U8 mip) const
Definition: ImageTools.h:105
bufferPtr data(const U8 mip) const
Definition: ImageTools.h:97
T * allocateMip(const T *data, size_t len, U16 width, U16 height, U16 depth, const U8 numComponents)
Definition: ImageTools.h:85
bufferPtr data() const noexcept override
Definition: ImageTools.h:77
ImageMip(const T *data, size_t len, const U16 width, const U16 height, const U16 depth, const U8 numComponents)
Definition: ImageTools.h:54
virtual bufferPtr data() const =0
virtual ~LayerData()=default
size_t _size
the image data as it was read from the file / memory.
Definition: ImageTools.h:46
vec3< U16 > _dimensions
with and height
Definition: ImageTools.h:48