2022-12-20 10:54:01 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								/**************************************************************************/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*  image_compress_astcenc.cpp                                            */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/**************************************************************************/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*                         This file is part of:                          */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*                             GODOT ENGINE                               */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*                        https://godotengine.org                         */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/**************************************************************************/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur.                  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*                                                                        */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Permission is hereby granted, free of charge, to any person obtaining  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* a copy of this software and associated documentation files (the        */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* "Software"), to deal in the Software without restriction, including    */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* without limitation the rights to use, copy, modify, merge, publish,    */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* distribute, sublicense, and/or sell copies of the Software, and to     */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* permit persons to whom the Software is furnished to do so, subject to  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* the following conditions:                                              */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*                                                                        */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* The above copyright notice and this permission notice shall be         */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* included in all copies or substantial portions of the Software.        */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*                                                                        */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,        */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF     */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY   */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,   */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE      */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/**************************************************************************/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "image_compress_astcenc.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "core/os/os.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "core/string/print_string.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <astcenc.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-25 12:17:11 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  _compress_astc ( Image  * r_img ,  Image : : ASTCFormat  p_format )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-20 10:54:01 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									uint64_t  start_time  =  OS : : get_singleton ( ) - > get_ticks_msec ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// TODO: See how to handle lossy quality.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									Image : : Format  img_format  =  r_img - > get_format ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( img_format  > =  Image : : FORMAT_DXT1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return ;  // Do not compress, already compressed.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									bool  is_hdr  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ( img_format  > =  Image : : FORMAT_RH )  & &  ( img_format  < =  Image : : FORMAT_RGBE9995 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										is_hdr  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										r_img - > convert ( Image : : FORMAT_RGBAF ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										r_img - > convert ( Image : : FORMAT_RGBA8 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Determine encoder output format from our enum.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									Image : : Format  target_format  =  Image : : FORMAT_RGBA8 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									astcenc_profile  profile  =  ASTCENC_PRF_LDR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  int  block_x  =  4 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  int  block_y  =  4 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( p_format  = =  Image : : ASTCFormat : : ASTC_FORMAT_4x4 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( is_hdr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											target_format  =  Image : : FORMAT_ASTC_4x4_HDR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											profile  =  ASTCENC_PRF_HDR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											target_format  =  Image : : FORMAT_ASTC_4x4 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  if  ( p_format  = =  Image : : ASTCFormat : : ASTC_FORMAT_8x8 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( is_hdr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											target_format  =  Image : : FORMAT_ASTC_8x8_HDR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											profile  =  ASTCENC_PRF_HDR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											target_format  =  Image : : FORMAT_ASTC_8x8 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										block_x  =  8 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										block_y  =  8 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Compress image data and (if required) mipmaps.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									const  bool  mipmaps  =  r_img - > has_mipmaps ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  width  =  r_img - > get_width ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  height  =  r_img - > get_height ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-25 12:17:11 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  required_width  =  ( width  %  block_x )  ! =  0  ?  width  +  ( block_x  -  ( width  %  block_x ) )  :  width ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  required_height  =  ( height  %  block_y )  ! =  0  ?  height  +  ( block_y  -  ( height  %  block_y ) )  :  height ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( width  ! =  required_width  | |  height  ! =  required_height )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// Resize texture to fit block size.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										r_img - > resize ( required_width ,  required_height ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										width  =  required_width ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										height  =  required_height ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-20 10:54:01 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									print_verbose ( vformat ( " astcenc: Encoding image size %dx%d to format %s%s. " ,  width ,  height ,  Image : : get_format_name ( target_format ) ,  mipmaps  ?  " , with mipmaps "  :  " " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Initialize astcenc.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-25 12:17:11 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  dest_size  =  Image : : get_image_data_size ( width ,  height ,  target_format ,  mipmaps ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									Vector < uint8_t >  dest_data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									dest_data . resize ( dest_size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									uint8_t  * dest_write  =  dest_data . ptrw ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-20 10:54:01 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									astcenc_config  config ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									config . block_x  =  block_x ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									config . block_y  =  block_y ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									config . profile  =  profile ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-25 12:17:11 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									const  float  quality  =  ASTCENC_PRE_MEDIUM ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									astcenc_error  status  =  astcenc_config_init ( profile ,  block_x ,  block_y ,  1 ,  quality ,  0 ,  & config ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-20 10:54:01 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									ERR_FAIL_COND_MSG ( status  ! =  ASTCENC_SUCCESS , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											vformat ( " astcenc: Configuration initialization failed: %s. " ,  astcenc_get_error_string ( status ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Context allocation.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									astcenc_context  * context ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-25 12:17:11 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									const  unsigned  int  thread_count  =  1 ;  // Godot compresses multiple images each on a thread, which is more efficient for large amount of images imported.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-20 10:54:01 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									status  =  astcenc_context_alloc ( & config ,  thread_count ,  & context ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ERR_FAIL_COND_MSG ( status  ! =  ASTCENC_SUCCESS , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											vformat ( " astcenc: Context allocation failed: %s. " ,  astcenc_get_error_string ( status ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									Vector < uint8_t >  image_data  =  r_img - > get_data ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-25 12:17:11 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  mip_count  =  mipmaps  ?  Image : : get_image_required_mipmaps ( width ,  height ,  target_format )  :  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  ( int  i  =  0 ;  i  <  mip_count  +  1 ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										int  src_mip_w ,  src_mip_h ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										int  src_ofs  =  Image : : get_image_mipmap_offset_and_dimensions ( width ,  height ,  r_img - > get_format ( ) ,  i ,  src_mip_w ,  src_mip_h ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-20 10:54:01 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-25 12:17:11 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										const  uint8_t  * slices  =  & image_data . ptr ( ) [ src_ofs ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-20 10:54:01 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-25 12:17:11 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										int  dst_mip_w ,  dst_mip_h ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										int  dst_ofs  =  Image : : get_image_mipmap_offset_and_dimensions ( width ,  height ,  target_format ,  i ,  dst_mip_w ,  dst_mip_h ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// Ensure that mip offset is a multiple of 8 (etcpak expects uint64_t pointer).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ERR_FAIL_COND ( dst_ofs  %  8  ! =  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										uint8_t  * dest_mip_write  =  ( uint8_t  * ) & dest_write [ dst_ofs ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-20 10:54:01 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-25 12:17:11 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										// Compress image.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-20 10:54:01 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-25 12:17:11 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										astcenc_image  image ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										image . dim_x  =  src_mip_w ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										image . dim_y  =  src_mip_h ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										image . dim_z  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										image . data_type  =  ASTCENC_TYPE_U8 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( is_hdr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											image . data_type  =  ASTCENC_TYPE_F32 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										image . data  =  ( void  * * ) ( & slices ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// Compute the number of ASTC blocks in each dimension.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										unsigned  int  block_count_x  =  ( src_mip_w  +  block_x  -  1 )  /  block_x ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										unsigned  int  block_count_y  =  ( src_mip_h  +  block_y  -  1 )  /  block_y ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										size_t  comp_len  =  block_count_x  *  block_count_y  *  16 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										const  astcenc_swizzle  swizzle  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ASTCENC_SWZ_R ,  ASTCENC_SWZ_G ,  ASTCENC_SWZ_B ,  ASTCENC_SWZ_A 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										status  =  astcenc_compress_image ( context ,  & image ,  & swizzle ,  dest_mip_write ,  comp_len ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ERR_BREAK_MSG ( status  ! =  ASTCENC_SUCCESS , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												vformat ( " astcenc: ASTC image compression failed: %s. " ,  astcenc_get_error_string ( status ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										astcenc_compress_reset ( context ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									astcenc_context_free ( context ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-20 10:54:01 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Replace original image with compressed one.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-25 12:17:11 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									r_img - > set_data ( width ,  height ,  mipmaps ,  target_format ,  dest_data ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-20 10:54:01 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									print_verbose ( vformat ( " astcenc: Encoding took %s ms. " ,  rtos ( OS : : get_singleton ( ) - > get_ticks_msec ( )  -  start_time ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  _decompress_astc ( Image  * r_img )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									uint64_t  start_time  =  OS : : get_singleton ( ) - > get_ticks_msec ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Determine decompression parameters from image format.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									Image : : Format  img_format  =  r_img - > get_format ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									bool  is_hdr  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  int  block_x  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  int  block_y  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( img_format  = =  Image : : FORMAT_ASTC_4x4 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										block_x  =  4 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										block_y  =  4 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										is_hdr  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  if  ( img_format  = =  Image : : FORMAT_ASTC_4x4_HDR )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										block_x  =  4 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										block_y  =  4 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										is_hdr  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  if  ( img_format  = =  Image : : FORMAT_ASTC_8x8 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										block_x  =  8 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										block_y  =  8 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										is_hdr  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  if  ( img_format  = =  Image : : FORMAT_ASTC_8x8_HDR )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										block_x  =  8 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										block_y  =  8 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										is_hdr  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ERR_FAIL_MSG ( " astcenc: Cannot decompress Image with a non-ASTC format. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Initialize astcenc.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									astcenc_profile  profile  =  ASTCENC_PRF_LDR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( is_hdr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										profile  =  ASTCENC_PRF_HDR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									astcenc_config  config ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									const  float  quality  =  ASTCENC_PRE_MEDIUM ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-25 12:17:11 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									astcenc_error  status  =  astcenc_config_init ( profile ,  block_x ,  block_y ,  1 ,  quality ,  0 ,  & config ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-20 10:54:01 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									ERR_FAIL_COND_MSG ( status  ! =  ASTCENC_SUCCESS , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											vformat ( " astcenc: Configuration initialization failed: %s. " ,  astcenc_get_error_string ( status ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Context allocation.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									astcenc_context  * context  =  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-25 12:17:11 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									const  unsigned  int  thread_count  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-20 10:54:01 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									status  =  astcenc_context_alloc ( & config ,  thread_count ,  & context ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ERR_FAIL_COND_MSG ( status  ! =  ASTCENC_SUCCESS , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											vformat ( " astcenc: Context allocation failed: %s. " ,  astcenc_get_error_string ( status ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-25 12:17:11 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									Image : : Format  target_format  =  is_hdr  ?  Image : : FORMAT_RGBAF  :  Image : : FORMAT_RGBA8 ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-20 10:54:01 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									const  bool  mipmaps  =  r_img - > has_mipmaps ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  width  =  r_img - > get_width ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  height  =  r_img - > get_height ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-25 12:17:11 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  dest_size  =  Image : : get_image_data_size ( width ,  height ,  target_format ,  mipmaps ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									Vector < uint8_t >  dest_data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									dest_data . resize ( dest_size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									uint8_t  * dest_write  =  dest_data . ptrw ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-20 10:54:01 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-25 12:17:11 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									// Decompress image.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-20 10:54:01 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									Vector < uint8_t >  image_data  =  r_img - > get_data ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-25 12:17:11 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  mip_count  =  mipmaps  ?  Image : : get_image_required_mipmaps ( width ,  height ,  target_format )  :  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-20 10:54:01 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-25 12:17:11 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									for  ( int  i  =  0 ;  i  <  mip_count  +  1 ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										int  src_mip_w ,  src_mip_h ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										int  src_ofs  =  Image : : get_image_mipmap_offset_and_dimensions ( width ,  height ,  r_img - > get_format ( ) ,  i ,  src_mip_w ,  src_mip_h ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										const  uint8_t  * src_data  =  & image_data . ptr ( ) [ src_ofs ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										int  src_size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( i  = =  mip_count )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											src_size  =  image_data . size ( )  -  src_ofs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											int  auxw ,  auxh ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											src_size  =  Image : : get_image_mipmap_offset_and_dimensions ( width ,  height ,  r_img - > get_format ( ) ,  i  +  1 ,  auxw ,  auxh )  -  src_ofs ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-20 10:54:01 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-25 12:17:11 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										int  dst_mip_w ,  dst_mip_h ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										int  dst_ofs  =  Image : : get_image_mipmap_offset_and_dimensions ( width ,  height ,  target_format ,  i ,  dst_mip_w ,  dst_mip_h ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										// Ensure that mip offset is a multiple of 8 (etcpak expects uint64_t pointer).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ERR_FAIL_COND ( dst_ofs  %  8  ! =  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										uint8_t  * dest_mip_write  =  ( uint8_t  * ) & dest_write [ dst_ofs ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										astcenc_image  image ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										image . dim_x  =  dst_mip_w ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										image . dim_y  =  dst_mip_h ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										image . dim_z  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										image . data_type  =  ASTCENC_TYPE_U8 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( is_hdr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											target_format  =  Image : : FORMAT_RGBAF ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											image . data_type  =  ASTCENC_TYPE_F32 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-20 10:54:01 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-25 12:17:11 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										image . data  =  ( void  * * ) ( & dest_mip_write ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-20 10:54:01 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-25 12:17:11 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										const  astcenc_swizzle  swizzle  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ASTCENC_SWZ_R ,  ASTCENC_SWZ_G ,  ASTCENC_SWZ_B ,  ASTCENC_SWZ_A 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-20 10:54:01 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-25 12:17:11 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										status  =  astcenc_decompress_image ( context ,  src_data ,  src_size ,  & image ,  & swizzle ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ERR_BREAK_MSG ( status  ! =  ASTCENC_SUCCESS , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												vformat ( " astcenc: ASTC decompression failed: %s. " ,  astcenc_get_error_string ( status ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ERR_BREAK_MSG ( image . dim_z  >  1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												" astcenc: ASTC decompression failed because this is a 3D texture, which is not supported. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										astcenc_compress_reset ( context ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-20 10:54:01 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-25 12:17:11 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									astcenc_context_free ( context ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									// Replace original image with compressed one.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-20 10:54:01 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-01-25 12:17:11 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									r_img - > set_data ( width ,  height ,  mipmaps ,  target_format ,  dest_data ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-20 10:54:01 -08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									print_verbose ( vformat ( " astcenc: Decompression took %s ms. " ,  rtos ( OS : : get_singleton ( ) - > get_ticks_msec ( )  -  start_time ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								}