@@ -455,6 +455,18 @@ Size2i Image::get_size() const {
455455 return Size2i (width, height);
456456}
457457
458+ int Image::get_original_width () const {
459+ return original_width;
460+ }
461+
462+ int Image::get_original_height () const {
463+ return original_height;
464+ }
465+
466+ Size2i Image::get_original_size () const {
467+ return Size2i (original_width, original_height);
468+ }
469+
458470bool Image::has_mipmaps () const {
459471 return mipmaps;
460472}
@@ -765,6 +777,102 @@ void Image::convert(Format p_new_format) {
765777 _copy_internals_from (new_img);
766778}
767779
780+ Image::PerformanceMode Image::get_performance_mode () const {
781+ return performance_mode;
782+ }
783+
784+ Error Image::set_performance_mode (PerformanceMode p_performance_mode) {
785+ switch (performance_mode) {
786+ case PERFORMANCE_MODE_ORIGINAL_SIZE :
787+ break ;
788+
789+ default :
790+ ERR_FAIL_V_MSG (FAILED , " Image's performance_mode has already been set. It needs to be reloaded/recreated before it can be set again" );
791+ }
792+
793+ performance_mode = p_performance_mode;
794+
795+ Size2i size = get_size ();
796+ Vector2i desired_size = size;
797+
798+ switch (performance_mode) {
799+ case PERFORMANCE_MODE_ORIGINAL_SIZE :
800+ break ;
801+
802+ case PERFORMANCE_MODE_MAX_SIZE : {
803+ Vector2i max_size = GLOBAL_GET (" rendering/textures/performance/max_size" );
804+
805+ if (desired_size.x > max_size.x ) {
806+ desired_size.x = max_size.x ;
807+ }
808+
809+ if (desired_size.y > max_size.y ) {
810+ desired_size.y = max_size.y ;
811+ }
812+
813+ break ;
814+ }
815+
816+ case PERFORMANCE_MODE_DOWNSCALE_SIZE : {
817+ int factor = GLOBAL_GET (" rendering/textures/performance/downscale_factor" );
818+ factor = CLAMP (factor, 1 , 14 );
819+
820+ desired_size.x >>= factor;
821+ desired_size.y >>= factor;
822+
823+ break ;
824+ }
825+
826+ default :
827+ ERR_FAIL_V_MSG (FAILED , vformat (" Unknown image performance mode '%i'" , performance_mode));
828+ }
829+
830+ desired_size = desired_size.max (Vector2i (1 , 1 ));
831+
832+ if (desired_size == size) {
833+ return OK ;
834+ }
835+
836+ if (is_compressed ()) {
837+ Format current_format = get_format ();
838+
839+ Error err = decompress ();
840+
841+ if (err != OK ) {
842+ ERR_FAIL_V_MSG (FAILED , vformat (" Cannot decompress image format '%s'" , current_format));
843+ }
844+
845+ resize (desired_size.x , desired_size.y );
846+
847+ Image::CompressMode compress_mode = COMPRESS_MAX ;
848+
849+ if ((current_format >= FORMAT_DXT1 && current_format <= FORMAT_RGTC_RG ) || (current_format == FORMAT_DXT5_RA_AS_RG )) {
850+ compress_mode = COMPRESS_S3TC ;
851+ } else if (current_format >= FORMAT_BPTC_RGBA && current_format <= FORMAT_BPTC_RGBFU ) {
852+ compress_mode = COMPRESS_BPTC ;
853+ } else if (current_format == FORMAT_ETC ) {
854+ compress_mode = COMPRESS_ETC ;
855+ } else if (current_format >= FORMAT_ETC2_R11 && current_format <= FORMAT_ETC2_RA_AS_RG ) {
856+ compress_mode = COMPRESS_ETC2 ;
857+ } else if (current_format >= FORMAT_ASTC_4x4 && current_format <= FORMAT_ASTC_8x8_HDR) {
858+ compress_mode = COMPRESS_ASTC ;
859+ }
860+
861+ if (compress_mode != COMPRESS_MAX ) {
862+ compress (compress_mode);
863+ } else {
864+ ERR_PRINT (vformat (" Cannot recompress image format '%s'" , current_format));
865+ }
866+ } else {
867+ resize (desired_size.x , desired_size.y );
868+ }
869+
870+ original_width = size.x ;
871+ original_height = size.y ;
872+
873+ return OK ;
874+ }
875+
768876Image::Format Image::get_format () const {
769877 return format;
770878}
@@ -1429,6 +1537,7 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) {
14291537 }
14301538
14311539 _copy_internals_from (dst);
1540+ performance_mode = PERFORMANCE_MODE_ORIGINAL_SIZE ;
14321541}
14331542
14341543void Image::crop_from_point (int p_x, int p_y, int p_width, int p_height) {
@@ -1592,6 +1701,10 @@ void Image::rotate_90(ClockDirection p_direction) {
15921701
15931702 width = h;
15941703 height = w;
1704+ int o_h = original_height;
1705+ int o_w = original_width;
1706+ original_height = o_w;
1707+ original_width = o_h;
15951708 }
15961709
15971710#undef PREV_INDEX_IN_CYCLE
@@ -1902,6 +2015,8 @@ void Image::shrink_x2() {
19022015
19032016 width = MAX (width / 2 , 1 );
19042017 height = MAX (height / 2 , 1 );
2018+ original_width = width;
2019+ original_height = height;
19052020 data = new_data;
19062021}
19072022
@@ -2193,6 +2308,8 @@ void Image::initialize_data(int p_width, int p_height, bool p_use_mipmaps, Forma
21932308
21942309 width = p_width;
21952310 height = p_height;
2311+ original_width = p_width;
2312+ original_height = p_height;
21962313 mipmaps = p_use_mipmaps;
21972314 format = p_format;
21982315}
@@ -2229,10 +2346,14 @@ void Image::initialize_data(int p_width, int p_height, bool p_use_mipmaps, Forma
22292346
22302347 height = p_height;
22312348 width = p_width;
2349+ original_height = p_height;
2350+ original_width = p_width;
22322351 format = p_format;
22332352 data = p_data;
22342353
22352354 mipmaps = p_use_mipmaps;
2355+
2356+ performance_mode = PERFORMANCE_MODE_ORIGINAL_SIZE ;
22362357}
22372358
22382359void Image::initialize_data (const char **p_xpm) {
@@ -2242,6 +2363,8 @@ void Image::initialize_data(const char **p_xpm) {
22422363 mipmaps = false ;
22432364 bool has_alpha = false ;
22442365
2366+ performance_mode = PERFORMANCE_MODE_ORIGINAL_SIZE ;
2367+
22452368 enum Status {
22462369 READING_HEADER ,
22472370 READING_COLORS ,
@@ -2775,6 +2898,8 @@ Error Image::compress_from_channels(CompressMode p_mode, UsedChannels p_channels
27752898Image::Image (const char **p_xpm) {
27762899 width = 0 ;
27772900 height = 0 ;
2901+ original_width = 0 ;
2902+ original_height = 0 ;
27782903 mipmaps = false ;
27792904 format = FORMAT_L8 ;
27802905
@@ -2784,6 +2909,8 @@ Image::Image(const char **p_xpm) {
27842909Image::Image (int p_width, int p_height, bool p_use_mipmaps, Format p_format) {
27852910 width = 0 ;
27862911 height = 0 ;
2912+ original_width = 0 ;
2913+ original_height = 0 ;
27872914 mipmaps = p_use_mipmaps;
27882915 format = FORMAT_L8 ;
27892916
@@ -2793,6 +2920,8 @@ Image::Image(int p_width, int p_height, bool p_use_mipmaps, Format p_format) {
27932920Image::Image (int p_width, int p_height, bool p_mipmaps, Format p_format, const Vector<uint8_t > &p_data) {
27942921 width = 0 ;
27952922 height = 0 ;
2923+ original_width = 0 ;
2924+ original_height = 0 ;
27962925 mipmaps = p_mipmaps;
27972926 format = FORMAT_L8 ;
27982927
@@ -3113,6 +3242,8 @@ void Image::fill_rect(const Rect2i &p_rect, const Color &p_color) {
31133242void Image::_set_data (const Dictionary &p_data) {
31143243 ERR_FAIL_COND (!p_data.has (" width" ));
31153244 ERR_FAIL_COND (!p_data.has (" height" ));
3245+ ERR_FAIL_COND (!p_data.has (" original_width" ));
3246+ ERR_FAIL_COND (!p_data.has (" original_height" ));
31163247 ERR_FAIL_COND (!p_data.has (" format" ));
31173248 ERR_FAIL_COND (!p_data.has (" mipmaps" ));
31183249 ERR_FAIL_COND (!p_data.has (" data" ));
@@ -3133,12 +3264,17 @@ void Image::_set_data(const Dictionary &p_data) {
31333264 ERR_FAIL_COND (ddformat == FORMAT_MAX );
31343265
31353266 initialize_data (dwidth, dheight, dmipmaps, ddformat, ddata);
3267+
3268+ original_width = p_data[" original_width" ];
3269+ original_height = p_data[" original_height" ];
31363270}
31373271
31383272Dictionary Image::_get_data () const {
31393273 Dictionary d;
31403274 d[" width" ] = width;
31413275 d[" height" ] = height;
3276+ d[" original_width" ] = original_width;
3277+ d[" original_height" ] = original_height;
31423278 d[" format" ] = get_format_name (format);
31433279 d[" mipmaps" ] = mipmaps;
31443280 d[" data" ] = data;
@@ -3153,6 +3289,8 @@ void Image::_copy_internals_from(const Image &p_image) {
31533289 format = p_image.format ;
31543290 width = p_image.width ;
31553291 height = p_image.height ;
3292+ original_width = p_image.original_width ;
3293+ original_height = p_image.original_height ;
31563294 mipmaps = p_image.mipmaps ;
31573295 data = p_image.data ;
31583296}
@@ -3515,7 +3653,12 @@ void Image::_bind_methods() {
35153653 ClassDB::bind_method (D_METHOD (" get_width" ), &Image::get_width);
35163654 ClassDB::bind_method (D_METHOD (" get_height" ), &Image::get_height);
35173655 ClassDB::bind_method (D_METHOD (" get_size" ), &Image::get_size);
3656+ ClassDB::bind_method (D_METHOD (" get_original_width" ), &Image::get_original_width);
3657+ ClassDB::bind_method (D_METHOD (" get_original_height" ), &Image::get_original_height);
3658+ ClassDB::bind_method (D_METHOD (" get_original_size" ), &Image::get_original_size);
35183659 ClassDB::bind_method (D_METHOD (" has_mipmaps" ), &Image::has_mipmaps);
3660+ ClassDB::bind_method (D_METHOD (" get_performance_mode" ), &Image::get_performance_mode);
3661+ ClassDB::bind_method (D_METHOD (" set_performance_mode" , " performance_mode" ), &Image::set_performance_mode);
35193662 ClassDB::bind_method (D_METHOD (" get_format" ), &Image::get_format);
35203663 ClassDB::bind_method (D_METHOD (" get_data" ), &Image::get_data);
35213664 ClassDB::bind_method (D_METHOD (" get_data_size" ), &Image::get_data_size);
@@ -3618,6 +3761,9 @@ void Image::_bind_methods() {
36183761 BIND_CONSTANT (MAX_WIDTH );
36193762 BIND_CONSTANT (MAX_HEIGHT );
36203763
3764+ BIND_ENUM_CONSTANT (PERFORMANCE_MODE_ORIGINAL_SIZE );
3765+ BIND_ENUM_CONSTANT (PERFORMANCE_MODE_MAX_SIZE );
3766+ BIND_ENUM_CONSTANT (PERFORMANCE_MODE_DOWNSCALE_SIZE );
36213767 BIND_ENUM_CONSTANT (FORMAT_L8 );
36223768 BIND_ENUM_CONSTANT (FORMAT_LA8 );
36233769 BIND_ENUM_CONSTANT (FORMAT_R8 );
@@ -3748,6 +3894,8 @@ Ref<Image> Image::get_image_from_mipmap(int p_mipmap) const {
37483894 image.instantiate ();
37493895 image->width = w;
37503896 image->height = h;
3897+ image->original_width = w;
3898+ image->original_height = h;
37513899 image->format = format;
37523900 image->data = new_data;
37533901
@@ -4249,6 +4397,8 @@ void Image::renormalize_rgbe9995(uint32_t *p_rgb) {
42494397Image::Image (const uint8_t *p_mem_png_jpg, int p_len) {
42504398 width = 0 ;
42514399 height = 0 ;
4400+ original_width = 0 ;
4401+ original_height = 0 ;
42524402 mipmaps = false ;
42534403 format = FORMAT_L8 ;
42544404
@@ -4281,6 +4431,8 @@ void Image::copy_internals_from(const Ref<Image> &p_image) {
42814431 format = p_image->format ;
42824432 width = p_image->width ;
42834433 height = p_image->height ;
4434+ original_width = p_image->original_width ;
4435+ original_height = p_image->original_height ;
42844436 mipmaps = p_image->mipmaps ;
42854437 data = p_image->data ;
42864438}
0 commit comments