summaryrefslogtreecommitdiff
path: root/core/image.h
diff options
context:
space:
mode:
Diffstat (limited to 'core/image.h')
-rw-r--r--core/image.h147
1 files changed, 93 insertions, 54 deletions
diff --git a/core/image.h b/core/image.h
index c15cfc9f6f..06794c7fed 100644
--- a/core/image.h
+++ b/core/image.h
@@ -33,7 +33,6 @@
#include "core/color.h"
#include "core/math/rect2.h"
-#include "core/pool_vector.h"
#include "core/resource.h"
/**
@@ -47,6 +46,7 @@
class Image;
typedef Error (*SavePNGFunc)(const String &p_path, const Ref<Image> &p_img);
+typedef Vector<uint8_t> (*SavePNGBufferFunc)(const Ref<Image> &p_img);
typedef Ref<Image> (*ImageMemLoadFunc)(const uint8_t *p_png, int p_size);
typedef Error (*SaveEXRFunc)(const String &p_path, const Ref<Image> &p_img, bool p_grayscale);
@@ -57,10 +57,12 @@ class Image : public Resource {
public:
static SavePNGFunc save_png_func;
static SaveEXRFunc save_exr_func;
+ static SavePNGBufferFunc save_png_buffer_func;
enum {
- MAX_WIDTH = 16384, // force a limit somehow
- MAX_HEIGHT = 16384 // force a limit somehow
+ MAX_WIDTH = (1 << 24), // force a limit somehow
+ MAX_HEIGHT = (1 << 24), // force a limit somehow
+ MAX_PIXELS = 268435456
};
enum Format {
@@ -72,7 +74,7 @@ public:
FORMAT_RGB8,
FORMAT_RGBA8,
FORMAT_RGBA4444,
- FORMAT_RGBA5551,
+ FORMAT_RGB565,
FORMAT_RF, //float
FORMAT_RGF,
FORMAT_RGBF,
@@ -102,6 +104,8 @@ public:
FORMAT_ETC2_RGB8,
FORMAT_ETC2_RGBA8,
FORMAT_ETC2_RGB8A1,
+ FORMAT_ETC2_RA_AS_RG, //used to make basis universal happy
+ FORMAT_DXT5_RA_AS_RG, //used to make basis universal happy
FORMAT_MAX
};
@@ -117,25 +121,28 @@ public:
/* INTERPOLATE GAUSS */
};
- enum CompressSource {
- COMPRESS_SOURCE_GENERIC,
- COMPRESS_SOURCE_SRGB,
- COMPRESS_SOURCE_NORMAL,
- COMPRESS_SOURCE_LAYERED,
+ //this is used for compression
+ enum UsedChannels {
+ USED_CHANNELS_L,
+ USED_CHANNELS_LA,
+ USED_CHANNELS_R,
+ USED_CHANNELS_RG,
+ USED_CHANNELS_RGB,
+ USED_CHANNELS_RGBA,
};
-
//some functions provided by something else
static ImageMemLoadFunc _png_mem_loader_func;
static ImageMemLoadFunc _jpg_mem_loader_func;
static ImageMemLoadFunc _webp_mem_loader_func;
+ static ImageMemLoadFunc _tga_mem_loader_func;
- static void (*_image_compress_bc_func)(Image *, float, CompressSource p_source);
- static void (*_image_compress_bptc_func)(Image *, float p_lossy_quality, CompressSource p_source);
+ static void (*_image_compress_bc_func)(Image *, float, UsedChannels p_channels);
+ static void (*_image_compress_bptc_func)(Image *, float p_lossy_quality, UsedChannels p_channels);
static void (*_image_compress_pvrtc2_func)(Image *);
static void (*_image_compress_pvrtc4_func)(Image *);
static void (*_image_compress_etc1_func)(Image *, float);
- static void (*_image_compress_etc2_func)(Image *, float, CompressSource p_source);
+ static void (*_image_compress_etc2_func)(Image *, float, UsedChannels p_channels);
static void (*_image_decompress_pvrtc)(Image *);
static void (*_image_decompress_bc)(Image *);
@@ -143,12 +150,15 @@ public:
static void (*_image_decompress_etc1)(Image *);
static void (*_image_decompress_etc2)(Image *);
- static PoolVector<uint8_t> (*lossy_packer)(const Ref<Image> &p_image, float p_quality);
- static Ref<Image> (*lossy_unpacker)(const PoolVector<uint8_t> &p_buffer);
- static PoolVector<uint8_t> (*lossless_packer)(const Ref<Image> &p_image);
- static Ref<Image> (*lossless_unpacker)(const PoolVector<uint8_t> &p_buffer);
+ static Vector<uint8_t> (*lossy_packer)(const Ref<Image> &p_image, float p_quality);
+ static Ref<Image> (*lossy_unpacker)(const Vector<uint8_t> &p_buffer);
+ static Vector<uint8_t> (*lossless_packer)(const Ref<Image> &p_image);
+ static Ref<Image> (*lossless_unpacker)(const Vector<uint8_t> &p_buffer);
+ static Vector<uint8_t> (*basis_universal_packer)(const Ref<Image> &p_image, UsedChannels p_channels);
+ static Ref<Image> (*basis_universal_unpacker)(const Vector<uint8_t> &p_buffer);
- PoolVector<uint8_t>::Write write_lock;
+ _FORCE_INLINE_ Color _get_color_at_ofs(const uint8_t *ptr, uint32_t ofs) const;
+ _FORCE_INLINE_ void _set_color_at_ofs(uint8_t *ptr, uint32_t ofs, const Color &p_color);
protected:
static void _bind_methods();
@@ -158,14 +168,15 @@ private:
create(p_width, p_height, p_use_mipmaps, p_format);
}
- void _create_from_data(int p_width, int p_height, bool p_use_mipmaps, Format p_format, const PoolVector<uint8_t> &p_data) {
+ void _create_from_data(int p_width, int p_height, bool p_use_mipmaps, Format p_format, const Vector<uint8_t> &p_data) {
create(p_width, p_height, p_use_mipmaps, p_format, p_data);
}
- Format format;
- PoolVector<uint8_t> data;
- int width, height;
- bool mipmaps;
+ Format format = FORMAT_L8;
+ Vector<uint8_t> data;
+ int width = 0;
+ int height = 0;
+ bool mipmaps = false;
void _copy_internals_from(const Image &p_image) {
format = p_image.format;
@@ -177,7 +188,7 @@ private:
_FORCE_INLINE_ void _get_mipmap_offset_and_size(int p_mipmap, int &r_offset, int &r_width, int &r_height) const; //get where the mipmap begins in data
- static int _get_dst_image_size(int p_width, int p_height, Format p_format, int &r_mipmaps, int p_mipmaps = -1);
+ static int _get_dst_image_size(int p_width, int p_height, Format p_format, int &r_mipmaps, int p_mipmaps = -1, int *r_mm_width = nullptr, int *r_mm_height = nullptr);
bool _can_modify(Format p_format) const;
_FORCE_INLINE_ void _put_pixelb(int p_x, int p_y, uint32_t p_pixelsize, uint8_t *p_data, const uint8_t *p_pixel);
@@ -186,7 +197,7 @@ private:
void _set_data(const Dictionary &p_data);
Dictionary _get_data() const;
- Error _load_from_buffer(const PoolVector<uint8_t> &p_array, ImageMemLoadFunc p_loader);
+ Error _load_from_buffer(const Vector<uint8_t> &p_array, ImageMemLoadFunc p_loader);
static void average_4_uint8(uint8_t &p_out, const uint8_t &p_a, const uint8_t &p_b, const uint8_t &p_c, const uint8_t &p_d);
static void average_4_float(float &p_out, const float &p_a, const float &p_b, const float &p_c, const float &p_d);
@@ -214,17 +225,30 @@ public:
*/
Format get_format() const;
+ int get_mipmap_byte_size(int p_mipmap) const; //get where the mipmap begins in data
int get_mipmap_offset(int p_mipmap) const; //get where the mipmap begins in data
void get_mipmap_offset_and_size(int p_mipmap, int &r_ofs, int &r_size) const; //get where the mipmap begins in data
void get_mipmap_offset_size_and_dimensions(int p_mipmap, int &r_ofs, int &r_size, int &w, int &h) const; //get where the mipmap begins in data
+ enum Image3DValidateError {
+ VALIDATE_3D_OK,
+ VALIDATE_3D_ERR_IMAGE_EMPTY,
+ VALIDATE_3D_ERR_MISSING_IMAGES,
+ VALIDATE_3D_ERR_EXTRA_IMAGES,
+ VALIDATE_3D_ERR_IMAGE_SIZE_MISMATCH,
+ VALIDATE_3D_ERR_IMAGE_FORMAT_MISMATCH,
+ VALIDATE_3D_ERR_IMAGE_HAS_MIPMAPS,
+ };
+
+ static Image3DValidateError validate_3d_image(Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_images);
+ static String get_3d_image_validation_error_text(Image3DValidateError p_error);
+
/**
* Resize the image, using the preferred interpolation method.
*/
void resize_to_po2(bool p_square = false);
void resize(int p_width, int p_height, Interpolation p_interpolation = INTERPOLATE_BILINEAR);
void shrink_x2();
- void expand_x2_hq2x();
bool is_size_po2() const;
/**
* Crop the image to a specific size, if larger, then the image is filled by black
@@ -240,6 +264,16 @@ public:
*/
Error generate_mipmaps(bool p_renormalize = false);
+ enum RoughnessChannel {
+ ROUGHNESS_CHANNEL_R,
+ ROUGHNESS_CHANNEL_G,
+ ROUGHNESS_CHANNEL_B,
+ ROUGHNESS_CHANNEL_A,
+ ROUGHNESS_CHANNEL_L,
+ };
+
+ Error generate_mipmap_roughness(RoughnessChannel p_roughness_channel, const Ref<Image> &p_normal_map);
+
void clear_mipmaps();
void normalize(); //for normal maps
@@ -247,7 +281,7 @@ public:
* Create a new image of a given size and format. Current image will be lost
*/
void create(int p_width, int p_height, bool p_use_mipmaps, Format p_format);
- void create(int p_width, int p_height, bool p_use_mipmaps, Format p_format, const PoolVector<uint8_t> &p_data);
+ void create(int p_width, int p_height, bool p_use_mipmaps, Format p_format, const Vector<uint8_t> &p_data);
void create(const char **p_xpm);
/**
@@ -255,16 +289,17 @@ public:
*/
bool empty() const;
- PoolVector<uint8_t> get_data() const;
+ Vector<uint8_t> get_data() const;
Error load(const String &p_path);
Error save_png(const String &p_path) const;
+ Vector<uint8_t> save_png_to_buffer() const;
Error save_exr(const String &p_path, bool p_grayscale) const;
/**
* create an empty image
*/
- Image();
+ Image() {}
/**
* create an empty image of a specific size and format
*/
@@ -272,7 +307,9 @@ public:
/**
* import an image of a specific size and format from a pointer
*/
- Image(int p_width, int p_height, bool p_mipmaps, Format p_format, const PoolVector<uint8_t> &p_data);
+ Image(int p_width, int p_height, bool p_mipmaps, Format p_format, const Vector<uint8_t> &p_data);
+
+ ~Image() {}
enum AlphaMode {
ALPHA_NONE,
@@ -290,7 +327,9 @@ public:
static int get_image_data_size(int p_width, int p_height, Format p_format, bool p_mipmaps = false);
static int get_image_required_mipmaps(int p_width, int p_height, Format p_format);
+ static Size2i get_image_mipmap_size(int p_width, int p_height, Format p_format, int p_mipmap);
static int get_image_mipmap_offset(int p_width, int p_height, Format p_format, int p_mipmap);
+ static int get_image_mipmap_offset_and_dimensions(int p_width, int p_height, Format p_format, int p_mipmap, int &r_w, int &r_h);
enum CompressMode {
COMPRESS_S3TC,
@@ -300,8 +339,14 @@ public:
COMPRESS_ETC2,
COMPRESS_BPTC
};
+ enum CompressSource {
+ COMPRESS_SOURCE_GENERIC,
+ COMPRESS_SOURCE_SRGB,
+ COMPRESS_SOURCE_NORMAL
+ };
- Error compress(CompressMode p_mode = COMPRESS_S3TC, CompressSource p_source = COMPRESS_SOURCE_GENERIC, float p_lossy_quality = 0.7);
+ Error compress(CompressMode p_mode, CompressSource p_source = COMPRESS_SOURCE_GENERIC, float p_lossy_quality = 0.7);
+ Error compress_from_channels(CompressMode p_mode, UsedChannels p_channels, float p_lossy_quality = 0.7);
Error decompress();
bool is_compressed() const;
@@ -310,6 +355,7 @@ public:
void srgb_to_linear();
void normalmap_to_xy();
Ref<Image> rgbe_to_srgb();
+ Ref<Image> get_image_from_mipmap(int p_mipamp) const;
void bumpmap_to_normalmap(float bump_scale = 1.0);
void blit_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Point2 &p_dest);
@@ -321,33 +367,24 @@ public:
Rect2 get_used_rect() const;
Ref<Image> get_rect(const Rect2 &p_area) const;
- static void set_compress_bc_func(void (*p_compress_func)(Image *, float, CompressSource));
- static void set_compress_bptc_func(void (*p_compress_func)(Image *, float, CompressSource));
+ static void set_compress_bc_func(void (*p_compress_func)(Image *, float, UsedChannels));
+ static void set_compress_bptc_func(void (*p_compress_func)(Image *, float, UsedChannels));
static String get_format_name(Format p_format);
- Error load_png_from_buffer(const PoolVector<uint8_t> &p_array);
- Error load_jpg_from_buffer(const PoolVector<uint8_t> &p_array);
- Error load_webp_from_buffer(const PoolVector<uint8_t> &p_array);
+ Error load_png_from_buffer(const Vector<uint8_t> &p_array);
+ Error load_jpg_from_buffer(const Vector<uint8_t> &p_array);
+ Error load_webp_from_buffer(const Vector<uint8_t> &p_array);
+ Error load_tga_from_buffer(const Vector<uint8_t> &p_array);
+
+ void convert_rg_to_ra_rgba8();
+ void convert_ra_rgba8_to_rg();
Image(const uint8_t *p_mem_png_jpg, int p_len = -1);
Image(const char **p_xpm);
- virtual Ref<Resource> duplicate(bool p_subresources = false) const;
-
- void lock();
- void unlock();
+ virtual Ref<Resource> duplicate(bool p_subresources = false) const override;
- //this is used for compression
- enum DetectChannels {
- DETECTED_L,
- DETECTED_LA,
- DETECTED_R,
- DETECTED_RG,
- DETECTED_RGB,
- DETECTED_RGBA,
- };
-
- DetectChannels get_detected_channels();
+ UsedChannels detect_used_channels(CompressSource p_source = COMPRESS_SOURCE_GENERIC);
void optimize_channels();
Color get_pixelv(const Point2 &p_src) const;
@@ -355,6 +392,8 @@ public:
void set_pixelv(const Point2 &p_dst, const Color &p_color);
void set_pixel(int p_x, int p_y, const Color &p_color);
+ void set_as_black();
+
void copy_internals_from(const Ref<Image> &p_image) {
ERR_FAIL_COND_MSG(p_image.is_null(), "It's not a reference to a valid Image object.");
format = p_image->format;
@@ -363,14 +402,14 @@ public:
mipmaps = p_image->mipmaps;
data = p_image->data;
}
-
- ~Image();
};
VARIANT_ENUM_CAST(Image::Format)
VARIANT_ENUM_CAST(Image::Interpolation)
VARIANT_ENUM_CAST(Image::CompressMode)
VARIANT_ENUM_CAST(Image::CompressSource)
+VARIANT_ENUM_CAST(Image::UsedChannels)
VARIANT_ENUM_CAST(Image::AlphaMode)
+VARIANT_ENUM_CAST(Image::RoughnessChannel)
-#endif
+#endif // IMAGE_H