diff options
author | Rémi Verschelde <rverschelde@gmail.com> | 2017-01-02 21:38:20 +0100 |
---|---|---|
committer | Rémi Verschelde <rverschelde@gmail.com> | 2017-01-02 21:52:26 +0100 |
commit | 3f3f5a5359973e95e94148676a9793d6f52468f3 (patch) | |
tree | 65adf17c3d3f8d3a83bec29f51142fe884e942d8 /core | |
parent | db46a344180d4eae1455e97e22bf84c9c304be7c (diff) | |
parent | 2820b2d82b2ed747011e37c543aefc6d4d4edee9 (diff) |
Merge remote-tracking branch 'origin/gles3' into gles3-on-master
Various merge conflicts have been fixed manually and some mistakes
might have been made - time will tell :)
Diffstat (limited to 'core')
-rw-r--r-- | core/error_macros.h | 3 | ||||
-rw-r--r-- | core/globals.cpp | 47 | ||||
-rw-r--r-- | core/image.cpp | 1213 | ||||
-rw-r--r-- | core/image.h | 200 | ||||
-rw-r--r-- | core/image_quantize.cpp | 365 | ||||
-rw-r--r-- | core/io/marshalls.cpp | 2 | ||||
-rw-r--r-- | core/io/resource_format_binary.cpp | 94 | ||||
-rw-r--r-- | core/io/resource_format_xml.cpp | 61 | ||||
-rw-r--r-- | core/math/camera_matrix.cpp | 33 | ||||
-rw-r--r-- | core/math/camera_matrix.h | 5 | ||||
-rw-r--r-- | core/math/math_funcs.h | 102 | ||||
-rw-r--r-- | core/os/os.cpp | 1 | ||||
-rw-r--r-- | core/os/os.h | 3 | ||||
-rw-r--r-- | core/pair.h | 3 | ||||
-rw-r--r-- | core/rid.cpp | 12 | ||||
-rw-r--r-- | core/rid.h | 204 | ||||
-rw-r--r-- | core/ustring.cpp | 2 | ||||
-rw-r--r-- | core/variant_call.cpp | 71 | ||||
-rw-r--r-- | core/variant_parser.cpp | 80 |
19 files changed, 922 insertions, 1579 deletions
diff --git a/core/error_macros.h b/core/error_macros.h index c3f1c0b017..ac86ef432b 100644 --- a/core/error_macros.h +++ b/core/error_macros.h @@ -49,7 +49,8 @@ enum ErrorHandlerType { ERR_HANDLER_ERROR, ERR_HANDLER_WARNING, - ERR_HANDLER_SCRIPT + ERR_HANDLER_SCRIPT, + ERR_HANDLER_SHADER, }; typedef void (*ErrorHandlerFunc)(void*,const char*,const char*,int p_line,const char *, const char *,ErrorHandlerType p_type); diff --git a/core/globals.cpp b/core/globals.cpp index 3e9addecc0..5f47bfef2d 100644 --- a/core/globals.cpp +++ b/core/globals.cpp @@ -658,37 +658,37 @@ static Variant _decode_variant(const String& p_string) { String format=params[0].strip_edges(); Image::Format imgformat; - +/* if (format=="grayscale") { - imgformat=Image::FORMAT_GRAYSCALE; + imgformat=Image::FORMAT_L8; } else if (format=="intensity") { imgformat=Image::FORMAT_INTENSITY; } else if (format=="grayscale_alpha") { - imgformat=Image::FORMAT_GRAYSCALE_ALPHA; + imgformat=Image::FORMAT_LA8; } else if (format=="rgb") { - imgformat=Image::FORMAT_RGB; + imgformat=Image::FORMAT_RGB8; } else if (format=="rgba") { - imgformat=Image::FORMAT_RGBA; + imgformat=Image::FORMAT_RGBA8; } else if (format=="indexed") { imgformat=Image::FORMAT_INDEXED; } else if (format=="indexed_alpha") { imgformat=Image::FORMAT_INDEXED_ALPHA; } else if (format=="bc1") { - imgformat=Image::FORMAT_BC1; + imgformat=Image::FORMAT_DXT1; } else if (format=="bc2") { - imgformat=Image::FORMAT_BC2; + imgformat=Image::FORMAT_DXT3; } else if (format=="bc3") { - imgformat=Image::FORMAT_BC3; + imgformat=Image::FORMAT_DXT5; } else if (format=="bc4") { - imgformat=Image::FORMAT_BC4; + imgformat=Image::FORMAT_ATI1; } else if (format=="bc5") { - imgformat=Image::FORMAT_BC5; + imgformat=Image::FORMAT_ATI2; } else if (format=="custom") { imgformat=Image::FORMAT_CUSTOM; } else { ERR_FAIL_V( Image() ); - } + }*/ int mipmaps=params[1].to_int(); int w=params[2].to_int(); @@ -975,26 +975,30 @@ static String _encode_variant(const Variant& p_variant) { if (!img.empty()) { String format; + + /* switch(img.get_format()) { - case Image::FORMAT_GRAYSCALE: format="grayscale"; break; + case Image::FORMAT_L8: format="grayscale"; break; case Image::FORMAT_INTENSITY: format="intensity"; break; - case Image::FORMAT_GRAYSCALE_ALPHA: format="grayscale_alpha"; break; - case Image::FORMAT_RGB: format="rgb"; break; - case Image::FORMAT_RGBA: format="rgba"; break; + case Image::FORMAT_LA8: format="grayscale_alpha"; break; + case Image::FORMAT_RGB8: format="rgb"; break; + case Image::FORMAT_RGBA8: format="rgba"; break; case Image::FORMAT_INDEXED : format="indexed"; break; case Image::FORMAT_INDEXED_ALPHA: format="indexed_alpha"; break; - case Image::FORMAT_BC1: format="bc1"; break; - case Image::FORMAT_BC2: format="bc2"; break; - case Image::FORMAT_BC3: format="bc3"; break; - case Image::FORMAT_BC4: format="bc4"; break; - case Image::FORMAT_BC5: format="bc5"; break; + case Image::FORMAT_DXT1: format="bc1"; break; + case Image::FORMAT_DXT3: format="bc2"; break; + case Image::FORMAT_DXT5: format="bc3"; break; + case Image::FORMAT_ATI1: format="bc4"; break; + case Image::FORMAT_ATI2: format="bc5"; break; case Image::FORMAT_CUSTOM: format="custom custom_size="+itos(img.get_data().size())+""; break; default: {} } + */ + str+=format+", "; - str+=itos(img.get_mipmaps())+", "; + str+=itos(img.has_mipmaps())+", "; str+=itos(img.get_width())+", "; str+=itos(img.get_height())+", "; DVector<uint8_t> data = img.get_data(); @@ -1400,6 +1404,7 @@ void Globals::set_custom_property_info(const String& p_prop,const PropertyInfo& ERR_FAIL_COND(!props.has(p_prop)); custom_prop_info[p_prop]=p_info; + custom_prop_info[p_prop].name=p_prop; } diff --git a/core/image.cpp b/core/image.cpp index 3411a45aad..e949cd9b38 100644 --- a/core/image.cpp +++ b/core/image.cpp @@ -36,86 +36,186 @@ const char* Image::format_names[Image::FORMAT_MAX]={ - "Grayscale", - "Intensity", - "GrayscaleAlpha", - "RGB", - "RGBA", - "Indexed", - "IndexedAlpha", - "YUV422", - "YUV444", - "BC1", - "BC2", - "BC3", - "BC4", - "BC5", - "PVRTC2", - "PVRTC2Alpha", + "Lum8", //luminance + "LumAlpha8", //luminance-alpha + "Red8", + "RedGreen", + "RGB8", + "RGBA8", + "RGB565", //16 bit + "RGBA4444", + "RGBA5551", + "RFloat", //float + "RGFloat", + "RGBFloat", + "RGBAFloat", + "RHalf", //half float + "RGHalf", + "RGBHalf", + "RGBAHalf", + "DXT1", //s3tc + "DXT3", + "DXT5", + "ATI1", + "ATI2", + "BPTC_RGBA", + "BPTC_RGBF", + "BPTC_RGBFU", + "PVRTC2", //pvrtc + "PVRTC2A", "PVRTC4", - "PVRTC4Alpha", - "ETC", - "ATC", - "ATCAlphaExp", - "ATCAlphaInterp", + "PVRTC4A", + "ETC", //etc1 + "ETC2_R11", //etc2 + "ETC2_R11S", //signed", NOT srgb. + "ETC2_RG11", + "ETC2_RG11S", + "ETC2_RGB8", + "ETC2_RGBA8", + "ETC2_RGB8A1", }; SavePNGFunc Image::save_png_func = NULL; -void Image::_put_pixel(int p_x,int p_y, const BColor& p_color, unsigned char *p_data) { - _put_pixelw(p_x,p_y,width,p_color,p_data); +void Image::_put_pixelb(int p_x,int p_y, uint32_t p_pixelsize,uint8_t *p_dst,const uint8_t *p_src) { + + uint32_t ofs=(p_y*width+p_x)*p_pixelsize; + + for(uint32_t i=0;i<p_pixelsize;i++) { + p_dst[ofs+i]=p_src[i]; + } } -void Image::_put_pixelw(int p_x,int p_y, int p_width, const BColor& p_color, unsigned char *p_data) { +void Image::_get_pixelb(int p_x,int p_y, uint32_t p_pixelsize,const uint8_t *p_src,uint8_t *p_dst) { + uint32_t ofs=(p_y*width+p_x)*p_pixelsize; - int ofs=p_y*p_width+p_x; + for(uint32_t i=0;i<p_pixelsize;i++) { + p_dst[ofs]=p_src[ofs+i]; + } - switch(format) { - case FORMAT_GRAYSCALE: { +} - p_data[ofs]=p_color.gray(); - } break; - case FORMAT_INTENSITY: { - p_data[ofs]=p_color.a; - } break; - case FORMAT_GRAYSCALE_ALPHA: { +int Image::get_format_pixel_size(Format p_format) { + + switch(p_format) { + case FORMAT_L8: return 1; //luminance + case FORMAT_LA8: return 2; //luminance-alpha + case FORMAT_R8: return 1; + case FORMAT_RG8: return 2; + case FORMAT_RGB8: return 3; + case FORMAT_RGBA8: return 4; + case FORMAT_RGB565: return 2; //16 bit + case FORMAT_RGBA4444: return 2; + case FORMAT_RGBA5551: return 2; + case FORMAT_RF: return 4; //float + case FORMAT_RGF: return 8; + case FORMAT_RGBF: return 12; + case FORMAT_RGBAF: return 16; + case FORMAT_RH: return 2; //half float + case FORMAT_RGH: return 4; + case FORMAT_RGBH: return 8; + case FORMAT_RGBAH: return 12; + case FORMAT_DXT1: return 1; //s3tc bc1 + case FORMAT_DXT3: return 1; //bc2 + case FORMAT_DXT5: return 1; //bc3 + case FORMAT_ATI1: return 1; //bc4 + case FORMAT_ATI2: return 1; //bc5 + case FORMAT_BPTC_RGBA: return 1; //btpc bc6h + case FORMAT_BPTC_RGBF: return 1; //float / + case FORMAT_BPTC_RGBFU: return 1; //unsigned float + case FORMAT_PVRTC2: return 1; //pvrtc + case FORMAT_PVRTC2A: return 1; + case FORMAT_PVRTC4: return 1; + case FORMAT_PVRTC4A: return 1; + case FORMAT_ETC: return 1; //etc1 + case FORMAT_ETC2_R11: return 1; //etc2 + case FORMAT_ETC2_R11S: return 1; //signed: return 1; NOT srgb. + case FORMAT_ETC2_RG11: return 1; + case FORMAT_ETC2_RG11S: return 1; + case FORMAT_ETC2_RGB8: return 1; + case FORMAT_ETC2_RGBA8: return 1; + case FORMAT_ETC2_RGB8A1: return 1; + case FORMAT_MAX: {} - p_data[ofs*2]=p_color.gray(); - p_data[ofs*2+1]=p_color.a; + } + return 0; +} + +void Image::get_format_min_pixel_size(Format p_format,int &r_w, int &r_h) { + + + switch(p_format) { + case FORMAT_DXT1: //s3tc bc1 + case FORMAT_DXT3: //bc2 + case FORMAT_DXT5: //bc3 + case FORMAT_ATI1: //bc4 + case FORMAT_ATI2: { //bc5 case case FORMAT_DXT1: + + r_w=4; + r_h=4; } break; - case FORMAT_RGB: { + case FORMAT_PVRTC2: + case FORMAT_PVRTC2A: { - p_data[ofs*3+0]=p_color.r; - p_data[ofs*3+1]=p_color.g; - p_data[ofs*3+2]=p_color.b; + r_w=16; + r_h=8; + } break; + case FORMAT_PVRTC4A: + case FORMAT_PVRTC4: { + r_w=8; + r_h=8; } break; - case FORMAT_RGBA: { + case FORMAT_ETC: { - p_data[ofs*4+0]=p_color.r; - p_data[ofs*4+1]=p_color.g; - p_data[ofs*4+2]=p_color.b; - p_data[ofs*4+3]=p_color.a; + r_w=4; + r_h=4; + } break; + case FORMAT_BPTC_RGBA: + case FORMAT_BPTC_RGBF: + case FORMAT_BPTC_RGBFU: { + r_w=4; + r_h=4; } break; - case FORMAT_INDEXED: - case FORMAT_INDEXED_ALPHA: { + case FORMAT_ETC2_R11: //etc2 + case FORMAT_ETC2_R11S: //signed: NOT srgb. + case FORMAT_ETC2_RG11: + case FORMAT_ETC2_RG11S: + case FORMAT_ETC2_RGB8: + case FORMAT_ETC2_RGBA8: + case FORMAT_ETC2_RGB8A1: { + + r_w=4; + r_h=4; - ERR_FAIL(); } break; - default: {}; + default: { + r_w=1; + r_h=1; + } break; } } +int Image::get_format_pixel_rshift(Format p_format) { + + if (p_format==FORMAT_DXT1 || p_format==FORMAT_ATI1 || p_format==FORMAT_PVRTC4 || p_format==FORMAT_PVRTC4A || p_format==FORMAT_ETC || p_format==FORMAT_ETC2_R11 || p_format==FORMAT_ETC2_R11S || p_format==FORMAT_ETC2_RGB8 || p_format==FORMAT_ETC2_RGB8A1) + return 1; + else if (p_format==FORMAT_PVRTC2 || p_format==FORMAT_PVRTC2A) + return 2; + else + return 0; +} + void Image::_get_mipmap_offset_and_size(int p_mipmap,int &r_offset, int &r_width,int &r_height) const { @@ -126,7 +226,7 @@ void Image::_get_mipmap_offset_and_size(int p_mipmap,int &r_offset, int &r_width int pixel_size = get_format_pixel_size(format); int pixel_rshift = get_format_pixel_rshift(format); int minw,minh; - _get_format_min_data_size(format,minw,minh); + get_format_min_pixel_size(format,minw,minh); for(int i=0;i<p_mipmap;i++) { int s = w*h; @@ -173,191 +273,76 @@ void Image::get_mipmap_offset_size_and_dimensions(int p_mipmap,int &r_ofs, int & } -void Image::put_pixel(int p_x,int p_y, const Color& p_color,int p_mipmap){ - - ERR_FAIL_INDEX(p_mipmap,mipmaps+1); - int ofs,w,h; - _get_mipmap_offset_and_size(p_mipmap,ofs,w,h); - ERR_FAIL_INDEX(p_x,w); - ERR_FAIL_INDEX(p_y,h); - - DVector<uint8_t>::Write wp = data.write(); - unsigned char *data_ptr=wp.ptr(); - - _put_pixelw(p_x,p_y,w,BColor(p_color.r*255,p_color.g*255,p_color.b*255,p_color.a*255),&data_ptr[ofs]); +int Image::get_width() const { + return width; } +int Image::get_height() const{ -Image::BColor Image::_get_pixel(int p_x,int p_y,const unsigned char *p_data,int p_data_size) const{ - - return _get_pixelw(p_x,p_y,width,p_data,p_data_size); + return height; } -Image::BColor Image::_get_pixelw(int p_x,int p_y,int p_width,const unsigned char *p_data,int p_data_size) const{ - int ofs=p_y*p_width+p_x; - BColor result(0,0,0,0); - switch(format) { - - case FORMAT_GRAYSCALE: { - - result=BColor(p_data[ofs],p_data[ofs],p_data[ofs],255.0); - } break; - case FORMAT_INTENSITY: { - - result=BColor(255,255,255,p_data[ofs]); - } break; - case FORMAT_GRAYSCALE_ALPHA: { - - result=BColor(p_data[ofs*2],p_data[ofs*2],p_data[ofs*2],p_data[ofs*2+1]); - - } break; - case FORMAT_RGB: { - - result=BColor(p_data[ofs*3],p_data[ofs*3+1],p_data[ofs*3+2]); - - } break; - case FORMAT_RGBA: { - - result=BColor(p_data[ofs*4],p_data[ofs*4+1],p_data[ofs*4+2],p_data[ofs*4+3]); - } break; - case FORMAT_INDEXED_ALPHA: { - - int pitch = 4; - const uint8_t* pal = &p_data[ p_data_size - pitch * 256 ]; - int idx = p_data[ofs]; - result=BColor(pal[idx * pitch + 0] , pal[idx * pitch + 1] , pal[idx * pitch + 2] , pal[idx * pitch + 3] ); - - } break; - case FORMAT_INDEXED: { - - int pitch = 3; - const uint8_t* pal = &p_data[ p_data_size - pitch * 256 ]; - int idx = p_data[ofs]; - result=BColor(pal[idx * pitch + 0] , pal[idx * pitch + 1] , pal[idx * pitch + 2] ,255); - } break; - case FORMAT_YUV_422: { - - int y, u, v; - if (p_x % 2) { - const uint8_t* yp = &p_data[p_width * 2 * p_y + p_x * 2]; - u = *(yp-1); - y = yp[0]; - v = yp[1]; - } else { - - const uint8_t* yp = &p_data[p_width * 2 * p_y + p_x * 2]; - y = yp[0]; - u = yp[1]; - v = yp[3]; - }; - - int32_t r = 1.164 * (y - 16) + 1.596 * (v - 128); - int32_t g = 1.164 * (y - 16) - 0.813 * (v - 128) - 0.391 * (u - 128); - int32_t b = 1.164 * (y - 16) + 2.018 * (u - 128); - result = BColor(CLAMP(r, 0, 255), CLAMP(g, 0, 255), CLAMP(b, 0, 255)); - } break; - case FORMAT_YUV_444: { - - uint8_t y, u, v; - const uint8_t* yp = &p_data[p_width * 3 * p_y + p_x * 3]; - y = yp[0]; - u = yp[1]; - v = yp[2]; - - int32_t r = 1.164 * (y - 16) + 1.596 * (v - 128); - int32_t g = 1.164 * (y - 16) - 0.813 * (v - 128) - 0.391 * (u - 128); - int32_t b = 1.164 * (y - 16) + 2.018 * (u - 128); - result = BColor(CLAMP(r, 0, 255), CLAMP(g, 0, 255), CLAMP(b, 0, 255)); - } break; - default:{} - - } - - return result; +bool Image::has_mipmaps() const { + return mipmaps; } -void Image::put_indexed_pixel(int p_x, int p_y, uint8_t p_idx,int p_mipmap) { - - ERR_FAIL_COND(format != FORMAT_INDEXED && format != FORMAT_INDEXED_ALPHA); - ERR_FAIL_INDEX(p_mipmap,mipmaps+1); - int ofs,w,h; - _get_mipmap_offset_and_size(p_mipmap,ofs,w,h); - ERR_FAIL_INDEX(p_x,w); - ERR_FAIL_INDEX(p_y,h); - - data.set(ofs + p_y * w + p_x, p_idx); -}; - -uint8_t Image::get_indexed_pixel(int p_x, int p_y,int p_mipmap) const { - - ERR_FAIL_COND_V(format != FORMAT_INDEXED && format != FORMAT_INDEXED_ALPHA, 0); - - ERR_FAIL_INDEX_V(p_mipmap,mipmaps+1,0); - int ofs,w,h; - _get_mipmap_offset_and_size(p_mipmap,ofs,w,h); - ERR_FAIL_INDEX_V(p_x,w,0); - ERR_FAIL_INDEX_V(p_y,h,0); - - - return data[ofs + p_y * w + p_x]; -}; - -void Image::set_pallete(const DVector<uint8_t>& p_data) { +int Image::get_mipmap_count() const { + if (mipmaps) + return get_image_required_mipmaps(width,height,format); + else + return 0; +} - int len = p_data.size(); - ERR_FAIL_COND(format != FORMAT_INDEXED && format != FORMAT_INDEXED_ALPHA); - ERR_FAIL_COND(format == FORMAT_INDEXED && len!=(256*3)); - ERR_FAIL_COND(format == FORMAT_INDEXED_ALPHA && len!=(256*4)); +//using template generates perfectly optimized code due to constant expression reduction and unused variable removal present in all compilers +template<uint32_t read_bytes,bool read_alpha,uint32_t write_bytes,bool write_alpha,bool read_gray,bool write_gray> +static void _convert( int p_width,int p_height,const uint8_t* p_src,uint8_t* p_dst ){ - int ofs,w,h; - _get_mipmap_offset_and_size(mipmaps+1,ofs,w,h); - int pal_ofs = ofs; - data.resize(pal_ofs + p_data.size()); - DVector<uint8_t>::Write wp = data.write(); - unsigned char *dst=wp.ptr() + pal_ofs; + for(int y=0;y<p_height;y++) { + for(int x=0;x<p_width;x++) { - DVector<uint8_t>::Read r = p_data.read(); - const unsigned char *src=r.ptr(); + const uint8_t *rofs = &p_src[((y*p_width)+x)*(read_bytes+(read_alpha?1:0))]; + uint8_t *wofs = &p_dst[((y*p_width)+x)*(write_bytes+(write_alpha?1:0))]; - copymem(dst, src, len); -}; + uint8_t rgba[4]; -int Image::get_width() const { - - return width; -} -int Image::get_height() const{ - - return height; -} - -int Image::get_mipmaps() const { + if (read_gray) { + rgba[0]=rofs[0]; + rgba[1]=rofs[0]; + rgba[2]=rofs[0]; + } else { + for(uint32_t i=0;i<MAX(read_bytes,write_bytes);i++) { + rgba[i]=(i<read_bytes)?rofs[i]:0; + } + } - return mipmaps; -} + if (read_alpha || write_alpha) { + rgba[3]=read_alpha?rofs[read_bytes]:255; + } -Color Image::get_pixel(int p_x,int p_y,int p_mipmap) const { + if (write_gray) { + //TODO: not correct grayscale, should use fixed point version of actual weights + wofs[0]=uint8_t((uint16_t(rofs[0])+uint16_t(rofs[1])+uint16_t(rofs[2]))/3); + } else { + for(uint32_t i=0;i<write_bytes;i++) { + wofs[i]=rgba[i]; + } + } - ERR_FAIL_INDEX_V(p_mipmap,mipmaps+1,Color()); - int ofs,w,h; - _get_mipmap_offset_and_size(p_mipmap,ofs,w,h); - ERR_FAIL_INDEX_V(p_x,w,Color()); - ERR_FAIL_INDEX_V(p_y,h,Color()); + if (write_alpha) { + wofs[write_bytes]=rgba[3]; + } + } + } - int len = data.size(); - DVector<uint8_t>::Read r = data.read(); - const unsigned char*data_ptr=r.ptr(); - BColor c = _get_pixelw(p_x,p_y,w,&data_ptr[ofs],len); - return Color( c.r/255.0,c.g/255.0,c.b/255.0,c.a/255.0 ); } void Image::convert( Format p_new_format ){ @@ -368,22 +353,17 @@ void Image::convert( Format p_new_format ){ if (p_new_format==format) return; - if (format>=FORMAT_BC1 || p_new_format>=FORMAT_BC1) { - ERR_EXPLAIN("Cannot convert to <-> from compressed/custom image formats (for now)."); - ERR_FAIL(); - } - - if (p_new_format==FORMAT_INDEXED || p_new_format==FORMAT_INDEXED_ALPHA) { + if (format>=FORMAT_RGB565 || p_new_format>=FORMAT_RGB565) { - - return; + ERR_EXPLAIN("Cannot convert to <-> from non byte formats."); + ERR_FAIL(); } Image new_img(width,height,0,p_new_format); - int len=data.size(); +// int len=data.size(); DVector<uint8_t>::Read r = data.read(); DVector<uint8_t>::Write w = new_img.data.write(); @@ -391,35 +371,56 @@ void Image::convert( Format p_new_format ){ const uint8_t *rptr = r.ptr(); uint8_t *wptr = w.ptr(); - if (p_new_format==FORMAT_RGBA && format==FORMAT_INDEXED_ALPHA) { + int conversion_type = format | p_new_format<<8; + + switch(conversion_type) { + + case FORMAT_L8|(FORMAT_LA8<<8): _convert<1,false,1,true,true,true>( width, height,rptr, wptr ); break; + case FORMAT_L8|(FORMAT_R8<<8): _convert<1,false,1,false,true,false>( width, height,rptr, wptr ); break; + case FORMAT_L8|(FORMAT_RG8<<8): _convert<1,false,2,false,true,false>( width, height,rptr, wptr ); break; + case FORMAT_L8|(FORMAT_RGB8<<8): _convert<1,false,3,false,true,false>( width, height,rptr, wptr ); break; + case FORMAT_L8|(FORMAT_RGBA8<<8): _convert<1,false,3,true,true,false>( width, height,rptr, wptr ); break; + case FORMAT_LA8|(FORMAT_L8<<8): _convert<1,true,1,false,true,true>( width, height,rptr, wptr ); break; + case FORMAT_LA8|(FORMAT_R8<<8): _convert<1,true,1,false,true,false>( width, height,rptr, wptr ); break; + case FORMAT_LA8|(FORMAT_RG8<<8): _convert<1,true,2,false,true,false>( width, height,rptr, wptr ); break; + case FORMAT_LA8|(FORMAT_RGB8<<8): _convert<1,true,3,false,true,false>( width, height,rptr, wptr ); break; + case FORMAT_LA8|(FORMAT_RGBA8<<8): _convert<1,true,3,true,true,false>( width, height,rptr, wptr ); break; + case FORMAT_R8|(FORMAT_L8<<8): _convert<1,false,1,false,false,true>( width, height,rptr, wptr ); break; + case FORMAT_R8|(FORMAT_LA8<<8): _convert<1,false,1,true,false,true>( width, height,rptr, wptr ); break; + case FORMAT_R8|(FORMAT_RG8<<8): _convert<1,false,2,false,false,false>( width, height,rptr, wptr ); break; + case FORMAT_R8|(FORMAT_RGB8<<8): _convert<1,false,3,false,false,false>( width, height,rptr, wptr ); break; + case FORMAT_R8|(FORMAT_RGBA8<<8): _convert<1,false,3,true,false,false>( width, height,rptr, wptr ); break; + case FORMAT_RG8|(FORMAT_L8<<8): _convert<2,false,1,false,false,true>( width, height,rptr, wptr ); break; + case FORMAT_RG8|(FORMAT_LA8<<8): _convert<2,false,1,true,false,true>( width, height,rptr, wptr ); break; + case FORMAT_RG8|(FORMAT_R8<<8): _convert<2,false,1,false,false,false>( width, height,rptr, wptr ); break; + case FORMAT_RG8|(FORMAT_RGB8<<8): _convert<2,false,3,false,false,false>( width, height,rptr, wptr ); break; + case FORMAT_RG8|(FORMAT_RGBA8<<8): _convert<2,false,3,true,false,false>( width, height,rptr, wptr ); break; + case FORMAT_RGB8|(FORMAT_L8<<8): _convert<3,false,1,false,false,true>( width, height,rptr, wptr ); break; + case FORMAT_RGB8|(FORMAT_LA8<<8): _convert<3,false,1,true,false,true>( width, height,rptr, wptr ); break; + case FORMAT_RGB8|(FORMAT_R8<<8): _convert<3,false,1,false,false,false>( width, height,rptr, wptr ); break; + case FORMAT_RGB8|(FORMAT_RG8<<8): _convert<3,false,2,false,false,false>( width, height,rptr, wptr ); break; + case FORMAT_RGB8|(FORMAT_RGBA8<<8): _convert<3,false,3,true,false,false>( width, height,rptr, wptr ); break; + case FORMAT_RGBA8|(FORMAT_L8<<8): _convert<3,true,1,false,false,true>( width, height,rptr, wptr ); break; + case FORMAT_RGBA8|(FORMAT_LA8<<8): _convert<3,true,1,true,false,true>( width, height,rptr, wptr ); break; + case FORMAT_RGBA8|(FORMAT_R8<<8): _convert<3,true,1,false,false,false>( width, height,rptr, wptr ); break; + case FORMAT_RGBA8|(FORMAT_RG8<<8): _convert<3,true,2,false,false,false>( width, height,rptr, wptr ); break; + case FORMAT_RGBA8|(FORMAT_RGB8<<8): _convert<3,true,3,false,false,false>( width, height,rptr, wptr ); break; - //optimized unquantized form - int dataend = len-256*4; - const uint32_t *palpos = (const uint32_t*)&rptr[dataend]; - uint32_t *dst32 = (uint32_t *)wptr; - - for(int i=0;i<dataend;i++) - dst32[i]=palpos[rptr[i]]; //since this is read/write, endianness is not a problem - - } else { - - //this is temporary, must find a faster way to do it. - for(int i=0;i<width;i++) - for(int j=0;j<height;j++) - new_img._put_pixel(i,j,_get_pixel(i,j,rptr,len),wptr); } + r = DVector<uint8_t>::Read(); w = DVector<uint8_t>::Write(); - bool gen_mipmaps=mipmaps>0; + bool gen_mipmaps=mipmaps; + +// mipmaps=false; *this=new_img; if (gen_mipmaps) generate_mipmaps(); - } Image::Format Image::get_format() const{ @@ -460,13 +461,13 @@ static void _scale_cubic(const uint8_t* p_src, uint8_t* p_dst, uint32_t p_src_wi int xmax = width - 1; // temporary pointer - for ( int y = 0; y < p_dst_height; y++ ) { + for ( uint32_t y = 0; y < p_dst_height; y++ ) { // Y coordinates oy = (double) y * yfac - 0.5f; oy1 = (int) oy; dy = oy - (double) oy1; - for ( int x = 0; x < p_dst_width; x++ ) { + for ( uint32_t x = 0; x < p_dst_width; x++ ) { // X coordinates ox = (double) x * xfac - 0.5f; ox1 = (int) ox; @@ -650,10 +651,6 @@ void Image::resize( int p_width, int p_height, Interpolation p_interpolation ) { Image dst( p_width, p_height, 0, format ); - if (format==FORMAT_INDEXED) - p_interpolation=INTERPOLATE_NEAREST; - - DVector<uint8_t>::Read r = data.read(); const unsigned char*r_ptr=r.ptr(); @@ -722,18 +719,33 @@ void Image::crop( int p_width, int p_height ) { if (p_width==width && p_height==height) return; + uint8_t pdata[16]; //largest is 16 + uint32_t pixel_size = get_format_pixel_size(format); + Image dst( p_width, p_height,0, format ); + { + DVector<uint8_t>::Read r = data.read(); + DVector<uint8_t>::Write w = dst.data.write(); - for (int y=0;y<p_height;y++) { + for (int y=0;y<p_height;y++) { - for (int x=0;x<p_width;x++) { + for (int x=0;x<p_width;x++) { - Color col = (x>=width || y>=height)? Color() : get_pixel(x,y); - dst.put_pixel(x,y,col); + if ((x>=width || y>=height)) { + for(uint32_t i=0;i<pixel_size;i++) + pdata[i]=0; + } else { + _get_pixelb(x,y,pixel_size,r.ptr(),pdata); + } + + + dst._put_pixelb(x,y,pixel_size,w.ptr(),pdata); + } } } + if (mipmaps>0) dst.generate_mipmaps(); *this=dst; @@ -754,18 +766,28 @@ void Image::flip_y() { + { + DVector<uint8_t>::Write w = data.write(); + uint8_t up[16]; + uint8_t down[16]; + uint32_t pixel_size = get_format_pixel_size(format); - for (int y=0;y<(height/2);y++) { + for (int y=0;y<height;y++) { - for (int x=0;x<width;x++) { + for (int x=0;x<width;x++) { - Color up = get_pixel(x,y); - Color down = get_pixel(x,height-y-1); - put_pixel(x,y,down); - put_pixel(x,height-y-1,up); + _get_pixelb(x,y,pixel_size,w.ptr(),up); + _get_pixelb(x,height-y-1,pixel_size,w.ptr(),down); + + _put_pixelb(x,height-y-1,pixel_size,w.ptr(),up); + _put_pixelb(x,y,pixel_size,w.ptr(),down); + + } } } + + if (gm) generate_mipmaps();; @@ -782,15 +804,25 @@ void Image::flip_x() { if (gm) clear_mipmaps();; - for (int y=0;y<(height/2);y++) { - for (int x=0;x<width;x++) { + { + DVector<uint8_t>::Write w = data.write(); + uint8_t up[16]; + uint8_t down[16]; + uint32_t pixel_size = get_format_pixel_size(format); + + for (int y=0;y<height;y++) { + + for (int x=0;x<width;x++) { - Color up = get_pixel(x,y); - Color down = get_pixel(width-x-1,y); - put_pixel(x,y,down); - put_pixel(width-x-1,y,up); + _get_pixelb(x,y,pixel_size,w.ptr(),up); + _get_pixelb(width-x-1,y,pixel_size,w.ptr(),down); + + _put_pixelb(width-x-1,y,pixel_size,w.ptr(),up); + _put_pixelb(x,y,pixel_size,w.ptr(),down); + + } } } @@ -809,15 +841,7 @@ int Image::_get_dst_image_size(int p_width, int p_height, Format p_format,int &r int pixsize=get_format_pixel_size(p_format); int pixshift=get_format_pixel_rshift(p_format); int minw,minh; - _get_format_min_data_size(p_format,minw,minh); - - - switch(p_format) { - - case FORMAT_INDEXED: pixsize=1; size=256*3; break; - case FORMAT_INDEXED_ALPHA: pixsize=1; size=256*4;break; - default: {} - } ; + get_format_min_pixel_size(p_format,minw,minh); while(true) { @@ -849,20 +873,7 @@ int Image::_get_dst_image_size(int p_width, int p_height, Format p_format,int &r bool Image::_can_modify(Format p_format) const { - switch(p_format) { - - //these are OK - case FORMAT_GRAYSCALE: - case FORMAT_INTENSITY: - case FORMAT_GRAYSCALE_ALPHA: - case FORMAT_RGB: - case FORMAT_RGBA: - return true; - default: - return false; - } - - return false; + return p_format<FORMAT_RGB565; } template<int CC> @@ -903,16 +914,16 @@ static void _generate_po2_mipmap(const uint8_t* p_src, uint8_t* p_dst, uint32_t void Image::expand_x2_hq2x() { - ERR_FAIL_COND(format>=FORMAT_INDEXED); + ERR_FAIL_COND(!_can_modify(format)); Format current = format; - bool mipmaps=get_mipmaps(); - if (mipmaps) { + bool mm=has_mipmaps(); + if (mm) { clear_mipmaps(); } - if (current!=FORMAT_RGBA) - convert(FORMAT_RGBA); + if (current!=FORMAT_RGBA8) + convert(FORMAT_RGBA8); DVector<uint8_t> dest; dest.resize(width*2*height*2*4); @@ -930,7 +941,7 @@ void Image::expand_x2_hq2x() { data=dest; - if (current!=FORMAT_RGBA) + if (current!=FORMAT_RGBA8) convert(current); if (mipmaps) { @@ -941,7 +952,6 @@ void Image::expand_x2_hq2x() { void Image::shrink_x2() { - ERR_FAIL_COND(format==FORMAT_INDEXED || format==FORMAT_INDEXED_ALPHA); ERR_FAIL_COND( data.size()==0 ); @@ -964,7 +974,6 @@ void Image::shrink_x2() { copymem(w.ptr(),&r[ofs],new_size); } - mipmaps--; width/=2; height/=2; data=new_img; @@ -973,7 +982,7 @@ void Image::shrink_x2() { DVector<uint8_t> new_img; - ERR_FAIL_COND( format>=FORMAT_INDEXED ); + ERR_FAIL_COND( !_can_modify(format) ); int ps = get_format_pixel_size(format); new_img.resize((width/2)*(height/2)*ps); @@ -983,11 +992,12 @@ void Image::shrink_x2() { switch(format) { - case FORMAT_GRAYSCALE: - case FORMAT_INTENSITY: _generate_po2_mipmap<1>(r.ptr(), w.ptr(), width,height); break; - case FORMAT_GRAYSCALE_ALPHA: _generate_po2_mipmap<2>(r.ptr(), w.ptr(), width,height); break; - case FORMAT_RGB: _generate_po2_mipmap<3>(r.ptr(), w.ptr(), width,height); break; - case FORMAT_RGBA: _generate_po2_mipmap<4>(r.ptr(), w.ptr(), width,height); break; + case FORMAT_L8: + case FORMAT_R8: _generate_po2_mipmap<1>(r.ptr(), w.ptr(), width,height); break; + case FORMAT_LA8: _generate_po2_mipmap<2>(r.ptr(), w.ptr(), width,height); break; + case FORMAT_RG8: _generate_po2_mipmap<2>(r.ptr(), w.ptr(), width,height); break; + case FORMAT_RGB8: _generate_po2_mipmap<3>(r.ptr(), w.ptr(), width,height); break; + case FORMAT_RGBA8: _generate_po2_mipmap<4>(r.ptr(), w.ptr(), width,height); break; default: {} } } @@ -999,7 +1009,7 @@ void Image::shrink_x2() { } } -Error Image::generate_mipmaps(int p_mipmaps,bool p_keep_existing) { +Error Image::generate_mipmaps(bool p_keep_existing) { if (!_can_modify(format)) { ERR_EXPLAIN("Cannot generate mipmaps in indexed, compressed or custom image formats."); @@ -1007,11 +1017,13 @@ Error Image::generate_mipmaps(int p_mipmaps,bool p_keep_existing) { } + int mmcount = get_mipmap_count(); + int from_mm=1; if (p_keep_existing) { - from_mm=mipmaps+1; + from_mm=mmcount+1; } - int size = _get_dst_image_size(width,height,format,mipmaps,p_mipmaps); + int size = _get_dst_image_size(width,height,format,mmcount); data.resize(size); @@ -1023,7 +1035,7 @@ Error Image::generate_mipmaps(int p_mipmaps,bool p_keep_existing) { int prev_h=height; int prev_w=width; - for(int i=1;i<mipmaps;i++) { + for(int i=1;i<mmcount;i++) { int ofs,w,h; @@ -1033,11 +1045,12 @@ Error Image::generate_mipmaps(int p_mipmaps,bool p_keep_existing) { switch(format) { - case FORMAT_GRAYSCALE: - case FORMAT_INTENSITY: _generate_po2_mipmap<1>(&wp[prev_ofs], &wp[ofs], prev_w,prev_h); break; - case FORMAT_GRAYSCALE_ALPHA: _generate_po2_mipmap<2>(&wp[prev_ofs], &wp[ofs], prev_w,prev_h); break; - case FORMAT_RGB: _generate_po2_mipmap<3>(&wp[prev_ofs], &wp[ofs], prev_w,prev_h); break; - case FORMAT_RGBA: _generate_po2_mipmap<4>(&wp[prev_ofs], &wp[ofs], prev_w,prev_h); break; + case FORMAT_L8: + case FORMAT_R8: _generate_po2_mipmap<1>(&wp[prev_ofs], &wp[ofs], prev_w,prev_h); break; + case FORMAT_LA8: + case FORMAT_RG8: _generate_po2_mipmap<2>(&wp[prev_ofs], &wp[ofs], prev_w,prev_h); break; + case FORMAT_RGB8: _generate_po2_mipmap<3>(&wp[prev_ofs], &wp[ofs], prev_w,prev_h); break; + case FORMAT_RGBA8: _generate_po2_mipmap<4>(&wp[prev_ofs], &wp[ofs], prev_w,prev_h); break; default: {} } } @@ -1056,7 +1069,7 @@ Error Image::generate_mipmaps(int p_mipmaps,bool p_keep_existing) { int prev_h=height; int prev_w=width; - for(int i=1;i<mipmaps;i++) { + for(int i=1;i<mmcount;i++) { int ofs,w,h; @@ -1066,11 +1079,12 @@ Error Image::generate_mipmaps(int p_mipmaps,bool p_keep_existing) { switch(format) { - case FORMAT_GRAYSCALE: - case FORMAT_INTENSITY: _scale_bilinear<1>(&wp[prev_ofs], &wp[ofs], prev_w,prev_h,w,h); break; - case FORMAT_GRAYSCALE_ALPHA: _scale_bilinear<2>(&wp[prev_ofs], &wp[ofs], prev_w,prev_h,w,h); break; - case FORMAT_RGB: _scale_bilinear<3>(&wp[prev_ofs], &wp[ofs], prev_w,prev_h,w,h); break; - case FORMAT_RGBA: _scale_bilinear<4>(&wp[prev_ofs], &wp[ofs], prev_w,prev_h,w,h); break; + case FORMAT_L8: + case FORMAT_R8: _scale_bilinear<1>(&wp[prev_ofs], &wp[ofs], prev_w,prev_h,w,h); break; + case FORMAT_LA8: + case FORMAT_RG8: _scale_bilinear<2>(&wp[prev_ofs], &wp[ofs], prev_w,prev_h,w,h); break; + case FORMAT_RGB8:_scale_bilinear<3>(&wp[prev_ofs], &wp[ofs], prev_w,prev_h,w,h); break; + case FORMAT_RGBA8: _scale_bilinear<4>(&wp[prev_ofs], &wp[ofs], prev_w,prev_h,w,h); break; default: {} } } @@ -1083,85 +1097,25 @@ Error Image::generate_mipmaps(int p_mipmaps,bool p_keep_existing) { } - - return OK; } void Image::clear_mipmaps() { - if (mipmaps==0) + if (!mipmaps) return; - if (format==FORMAT_CUSTOM) { - ERR_EXPLAIN("Cannot clear mipmaps in indexed, compressed or custom image formats."); - ERR_FAIL(); - - } - if (empty()) return; int ofs,w,h; _get_mipmap_offset_and_size(1,ofs,w,h); - int palsize = get_format_pallete_size(format); - DVector<uint8_t> pallete; - ERR_FAIL_COND(ofs+palsize > data.size()); //bug? - if (palsize) { - - pallete.resize(palsize); - DVector<uint8_t>::Read r = data.read(); - DVector<uint8_t>::Write w = pallete.write(); - - copymem(&w[0],&r[data.size()-palsize],palsize); - } + data.resize(ofs); - data.resize(ofs+palsize); - - if (palsize) { - - DVector<uint8_t>::Read r = pallete.read(); - DVector<uint8_t>::Write w = data.write(); - - copymem(&w[ofs],&r[0],palsize); - } - - mipmaps=0; + mipmaps=false; } -void Image::make_normalmap(float p_height_scale) { - - if (!_can_modify(format)) { - ERR_EXPLAIN("Cannot crop in indexed, compressed or custom image formats."); - ERR_FAIL(); - } - - ERR_FAIL_COND( empty() ); - - Image normalmap(width,height,0, FORMAT_RGB); - /* - for (int y=0;y<height;y++) { - for (int x=0;x<width;x++) { - - float center=get_pixel(x,y).gray()/255.0; - float up=(y>0)?get_pixel(x,y-1).gray()/255.0:center; - float down=(y<(height-1))?get_pixel(x,y+1).gray()/255.0:center; - float left=(x>0)?get_pixel(x-1,y).gray()/255.0:center; - float right=(x<(width-1))?get_pixel(x+1,y).gray()/255.0:center; - - - // uhm, how do i do this? .... - - Color result( (uint8_t)((normal.x+1.0)*127.0), (uint8_t)((normal.y+1.0)*127.0), (uint8_t)((normal.z+1.0)*127.0) ); - - normalmap.put_pixel( x, y, result ); - } - - } - */ - *this=normalmap; -} bool Image::empty() const { @@ -1186,32 +1140,30 @@ void Image::create(int p_width, int p_height, bool p_use_mipmaps,Format p_format width=p_width; height=p_height; - mipmaps=mm; + mipmaps=p_use_mipmaps; format=p_format; } -void Image::create(int p_width, int p_height, int p_mipmaps, Format p_format, const DVector<uint8_t>& p_data) { +void Image::create(int p_width, int p_height, bool p_use_mipmaps, Format p_format, const DVector<uint8_t>& p_data) { ERR_FAIL_INDEX(p_width-1,MAX_WIDTH); ERR_FAIL_INDEX(p_height-1,MAX_HEIGHT); - if (p_format < FORMAT_CUSTOM) { - int mm; - int size = _get_dst_image_size(p_width,p_height,p_format,mm,p_mipmaps); + int mm; + int size = _get_dst_image_size(p_width,p_height,p_format,mm,p_use_mipmaps); - if (size!=p_data.size()) { - ERR_EXPLAIN("Expected data size of "+itos(size)+" in Image::create()"); - ERR_FAIL_COND(p_data.size()!=size); - } - }; + if (size!=p_data.size()) { + ERR_EXPLAIN("Expected data size of "+itos(size)+" in Image::create()"); + ERR_FAIL_COND(p_data.size()!=size); + } height=p_height; width=p_width; format=p_format; data=p_data; - mipmaps=p_mipmaps; + mipmaps=p_use_mipmaps; } @@ -1220,7 +1172,7 @@ void Image::create( const char ** p_xpm ) { int size_width,size_height; int pixelchars=0; - mipmaps=0; + mipmaps=false; bool has_alpha=false; enum Status { @@ -1235,6 +1187,8 @@ void Image::create( const char ** p_xpm ) { HashMap<String,Color> colormap; int colormap_size; + uint32_t pixel_size; + DVector<uint8_t>::Write w; while (status!=DONE) { @@ -1327,7 +1281,9 @@ void Image::create( const char ** p_xpm ) { if (line==colormap_size) { status=READING_PIXELS; - create(size_width,size_height,0,has_alpha?FORMAT_RGBA:FORMAT_RGB); + create(size_width,size_height,0,has_alpha?FORMAT_RGBA8:FORMAT_RGB8); + w=data.write(); + pixel_size=has_alpha?4:3; } } break; case READING_PIXELS: { @@ -1341,7 +1297,11 @@ void Image::create( const char ** p_xpm ) { Color *colorptr = colormap.getptr(pixelstr); ERR_FAIL_COND(!colorptr); - put_pixel(x,y,*colorptr); + uint8_t pixel[4]; + for(uint32_t i=0;i<pixel_size;i++) { + pixel[i]=CLAMP((*colorptr)[i]*255,0,255); + } + _put_pixelb(x,y,pixel_size,w.ptr(),pixel); } @@ -1382,9 +1342,8 @@ void Image::create( const char ** p_xpm ) { bool Image::is_invisible() const { - if (format==FORMAT_GRAYSCALE || - format==FORMAT_RGB || - format==FORMAT_INDEXED) + if (format==FORMAT_L8 || + format==FORMAT_RGB8 || format==FORMAT_RG8) return false; int len = data.size(); @@ -1392,8 +1351,6 @@ bool Image::is_invisible() const { if (len==0) return true; - if (format >= FORMAT_YUV_422 && format <= FORMAT_YUV_444) - return false; int w,h; _get_mipmap_offset_and_size(1,len,w,h); @@ -1404,13 +1361,8 @@ bool Image::is_invisible() const { bool detected=false; switch(format) { - case FORMAT_INTENSITY: { - for(int i=0;i<len;i++) { - DETECT_NON_ALPHA(data_ptr[i]); - } - } break; - case FORMAT_GRAYSCALE_ALPHA: { + case FORMAT_LA8: { for(int i=0;i<(len>>1);i++) { @@ -1418,25 +1370,18 @@ bool Image::is_invisible() const { } } break; - case FORMAT_RGBA: { + case FORMAT_RGBA8: { for(int i=0;i<(len>>2);i++) { DETECT_NON_ALPHA(data_ptr[(i<<2)+3]) } } break; - case FORMAT_INDEXED: { - return false; - } break; - case FORMAT_INDEXED_ALPHA: { - - return false; - } break; - case FORMAT_PVRTC2_ALPHA: - case FORMAT_PVRTC4_ALPHA: - case FORMAT_BC2: - case FORMAT_BC3: { + case FORMAT_PVRTC2A: + case FORMAT_PVRTC4A: + case FORMAT_DXT3: + case FORMAT_DXT5: { detected=true; } break; default: {} @@ -1447,19 +1392,12 @@ bool Image::is_invisible() const { Image::AlphaMode Image::detect_alpha() const { - if (format==FORMAT_GRAYSCALE || - format==FORMAT_RGB || - format==FORMAT_INDEXED) - return ALPHA_NONE; int len = data.size(); if (len==0) return ALPHA_NONE; - if (format >= FORMAT_YUV_422 && format <= FORMAT_YUV_444) - return ALPHA_NONE; - int w,h; _get_mipmap_offset_and_size(1,len,w,h); @@ -1470,13 +1408,8 @@ Image::AlphaMode Image::detect_alpha() const { bool detected=false; switch(format) { - case FORMAT_INTENSITY: { - for(int i=0;i<len;i++) { - DETECT_ALPHA(data_ptr[i]); - } - } break; - case FORMAT_GRAYSCALE_ALPHA: { + case FORMAT_LA8: { for(int i=0;i<(len>>1);i++) { @@ -1484,25 +1417,17 @@ Image::AlphaMode Image::detect_alpha() const { } } break; - case FORMAT_RGBA: { + case FORMAT_RGBA8: { for(int i=0;i<(len>>2);i++) { DETECT_ALPHA(data_ptr[(i<<2)+3]) } - } break; - case FORMAT_INDEXED: { - - return ALPHA_NONE; - } break; - case FORMAT_INDEXED_ALPHA: { - - return ALPHA_BLEND; - } break; - case FORMAT_PVRTC2_ALPHA: - case FORMAT_PVRTC4_ALPHA: - case FORMAT_BC2: - case FORMAT_BC3: { + } break; + case FORMAT_PVRTC2A: + case FORMAT_PVRTC4A: + case FORMAT_DXT3: + case FORMAT_DXT5: { detected=true; } break; default: {} @@ -1528,7 +1453,7 @@ Error Image::save_png(const String& p_path) { return ERR_UNAVAILABLE; return save_png_func(p_path, *this); -}; +} bool Image::operator==(const Image& p_image) const { @@ -1541,84 +1466,7 @@ bool Image::operator==(const Image& p_image) const { } -int Image::get_format_pixel_size(Format p_format) { - - switch(p_format) { - case FORMAT_GRAYSCALE: { - - return 1; - } break; - case FORMAT_INTENSITY: { - - return 1; - } break; - case FORMAT_GRAYSCALE_ALPHA: { - - return 2; - } break; - case FORMAT_RGB: { - - return 3; - } break; - case FORMAT_RGBA: { - - return 4; - } break; - case FORMAT_INDEXED: { - return 1; - } break; - case FORMAT_INDEXED_ALPHA: { - - return 1; - } break; - case FORMAT_BC1: - case FORMAT_BC2: - case FORMAT_BC3: - case FORMAT_BC4: - case FORMAT_BC5: { - - return 1; - } break; - case FORMAT_PVRTC2: - case FORMAT_PVRTC2_ALPHA: { - - return 1; - } break; - case FORMAT_PVRTC4: - case FORMAT_PVRTC4_ALPHA: { - - return 1; - } break; - case FORMAT_ATC: - case FORMAT_ATC_ALPHA_EXPLICIT: - case FORMAT_ATC_ALPHA_INTERPOLATED: { - - return 1; - } break; - case FORMAT_ETC: { - - return 1; - } break; - case FORMAT_YUV_422: { - return 2; - }; - case FORMAT_YUV_444: { - return 3; - } break; - case FORMAT_CUSTOM: { - - ERR_EXPLAIN("pixel size requested for custom image format, and it's unknown obviously"); - ERR_FAIL_V(1); - } break; - default:{ - ERR_EXPLAIN("Cannot obtain pixel size from this format"); - ERR_FAIL_V(1); - - } - } - return 0; -} int Image::get_image_data_size(int p_width, int p_height, Format p_format,int p_mipmaps) { @@ -1635,105 +1483,12 @@ int Image::get_image_required_mipmaps(int p_width, int p_height, Format p_format } -void Image::_get_format_min_data_size(Format p_format,int &r_w, int &r_h) { - - - switch(p_format) { - case FORMAT_BC1: - case FORMAT_BC2: - case FORMAT_BC3: - case FORMAT_BC4: - case FORMAT_BC5: { - r_w=4; - r_h=4; - } break; - case FORMAT_PVRTC2: - case FORMAT_PVRTC2_ALPHA: { - - r_w=16; - r_h=8; - } break; - case FORMAT_PVRTC4_ALPHA: - case FORMAT_PVRTC4: { - - r_w=8; - r_h=8; - } break; - case FORMAT_ATC: - case FORMAT_ATC_ALPHA_EXPLICIT: - case FORMAT_ATC_ALPHA_INTERPOLATED: { - - r_w=8; - r_h=8; - - } break; - - case FORMAT_ETC: { - - r_w=4; - r_h=4; - } break; - default: { - r_w=1; - r_h=1; - } break; - } - -} - - -int Image::get_format_pixel_rshift(Format p_format) { - - if (p_format==FORMAT_BC1 || p_format==FORMAT_BC4 || p_format==FORMAT_ATC || p_format==FORMAT_PVRTC4 || p_format==FORMAT_PVRTC4_ALPHA || p_format==FORMAT_ETC) - return 1; - else if (p_format==FORMAT_PVRTC2 || p_format==FORMAT_PVRTC2_ALPHA) - return 2; - else - return 0; -} - -int Image::get_format_pallete_size(Format p_format) { - - switch(p_format) { - case FORMAT_GRAYSCALE: { - - return 0; - } break; - case FORMAT_INTENSITY: { - - return 0; - } break; - case FORMAT_GRAYSCALE_ALPHA: { - - return 0; - } break; - case FORMAT_RGB: { - - return 0; - } break; - case FORMAT_RGBA: { - - return 0; - } break; - case FORMAT_INDEXED: { - - return 3*256; - } break; - case FORMAT_INDEXED_ALPHA: { - - return 4*256; - } break; - default:{} - } - return 0; -} Error Image::_decompress_bc() { - print_line("decompressing bc"); int wd=width,ht=height; if (wd%4!=0) { @@ -1745,7 +1500,7 @@ Error Image::_decompress_bc() { int mm; - int size = _get_dst_image_size(wd,ht,FORMAT_RGBA,mm,mipmaps); + int size = _get_dst_image_size(wd,ht,FORMAT_RGBA8,mm); DVector<uint8_t> newdata; newdata.resize(size); @@ -1762,7 +1517,7 @@ Error Image::_decompress_bc() { switch(format) { - case FORMAT_BC1: { + case FORMAT_DXT1: { int len = (wd*ht)/16; uint8_t* dst=&w[wofs]; @@ -1788,8 +1543,8 @@ Error Image::_decompress_bc() { col_b|=src[2]; uint8_t table[4][4]={ - { (col_a>>11)<<3, ((col_a>>5)&0x3f)<<2, ((col_a)&0x1f)<<3, 255 }, - { (col_b>>11)<<3, ((col_b>>5)&0x3f)<<2, ((col_b)&0x1f)<<3, 255 }, + { uint8_t((col_a>>11)<<3), uint8_t(((col_a>>5)&0x3f)<<2),uint8_t(((col_a)&0x1f)<<3), 255 }, + { uint8_t((col_b>>11)<<3), uint8_t(((col_b>>5)&0x3f)<<2),uint8_t(((col_b)&0x1f)<<3), 255 }, {0,0,0,255}, {0,0,0,255} }; @@ -1841,7 +1596,7 @@ Error Image::_decompress_bc() { ht/=2; } break; - case FORMAT_BC2: { + case FORMAT_DXT3: { int len = (wd*ht)/16; uint8_t* dst=&w[wofs]; @@ -1885,8 +1640,9 @@ Error Image::_decompress_bc() { col_b|=src[8+2]; uint8_t table[4][4]={ - { (col_a>>11)<<3, ((col_a>>5)&0x3f)<<2, ((col_a)&0x1f)<<3, 255 }, - { (col_b>>11)<<3, ((col_b>>5)&0x3f)<<2, ((col_b)&0x1f)<<3, 255 }, + { uint8_t((col_a>>11)<<3), uint8_t(((col_a>>5)&0x3f)<<2),uint8_t(((col_a)&0x1f)<<3), 255 }, + { uint8_t((col_b>>11)<<3), uint8_t(((col_b>>5)&0x3f)<<2),uint8_t(((col_b)&0x1f)<<3), 255 }, + {0,0,0,255}, {0,0,0,255} }; @@ -1933,7 +1689,7 @@ Error Image::_decompress_bc() { ht/=2; } break; - case FORMAT_BC3: { + case FORMAT_DXT5: { int len = (wd*ht)/16; uint8_t* dst=&w[wofs]; @@ -2001,9 +1757,10 @@ Error Image::_decompress_bc() { col_b<<=8; col_b|=src[8+2]; - uint8_t table[4][4]={ - { (col_a>>11)<<3, ((col_a>>5)&0x3f)<<2, ((col_a)&0x1f)<<3, 255 }, - { (col_b>>11)<<3, ((col_b>>5)&0x3f)<<2, ((col_b)&0x1f)<<3, 255 }, + uint8_t table[4][4]={ + { uint8_t((col_a>>11)<<3), uint8_t(((col_a>>5)&0x3f)<<2),uint8_t(((col_a)&0x1f)<<3), 255 }, + { uint8_t((col_b>>11)<<3), uint8_t(((col_b>>5)&0x3f)<<2),uint8_t(((col_b)&0x1f)<<3), 255 }, + {0,0,0,255}, {0,0,0,255} }; @@ -2061,18 +1818,19 @@ Error Image::_decompress_bc() { r=DVector<uint8_t>::Read(); data=newdata; - format=FORMAT_RGBA; + format=FORMAT_RGBA8; if (wd!=width || ht!=height) { - //todo, crop - width=wd; - height=ht; + + SWAP(width,wd); + SWAP(height,ht); + crop(wd,ht); } return OK; } bool Image::is_compressed() const { - return format>=FORMAT_BC1; + return format>=FORMAT_RGB565; } @@ -2085,12 +1843,14 @@ Image Image::decompressed() const { Error Image::decompress() { - if (format>=FORMAT_BC1 && format<=FORMAT_BC5 ) + if (format>=FORMAT_DXT1 && format<=FORMAT_ATI2 ) _decompress_bc();//_image_decompress_bc(this); - else if (format>=FORMAT_PVRTC2 && format<=FORMAT_PVRTC4_ALPHA && _image_decompress_pvrtc) + else if (format>=FORMAT_PVRTC2 && format<=FORMAT_PVRTC4A&& _image_decompress_pvrtc) _image_decompress_pvrtc(this); else if (format==FORMAT_ETC && _image_decompress_etc) _image_decompress_etc(this); + else if (format>=FORMAT_ETC2_R11 && format<=FORMAT_ETC2_RGB8A1 && _image_decompress_etc) + _image_decompress_etc2(this); else return ERR_UNAVAILABLE; return OK; @@ -2101,7 +1861,12 @@ Error Image::compress(CompressMode p_mode) { switch(p_mode) { - case COMPRESS_BC: { + case COMPRESS_16BIT: { + + //ERR_FAIL_COND_V(!_image_compress_bc_func, ERR_UNAVAILABLE); + //_image_compress_bc_func(this); + } break; + case COMPRESS_S3TC: { ERR_FAIL_COND_V(!_image_compress_bc_func, ERR_UNAVAILABLE); _image_compress_bc_func(this); @@ -2121,6 +1886,11 @@ Error Image::compress(CompressMode p_mode) { ERR_FAIL_COND_V(!_image_compress_etc_func, ERR_UNAVAILABLE); _image_compress_etc_func(this); } break; + case COMPRESS_ETC2: { + + ERR_FAIL_COND_V(!_image_compress_etc_func, ERR_UNAVAILABLE); + _image_compress_etc_func(this); + } break; } @@ -2133,14 +1903,14 @@ Image Image::compressed(int p_mode) { ret.compress((Image::CompressMode)p_mode); return ret; -}; +} Image::Image(const char **p_xpm) { width=0; height=0; - mipmaps=0; - format=FORMAT_GRAYSCALE; + mipmaps=false; + format=FORMAT_L8; create(p_xpm); } @@ -2150,37 +1920,28 @@ Image::Image(int p_width, int p_height,bool p_use_mipmaps, Format p_format) { width=0; height=0; - mipmaps=0; - format=FORMAT_GRAYSCALE; + mipmaps=p_use_mipmaps; + format=FORMAT_L8; create(p_width,p_height,p_use_mipmaps,p_format); } -Image::Image(int p_width, int p_height, int p_mipmaps, Format p_format, const DVector<uint8_t>& p_data) { +Image::Image(int p_width, int p_height, bool p_mipmaps, Format p_format, const DVector<uint8_t>& p_data) { width=0; height=0; - mipmaps=0; - format=FORMAT_GRAYSCALE; + mipmaps=p_mipmaps; + format=FORMAT_L8; create(p_width,p_height,p_mipmaps,p_format,p_data); } -Image Image::brushed(const Image& p_src, const Image& p_brush, const Point2& p_dest) const { - - Image img = *this; - img.brush_transfer(p_src,p_brush,p_dest); - return img; -} - Rect2 Image::get_used_rect() const { - if (format==FORMAT_GRAYSCALE || - format==FORMAT_RGB || - format==FORMAT_INDEXED || format>FORMAT_INDEXED_ALPHA) + if (format!=FORMAT_LA8 && format!=FORMAT_RGBA8) return Rect2(Point2(),Size2(width,height)); int len = data.size(); @@ -2188,16 +1949,18 @@ Rect2 Image::get_used_rect() const { if (len==0) return Rect2(); - int data_size = len; + //int data_size = len; DVector<uint8_t>::Read r = data.read(); const unsigned char *rptr=r.ptr(); + int ps = format==FORMAT_LA8?2:4; int minx=0xFFFFFF,miny=0xFFFFFFF; int maxx=-1,maxy=-1; - for(int i=0;i<width;i++) { - for(int j=0;j<height;j++) { + for(int j=0;j<height;j++) { + for(int i=0;i<width;i++) { + - bool opaque = _get_pixel(i,j,rptr,data_size).a>2; + bool opaque = rptr[(j*width+i)*ps+(ps-1)]>2; if (!opaque) continue; if (i>maxx) @@ -2225,101 +1988,47 @@ Image Image::get_rect(const Rect2& p_area) const { img.blit_rect(*this, p_area, Point2(0, 0)); return img; -}; - -void Image::brush_transfer(const Image& p_src, const Image& p_brush, const Point2& p_dest) { - - - ERR_FAIL_COND( width != p_src.width || height !=p_src.height); - - int dst_data_size = data.size(); - DVector<uint8_t>::Write wp = data.write(); - unsigned char *dst_data_ptr=wp.ptr(); - - - int src_data_size = p_src.data.size(); - DVector<uint8_t>::Read rp = p_src.data.read(); - const unsigned char *src_data_ptr=rp.ptr(); - - int brush_data_size = p_brush.data.size(); - DVector<uint8_t>::Read bp = p_brush.data.read(); - const unsigned char *src_brush_ptr=bp.ptr(); - - int bw = p_brush.get_width(); - int bh = p_brush.get_height(); - int dx=p_dest.x; - int dy=p_dest.y; - - for(int i=dy;i<dy+bh;i++) { - - if (i<0 || i >= height) - continue; - for(int j=dx;j<dx+bw;j++) { - - if (j<0 || j>=width) - continue; - - BColor src = p_src._get_pixel(j,i,src_data_ptr,src_data_size); - BColor dst = _get_pixel(j,i,dst_data_ptr,dst_data_size); - BColor brush = p_brush._get_pixel(j-dx,i-dy,src_brush_ptr,brush_data_size); - uint32_t mult = brush.r; - dst.r = dst.r + (((int32_t(src.r)-int32_t(dst.r))*mult)>>8); - dst.g = dst.g + (((int32_t(src.g)-int32_t(dst.g))*mult)>>8); - dst.b = dst.b + (((int32_t(src.b)-int32_t(dst.b))*mult)>>8); - dst.a = dst.a + (((int32_t(src.a)-int32_t(dst.a))*mult)>>8); - _put_pixel(j,i,dst,dst_data_ptr); - } - } } - void Image::blit_rect(const Image& p_src, const Rect2& p_src_rect,const Point2& p_dest) { int dsize=data.size(); int srcdsize=p_src.data.size(); ERR_FAIL_COND( dsize==0 ); ERR_FAIL_COND( srcdsize==0 ); + ERR_FAIL_COND( format!=p_src.format ); + Rect2i local_src_rect = Rect2i(0,0,width,height).clip( Rect2i(p_dest+p_src_rect.pos,p_src_rect.size) ); - Rect2 rrect = Rect2(0,0,p_src.width,p_src.height).clip(p_src_rect); + if (local_src_rect.size.x<=0 || local_src_rect.size.y<=0) + return; + Rect2i src_rect( p_src_rect.pos + ( local_src_rect.pos - p_dest), local_src_rect.size ); DVector<uint8_t>::Write wp = data.write(); - unsigned char *dst_data_ptr=wp.ptr(); + uint8_t *dst_data_ptr=wp.ptr(); DVector<uint8_t>::Read rp = p_src.data.read(); - const unsigned char *src_data_ptr=rp.ptr(); - - if ((format==FORMAT_INDEXED || format == FORMAT_INDEXED_ALPHA) && (p_src.format==FORMAT_INDEXED || p_src.format == FORMAT_INDEXED_ALPHA)) { - - Point2i desti(p_dest.x, p_dest.y); - Point2i srci(rrect.pos.x, rrect.pos.y); + const uint8_t *src_data_ptr=rp.ptr(); - for(int i=0;i<rrect.size.y;i++) { + int pixel_size=get_format_pixel_size(format); - if (i<0 || i >= height) - continue; - for(int j=0;j<rrect.size.x;j++) { - - if (j<0 || j>=width) - continue; + for(int i=0;i<src_rect.size.y;i++) { - dst_data_ptr[width * (desti.y + i) + desti.x + j] = src_data_ptr[p_src.width * (srci.y+i) + srci.x+j]; - } - } - } else { + for(int j=0;j<src_rect.size.x;j++) { - for(int i=0;i<rrect.size.y;i++) { + int src_x = src_rect.pos.x+j; + int src_y = src_rect.pos.y+i; - if (i<0 || i >= height) - continue; - for(int j=0;j<rrect.size.x;j++) { + int dst_x = local_src_rect.pos.x+j; + int dst_y = local_src_rect.pos.y+i; - if (j<0 || j>=width) - continue; + const uint8_t *src = &src_data_ptr[ (src_y*p_src.width+src_x)*pixel_size]; + uint8_t *dst = &dst_data_ptr[ (dst_y*width+dst_x)*pixel_size]; - _put_pixel(p_dest.x+j,p_dest.y+i,p_src._get_pixel(rrect.pos.x+j,rrect.pos.y+i,src_data_ptr,srcdsize),dst_data_ptr); + for(int k=0;k<pixel_size;k++) { + dst[k]=src[k]; } } } @@ -2334,9 +2043,11 @@ void (*Image::_image_compress_bc_func)(Image *)=NULL; void (*Image::_image_compress_pvrtc2_func)(Image *)=NULL; void (*Image::_image_compress_pvrtc4_func)(Image *)=NULL; void (*Image::_image_compress_etc_func)(Image *)=NULL; +void (*Image::_image_compress_etc2_func)(Image *)=NULL; void (*Image::_image_decompress_pvrtc)(Image *)=NULL; void (*Image::_image_decompress_bc)(Image *)=NULL; void (*Image::_image_decompress_etc)(Image *)=NULL; +void (*Image::_image_decompress_etc2)(Image *)=NULL; DVector<uint8_t> (*Image::lossy_packer)(const Image& ,float )=NULL; Image (*Image::lossy_unpacker)(const DVector<uint8_t>& )=NULL; @@ -2352,7 +2063,7 @@ void Image::set_compress_bc_func(void (*p_compress_func)(Image *)) { void Image::normalmap_to_xy() { - convert(Image::FORMAT_RGBA); + convert(Image::FORMAT_RGBA8); { int len = data.size()/4; @@ -2367,7 +2078,7 @@ void Image::normalmap_to_xy() { } } - convert(Image::FORMAT_GRAYSCALE_ALPHA); + convert(Image::FORMAT_LA8); } void Image::srgb_to_linear() { @@ -2378,9 +2089,9 @@ void Image::srgb_to_linear() { static const uint8_t srgb2lin[256]={0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 22, 22, 23, 23, 24, 24, 25, 26, 26, 27, 27, 28, 29, 29, 30, 31, 31, 32, 33, 33, 34, 35, 36, 36, 37, 38, 38, 39, 40, 41, 42, 42, 43, 44, 45, 46, 47, 47, 48, 49, 50, 51, 52, 53, 54, 55, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 70, 71, 72, 73, 74, 75, 76, 77, 78, 80, 81, 82, 83, 84, 85, 87, 88, 89, 90, 92, 93, 94, 95, 97, 98, 99, 101, 102, 103, 105, 106, 107, 109, 110, 112, 113, 114, 116, 117, 119, 120, 122, 123, 125, 126, 128, 129, 131, 132, 134, 135, 137, 139, 140, 142, 144, 145, 147, 148, 150, 152, 153, 155, 157, 159, 160, 162, 164, 166, 167, 169, 171, 173, 175, 176, 178, 180, 182, 184, 186, 188, 190, 192, 193, 195, 197, 199, 201, 203, 205, 207, 209, 211, 213, 215, 218, 220, 222, 224, 226, 228, 230, 232, 235, 237, 239, 241, 243, 245, 248, 250, 252}; - ERR_FAIL_COND( format!=FORMAT_RGB && format!=FORMAT_RGBA ); + ERR_FAIL_COND( format!=FORMAT_RGB8 && format!=FORMAT_RGBA8 ); - if (format==FORMAT_RGBA) { + if (format==FORMAT_RGBA8) { int len = data.size()/4; DVector<uint8_t>::Write wp = data.write(); @@ -2393,7 +2104,7 @@ void Image::srgb_to_linear() { data_ptr[(i<<2)+2]=srgb2lin[ data_ptr[(i<<2)+2] ]; } - } else if (format==FORMAT_RGB) { + } else if (format==FORMAT_RGB8) { int len = data.size()/3; DVector<uint8_t>::Write wp = data.write(); @@ -2414,7 +2125,7 @@ void Image::premultiply_alpha() { if (data.size()==0) return; - if (format!=FORMAT_RGBA) + if (format!=FORMAT_RGBA8) return; //not needed DVector<uint8_t>::Write wp = data.write(); @@ -2424,11 +2135,11 @@ void Image::premultiply_alpha() { for(int i=0;i<height;i++) { for(int j=0;j<width;j++) { - BColor bc = _get_pixel(j,i,data_ptr,0); - bc.r=(int(bc.r)*int(bc.a))>>8; - bc.g=(int(bc.g)*int(bc.a))>>8; - bc.b=(int(bc.b)*int(bc.a))>>8; - _put_pixel(j,i,bc,data_ptr); + uint8_t *ptr = &data_ptr[(i*width+j)*4]; + + ptr[0]=(uint16_t(ptr[0])*uint16_t(ptr[3]))>>8; + ptr[1]=(uint16_t(ptr[1])*uint16_t(ptr[3]))>>8; + ptr[2]=(uint16_t(ptr[2])*uint16_t(ptr[3]))>>8; } } } @@ -2438,12 +2149,12 @@ void Image::fix_alpha_edges() { if (data.size()==0) return; - if (format!=FORMAT_RGBA) + if (format!=FORMAT_RGBA8) return; //not needed DVector<uint8_t> dcopy = data; DVector<uint8_t>::Read rp = data.read(); - const uint8_t *rptr=rp.ptr(); + const uint8_t *srcptr=rp.ptr(); DVector<uint8_t>::Write wp = data.write(); unsigned char *data_ptr=wp.ptr(); @@ -2455,13 +2166,16 @@ void Image::fix_alpha_edges() { for(int i=0;i<height;i++) { for(int j=0;j<width;j++) { - BColor bc = _get_pixel(j,i,rptr,0); - if (bc.a>=alpha_treshold) + const uint8_t *rptr = &srcptr[(i*width+j)*4]; + uint8_t *wptr = &data_ptr[(i*width+j)*4]; + + if (rptr[3]>=alpha_treshold) continue; int closest_dist=max_dist; - BColor closest_color; - closest_color.a=bc.a; + uint8_t closest_color[3]; + + int from_x = MAX(0,j-max_radius); int to_x = MIN(width-1,j+max_radius); int from_y = MAX(0,i-max_radius); @@ -2476,22 +2190,25 @@ void Image::fix_alpha_edges() { if (dist>=closest_dist) continue; - const uint8_t * rp = &rptr[(k*width+l)<<2]; + const uint8_t * rp = &srcptr[(k*width+l)<<2]; if (rp[3]<alpha_treshold) continue; - closest_dist=dist; - closest_color.r=rp[0]; - closest_color.g=rp[1]; - closest_color.b=rp[2]; + closest_color[0]=rp[0]; + closest_color[1]=rp[1]; + closest_color[2]=rp[2]; } } - if (closest_dist!=max_dist) - _put_pixel(j,i,closest_color,data_ptr); + if (closest_dist!=max_dist) { + + wptr[0]=closest_color[0]; + wptr[1]=closest_color[1]; + wptr[2]=closest_color[2]; + } } } @@ -2508,8 +2225,8 @@ Image::Image(const uint8_t* p_mem_png_jpg, int p_len) { width=0; height=0; - mipmaps=0; - format=FORMAT_GRAYSCALE; + mipmaps=false; + format=FORMAT_L8; if (_png_mem_loader_func) { *this = _png_mem_loader_func(p_mem_png_jpg,p_len); @@ -2525,8 +2242,8 @@ Image::Image() { width=0; height=0; - mipmaps=0; - format = FORMAT_GRAYSCALE; + mipmaps=false; + format = FORMAT_L8; } Image::~Image() { diff --git a/core/image.h b/core/image.h index d0f18841ad..2c585d74d9 100644 --- a/core/image.h +++ b/core/image.h @@ -55,35 +55,44 @@ public: static SavePNGFunc save_png_func; enum Format { - FORMAT_GRAYSCALE, ///< one byte per pixel, 0-255 - FORMAT_INTENSITY, ///< one byte per pixel, 0-255 - FORMAT_GRAYSCALE_ALPHA, ///< two bytes per pixel, 0-255. alpha 0-255 - FORMAT_RGB, ///< one byte R, one byte G, one byte B - FORMAT_RGBA, ///< one byte R, one byte G, one byte B, one byte A - FORMAT_INDEXED, ///< index byte 0-256, and after image end, 256*3 bytes of palette - FORMAT_INDEXED_ALPHA, ///< index byte 0-256, and after image end, 256*4 bytes of palette (alpha) - FORMAT_YUV_422, - FORMAT_YUV_444, - FORMAT_BC1, // DXT1 - FORMAT_BC2, // DXT3 - FORMAT_BC3, // DXT5 - FORMAT_BC4, // ATI1 - FORMAT_BC5, // ATI2 - FORMAT_PVRTC2, - FORMAT_PVRTC2_ALPHA, - FORMAT_PVRTC4, - FORMAT_PVRTC4_ALPHA, - FORMAT_ETC, // regular ETC, no transparency - FORMAT_ATC, - FORMAT_ATC_ALPHA_EXPLICIT, - FORMAT_ATC_ALPHA_INTERPOLATED, - /*FORMAT_ETC2_R, for the future.. - FORMAT_ETC2_RG, - FORMAT_ETC2_RGB, - FORMAT_ETC2_RGBA1, - FORMAT_ETC2_RGBA,*/ - FORMAT_CUSTOM, + FORMAT_L8, //luminance + FORMAT_LA8, //luminance-alpha + FORMAT_R8, + FORMAT_RG8, + FORMAT_RGB8, + FORMAT_RGBA8, + FORMAT_RGB565, //16 bit + FORMAT_RGBA4444, + FORMAT_RGBA5551, + FORMAT_RF, //float + FORMAT_RGF, + FORMAT_RGBF, + FORMAT_RGBAF, + FORMAT_RH, //half float + FORMAT_RGH, + FORMAT_RGBH, + FORMAT_RGBAH, + FORMAT_DXT1, //s3tc bc1 + FORMAT_DXT3, //bc2 + FORMAT_DXT5, //bc3 + FORMAT_ATI1, //bc4 + FORMAT_ATI2, //bc5 + FORMAT_BPTC_RGBA, //btpc bc6h + FORMAT_BPTC_RGBF, //float / + FORMAT_BPTC_RGBFU, //unsigned float + FORMAT_PVRTC2, //pvrtc + FORMAT_PVRTC2A, + FORMAT_PVRTC4, + FORMAT_PVRTC4A, + FORMAT_ETC, //etc1 + FORMAT_ETC2_R11, //etc2 + FORMAT_ETC2_R11S, //signed, NOT srgb. + FORMAT_ETC2_RG11, + FORMAT_ETC2_RG11S, + FORMAT_ETC2_RGB8, + FORMAT_ETC2_RGBA8, + FORMAT_ETC2_RGB8A1, FORMAT_MAX }; @@ -96,15 +105,21 @@ public: /* INTERPOLATE GAUSS */ }; + //some functions provided by something else + static Image (*_png_mem_loader_func)(const uint8_t* p_png,int p_size); static Image (*_jpg_mem_loader_func)(const uint8_t* p_png,int p_size); + static void (*_image_compress_bc_func)(Image *); static void (*_image_compress_pvrtc2_func)(Image *); static void (*_image_compress_pvrtc4_func)(Image *); static void (*_image_compress_etc_func)(Image *); + static void (*_image_compress_etc2_func)(Image *); + static void (*_image_decompress_pvrtc)(Image *); static void (*_image_decompress_bc)(Image *); static void (*_image_decompress_etc)(Image *); + static void (*_image_decompress_etc2)(Image *); Error _decompress_bc(); @@ -114,92 +129,19 @@ public: static Image (*lossless_unpacker)(const DVector<uint8_t>& p_buffer); private: - //internal byte based color - struct BColor { - union { - uint8_t col[4]; - struct { - uint8_t r,g,b,a; - }; - }; - - bool operator==(const BColor& p_color) const { for(int i=0;i<4;i++) {if (col[i]!=p_color.col[i]) return false; } return true; } - _FORCE_INLINE_ uint8_t gray() const { return (uint16_t(col[0])+uint16_t(col[1])+uint16_t(col[2]))/3; } - _FORCE_INLINE_ BColor() {} - BColor(uint8_t p_r,uint8_t p_g,uint8_t p_b,uint8_t p_a=255) { col[0]=p_r; col[1]=p_g; col[2]=p_b; col[3]=p_a; } - }; - - //median cut classes - - struct BColorPos { - - uint32_t index; - BColor color; - struct SortR { - - bool operator()(const BColorPos& ca, const BColorPos& cb) const { return ca.color.r < cb.color.r; } - }; - - struct SortG { - - bool operator()(const BColorPos& ca, const BColorPos& cb) const { return ca.color.g < cb.color.g; } - }; - - struct SortB { - - bool operator()(const BColorPos& ca, const BColorPos& cb) const { return ca.color.b < cb.color.b; } - }; - - struct SortA { - - bool operator()(const BColorPos& ca, const BColorPos& cb) const { return ca.color.a < cb.color.a; } - }; - }; - - struct SPTree { - - bool leaf; - uint8_t split_plane; - uint8_t split_value; - union { - int left; - int color; - }; - int right; - SPTree() { leaf=true; left=-1; right=-1;} - }; - - struct MCBlock { - - BColorPos min_color,max_color; - BColorPos *colors; - int sp_idx; - int color_count; - int get_longest_axis_index() const; - int get_longest_axis_length() const; - bool operator<(const MCBlock& p_block) const; - void shrink(); - MCBlock(); - MCBlock(BColorPos *p_colors,int p_color_count); - }; - Format format; DVector<uint8_t> data; - int width,height,mipmaps; - - + int width,height; + bool mipmaps; - _FORCE_INLINE_ BColor _get_pixel(int p_x,int p_y,const unsigned char *p_data,int p_data_size) const; - _FORCE_INLINE_ BColor _get_pixelw(int p_x,int p_y,int p_width,const unsigned char *p_data,int p_data_size) const; - _FORCE_INLINE_ void _put_pixelw(int p_x,int p_y, int p_width, const BColor& p_color, unsigned char *p_data); - _FORCE_INLINE_ void _put_pixel(int p_x,int p_y, const BColor& p_color, unsigned char *p_data); _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 - _FORCE_INLINE_ static void _get_format_min_data_size(Format p_format,int &r_w, int &r_h); static int _get_dst_image_size(int p_width, int p_height, Format p_format,int &r_mipmaps,int p_mipmaps=-1); 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_dst,const uint8_t *p_src); + _FORCE_INLINE_ void _get_pixelb(int p_x,int p_y, uint32_t p_pixelsize,const uint8_t *p_src,uint8_t *p_dst); public: @@ -207,20 +149,11 @@ public: int get_width() const; ///< Get image width int get_height() const; ///< Get image height - int get_mipmaps() const; - - /** - * Get a pixel from the image. for grayscale or indexed formats, use Color::gray to obtain the actual - * value. - */ - Color get_pixel(int p_x,int p_y,int p_mipmap=0) const; - /** - * Set a pixel into the image. for grayscale or indexed formats, a suitable Color constructor. - */ - void put_pixel(int p_x,int p_y, const Color& p_color,int p_mipmap=0); /* alpha and index are averaged */ + bool has_mipmaps() const; + int get_mipmap_count() const; /** - * Convert the image to another format, as close as it can be done. + * Convert the image to another format, conversion only to raw byte format */ void convert( Format p_new_format ); @@ -259,25 +192,21 @@ public: void flip_x(); void flip_y(); + /** * Generate a mipmap to an image (creates an image 1/4 the size, with averaging of 4->1) */ - Error generate_mipmaps(int p_amount=-1,bool p_keep_existing=false); + Error generate_mipmaps(bool p_keep_existing=false); void clear_mipmaps(); - /** - * Generate a normal map from a grayscale image - */ - - void make_normalmap(float p_height_scale=1.0); /** * 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, int p_mipmaps, Format p_format, const DVector<uint8_t>& p_data); + void create(int p_width, int p_height, bool p_use_mipmaps, Format p_format, const DVector<uint8_t>& p_data); void create( const char ** p_xpm ); /** @@ -301,7 +230,7 @@ public: /** * import an image of a specific size and format from a pointer */ - Image(int p_width, int p_height, int p_mipmaps, Format p_format, const DVector<uint8_t>& p_data); + Image(int p_width, int p_height, bool p_mipmaps, Format p_format, const DVector<uint8_t>& p_data); enum AlphaMode { ALPHA_NONE, @@ -312,32 +241,27 @@ public: AlphaMode detect_alpha() const; bool is_invisible() const; - void put_indexed_pixel(int p_x, int p_y, uint8_t p_idx,int p_mipmap=0); - uint8_t get_indexed_pixel(int p_x, int p_y,int p_mipmap=0) const; - void set_pallete(const DVector<uint8_t>& p_data); - static int get_format_pixel_size(Format p_format); static int get_format_pixel_rshift(Format p_format); - static int get_format_pallete_size(Format p_format); + static void get_format_min_pixel_size(Format p_format,int &r_w, int &r_h); + static int get_image_data_size(int p_width, int p_height, Format p_format,int p_mipmaps=0); static int get_image_required_mipmaps(int p_width, int p_height, Format p_format); - - bool operator==(const Image& p_image) const; - void quantize(); - enum CompressMode { - COMPRESS_BC, + COMPRESS_16BIT, + COMPRESS_S3TC, COMPRESS_PVRTC2, COMPRESS_PVRTC4, - COMPRESS_ETC + COMPRESS_ETC, + COMPRESS_ETC2 }; - Error compress(CompressMode p_mode=COMPRESS_BC); + Error compress(CompressMode p_mode=COMPRESS_S3TC); Image compressed(int p_mode); /* from the Image::CompressMode enum */ Error decompress(); Image decompressed() const; @@ -349,8 +273,6 @@ public: void normalmap_to_xy(); void blit_rect(const Image& p_src, const Rect2& p_src_rect,const Point2& p_dest); - void brush_transfer(const Image& p_src, const Image& p_brush, const Point2& p_dest); - Image brushed(const Image& p_src, const Image& p_brush, const Point2& p_dest) const; Rect2 get_used_rect() const; Image get_rect(const Rect2& p_area) const; diff --git a/core/image_quantize.cpp b/core/image_quantize.cpp deleted file mode 100644 index a594aee60c..0000000000 --- a/core/image_quantize.cpp +++ /dev/null @@ -1,365 +0,0 @@ -/*************************************************************************/ -/* image_quantize.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 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.h" -#include <stdio.h> -#include "print_string.h" -#ifdef TOOLS_ENABLED -#include "set.h" -#include "sort.h" -#include "os/os.h" - -//#define QUANTIZE_SPEED_OVER_QUALITY - - -Image::MCBlock::MCBlock() { - - -} - -Image::MCBlock::MCBlock(BColorPos *p_colors,int p_color_count) { - - colors=p_colors; - color_count=p_color_count; - min_color.color=BColor(255,255,255,255); - max_color.color=BColor(0,0,0,0); - shrink(); -} - -int Image::MCBlock::get_longest_axis_index() const { - - int max_dist=-1; - int max_index=0; - - for(int i=0;i<4;i++) { - - int d = max_color.color.col[i]-min_color.color.col[i]; - if (d>max_dist) { - max_index=i; - max_dist=d; - } - } - - return max_index; -} -int Image::MCBlock::get_longest_axis_length() const { - - int max_dist=-1; - - for(int i=0;i<4;i++) { - - int d = max_color.color.col[i]-min_color.color.col[i]; - if (d>max_dist) { - max_dist=d; - } - } - - return max_dist; -} - -bool Image::MCBlock::operator<(const MCBlock& p_block) const { - - int alen = get_longest_axis_length(); - int blen = p_block.get_longest_axis_length(); - if (alen==blen) { - - return colors < p_block.colors; - } else - return alen < blen; - -} - -void Image::MCBlock::shrink() { - - min_color=colors[0]; - max_color=colors[0]; - - for(int i=1;i<color_count;i++) { - - for(int j=0;j<4;j++) { - - min_color.color.col[j]=MIN(min_color.color.col[j],colors[i].color.col[j]); - max_color.color.col[j]=MAX(max_color.color.col[j],colors[i].color.col[j]); - } - } -} - - - - -void Image::quantize() { - - bool has_alpha = detect_alpha()!=ALPHA_NONE; - - bool quantize_fast=OS::get_singleton()->has_environment("QUANTIZE_FAST"); - - convert(FORMAT_RGBA); - - ERR_FAIL_COND( format!=FORMAT_RGBA ); - - DVector<uint8_t> indexed_data; - - - { - int color_count = data.size()/4; - - ERR_FAIL_COND(color_count==0); - - Set<MCBlock> block_queue; - - DVector<BColorPos> data_colors; - data_colors.resize(color_count); - - DVector<BColorPos>::Write dcw=data_colors.write(); - - DVector<uint8_t>::Read dr = data.read(); - const BColor * drptr=(const BColor*)&dr[0]; - BColorPos *bcptr=&dcw[0]; - - - - { - for(int i=0;i<color_count;i++) { - - //uint32_t data_ofs=i<<2; - bcptr[i].color=drptr[i];//BColor(drptr[data_ofs+0],drptr[data_ofs+1],drptr[data_ofs+2],drptr[data_ofs+3]); - bcptr[i].index=i; - } - - } - - //printf("color count: %i\n",color_count); - /* - for(int i=0;i<color_count;i++) { - - BColor bc = ((BColor*)&wb[0])[i]; - printf("%i - %i,%i,%i,%i\n",i,bc.r,bc.g,bc.b,bc.a); - }*/ - - MCBlock initial_block((BColorPos*)&dcw[0],color_count); - - block_queue.insert(initial_block); - - while( block_queue.size() < 256 && block_queue.back()->get().color_count > 1 ) { - - MCBlock longest = block_queue.back()->get(); - //printf("longest: %i (%i)\n",longest.get_longest_axis_index(),longest.get_longest_axis_length()); - - block_queue.erase(block_queue.back()); - - BColorPos *first = longest.colors; - BColorPos *median = longest.colors + (longest.color_count+1)/2; - BColorPos *end = longest.colors + longest.color_count; - -#if 0 - int lai =longest.get_longest_axis_index(); - switch(lai) { -#if 0 - case 0: { SortArray<BColorPos,BColorPos::SortR> sort; sort.sort(first,end-first); } break; - case 1: { SortArray<BColorPos,BColorPos::SortG> sort; sort.sort(first,end-first); } break; - case 2: { SortArray<BColorPos,BColorPos::SortB> sort; sort.sort(first,end-first); } break; - case 3: { SortArray<BColorPos,BColorPos::SortA> sort; sort.sort(first,end-first); } break; -#else - case 0: { SortArray<BColorPos,BColorPos::SortR> sort; sort.nth_element(0,end-first,median-first,first); } break; - case 1: { SortArray<BColorPos,BColorPos::SortG> sort; sort.nth_element(0,end-first,median-first,first); } break; - case 2: { SortArray<BColorPos,BColorPos::SortB> sort; sort.nth_element(0,end-first,median-first,first); } break; - case 3: { SortArray<BColorPos,BColorPos::SortA> sort; sort.nth_element(0,end-first,median-first,first); } break; -#endif - - } - - //avoid same color from being split in 2 - //search forward and flip - BColorPos *median_end=median; - BColorPos *p=median_end+1; - - while(p!=end) { - if (median_end->color==p->color) { - SWAP(*(median_end+1),*p); - median_end++; - } - p++; - } - - //search backward and flip - BColorPos *median_begin=median; - p=median_begin-1; - - while(p!=(first-1)) { - if (median_begin->color==p->color) { - SWAP(*(median_begin-1),*p); - median_begin--; - } - p--; - } - - - if (first < median_begin) { - median=median_begin; - } else if (median_end < end-1) { - median=median_end+1; - } else { - break; //shouldn't have arrived here, since it means all pixels are equal, but wathever - } - - MCBlock left(first,median-first); - MCBlock right(median,end-median); - - block_queue.insert(left); - block_queue.insert(right); - -#else - switch(longest.get_longest_axis_index()) { - case 0: { SortArray<BColorPos,BColorPos::SortR> sort; sort.nth_element(0,end-first,median-first,first); } break; - case 1: { SortArray<BColorPos,BColorPos::SortG> sort; sort.nth_element(0,end-first,median-first,first); } break; - case 2: { SortArray<BColorPos,BColorPos::SortB> sort; sort.nth_element(0,end-first,median-first,first); } break; - case 3: { SortArray<BColorPos,BColorPos::SortA> sort; sort.nth_element(0,end-first,median-first,first); } break; - - } - - MCBlock left(first,median-first); - MCBlock right(median,end-median); - - block_queue.insert(left); - block_queue.insert(right); - - -#endif - - - } - - while(block_queue.size() > 256) { - - block_queue.erase(block_queue.front());// erase least significant - } - - int res_colors=0; - - int comp_size = (has_alpha?4:3); - indexed_data.resize(color_count + 256*comp_size); - - DVector<uint8_t>::Write iw = indexed_data.write(); - uint8_t *iwptr=&iw[0]; - BColor pallete[256]; - - // print_line("applying quantization - res colors "+itos(block_queue.size())); - - while(block_queue.size()) { - - const MCBlock &b = block_queue.back()->get(); - - uint64_t sum[4]={0,0,0,0}; - - for(int i=0;i<b.color_count;i++) { - - sum[0]+=b.colors[i].color.col[0]; - sum[1]+=b.colors[i].color.col[1]; - sum[2]+=b.colors[i].color.col[2]; - sum[3]+=b.colors[i].color.col[3]; - } - - BColor c( sum[0]/b.color_count, sum[1]/b.color_count, sum[2]/b.color_count, sum[3]/b.color_count ); - - - - //printf(" %i: %i,%i,%i,%i out of %i\n",res_colors,c.r,c.g,c.b,c.a,b.color_count); - - - - for(int i=0;i<comp_size;i++) { - iwptr[ color_count + res_colors * comp_size + i ] = c.col[i]; - } - - if (quantize_fast) { - for(int i=0;i<b.color_count;i++) { - iwptr[b.colors[i].index]=res_colors; - } - } else { - - pallete[res_colors]=c; - } - - - res_colors++; - - block_queue.erase(block_queue.back()); - - } - - - if (!quantize_fast) { - - for(int i=0;i<color_count;i++) { - - const BColor &c=drptr[i]; - uint8_t best_dist_idx=0; - uint32_t dist=0xFFFFFFFF; - - for(int j=0;j<res_colors;j++) { - - const BColor &pc=pallete[j]; - uint32_t d = 0; - { int16_t v = (int16_t)c.r-(int16_t)pc.r; d+=v*v; } - { int16_t v = (int16_t)c.g-(int16_t)pc.g; d+=v*v; } - { int16_t v = (int16_t)c.b-(int16_t)pc.b; d+=v*v; } - { int16_t v = (int16_t)c.a-(int16_t)pc.a; d+=v*v; } - - if (d<=dist) { - best_dist_idx=j; - dist=d; - } - } - - - iwptr[ i ] = best_dist_idx; - - } - } - - //iw = DVector<uint8_t>::Write(); - //dr = DVector<uint8_t>::Read(); - //wb = DVector<uint8_t>::Write(); - } - - print_line(itos(indexed_data.size())); - data=indexed_data; - format=has_alpha?FORMAT_INDEXED_ALPHA:FORMAT_INDEXED; - - -} //do none - - - -#else - - -void Image::quantize() {} //do none - - -#endif diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp index 6032d8210a..bc6cc0bb83 100644 --- a/core/io/marshalls.cpp +++ b/core/io/marshalls.cpp @@ -1060,7 +1060,7 @@ Error encode_variant(const Variant& p_variant, uint8_t *r_buffer, int &r_len) { if (buf) { encode_uint32(image.get_format(),&buf[0]); - encode_uint32(image.get_mipmaps(),&buf[4]); + encode_uint32(image.has_mipmaps(),&buf[4]); encode_uint32(image.get_width(),&buf[8]); encode_uint32(image.get_height(),&buf[12]); int ds=data.size(); diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index 7df8f7fd5a..109d2d811e 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -74,29 +74,6 @@ enum { IMAGE_ENCODING_LOSSLESS=2, IMAGE_ENCODING_LOSSY=3, - IMAGE_FORMAT_GRAYSCALE=0, - IMAGE_FORMAT_INTENSITY=1, - IMAGE_FORMAT_GRAYSCALE_ALPHA=2, - IMAGE_FORMAT_RGB=3, - IMAGE_FORMAT_RGBA=4, - IMAGE_FORMAT_INDEXED=5, - IMAGE_FORMAT_INDEXED_ALPHA=6, - IMAGE_FORMAT_BC1=7, - IMAGE_FORMAT_BC2=8, - IMAGE_FORMAT_BC3=9, - IMAGE_FORMAT_BC4=10, - IMAGE_FORMAT_BC5=11, - IMAGE_FORMAT_PVRTC2=12, - IMAGE_FORMAT_PVRTC2_ALPHA=13, - IMAGE_FORMAT_PVRTC4=14, - IMAGE_FORMAT_PVRTC4_ALPHA=15, - IMAGE_FORMAT_ETC=16, - IMAGE_FORMAT_ATC=17, - IMAGE_FORMAT_ATC_ALPHA_EXPLICIT=18, - IMAGE_FORMAT_ATC_ALPHA_INTERPOLATED=19, - IMAGE_FORMAT_CUSTOM=30, - - OBJECT_EMPTY=0, OBJECT_EXTERNAL_RESOURCE=1, OBJECT_INTERNAL_RESOURCE=2, @@ -269,38 +246,22 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant& r_v) { uint32_t height = f->get_32(); uint32_t mipmaps = f->get_32(); uint32_t format = f->get_32(); - Image::Format fmt; - switch(format) { - - case IMAGE_FORMAT_GRAYSCALE: { fmt=Image::FORMAT_GRAYSCALE; } break; - case IMAGE_FORMAT_INTENSITY: { fmt=Image::FORMAT_INTENSITY; } break; - case IMAGE_FORMAT_GRAYSCALE_ALPHA: { fmt=Image::FORMAT_GRAYSCALE_ALPHA; } break; - case IMAGE_FORMAT_RGB: { fmt=Image::FORMAT_RGB; } break; - case IMAGE_FORMAT_RGBA: { fmt=Image::FORMAT_RGBA; } break; - case IMAGE_FORMAT_INDEXED: { fmt=Image::FORMAT_INDEXED; } break; - case IMAGE_FORMAT_INDEXED_ALPHA: { fmt=Image::FORMAT_INDEXED_ALPHA; } break; - case IMAGE_FORMAT_BC1: { fmt=Image::FORMAT_BC1; } break; - case IMAGE_FORMAT_BC2: { fmt=Image::FORMAT_BC2; } break; - case IMAGE_FORMAT_BC3: { fmt=Image::FORMAT_BC3; } break; - case IMAGE_FORMAT_BC4: { fmt=Image::FORMAT_BC4; } break; - case IMAGE_FORMAT_BC5: { fmt=Image::FORMAT_BC5; } break; - case IMAGE_FORMAT_PVRTC2: { fmt=Image::FORMAT_PVRTC2; } break; - case IMAGE_FORMAT_PVRTC2_ALPHA: { fmt=Image::FORMAT_PVRTC2_ALPHA; } break; - case IMAGE_FORMAT_PVRTC4: { fmt=Image::FORMAT_PVRTC4; } break; - case IMAGE_FORMAT_PVRTC4_ALPHA: { fmt=Image::FORMAT_PVRTC4_ALPHA; } break; - case IMAGE_FORMAT_ETC: { fmt=Image::FORMAT_ETC; } break; - case IMAGE_FORMAT_ATC: { fmt=Image::FORMAT_ATC; } break; - case IMAGE_FORMAT_ATC_ALPHA_EXPLICIT: { fmt=Image::FORMAT_ATC_ALPHA_EXPLICIT; } break; - case IMAGE_FORMAT_ATC_ALPHA_INTERPOLATED: { fmt=Image::FORMAT_ATC_ALPHA_INTERPOLATED; } break; - case IMAGE_FORMAT_CUSTOM: { fmt=Image::FORMAT_CUSTOM; } break; - default: { - - ERR_FAIL_V(ERR_FILE_CORRUPT); - } + const uint32_t format_version_shift=24; + const uint32_t format_version_mask=format_version_shift-1; + + uint32_t format_version = format>>format_version_shift; + + const uint32_t current_version = 0; + if (format_version>current_version) { + ERR_PRINT("Format version for encoded binary image is too new"); + return ERR_PARSE_ERROR; } + Image::Format fmt=Image::Format(format&format_version_mask); //if format changes, we can add a compatibility bit on top + + uint32_t datalen = f->get_32(); DVector<uint8_t> imgdata; @@ -1599,7 +1560,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(const Variant& p_property, int encoding=IMAGE_ENCODING_RAW; float quality=0.7; - if (val.get_format() <= Image::FORMAT_INDEXED_ALPHA) { + if (!val.is_compressed()) { //can only compress uncompressed stuff if (p_hint.hint==PROPERTY_HINT_IMAGE_COMPRESS_LOSSY && Image::lossy_packer) { @@ -1621,33 +1582,8 @@ void ResourceFormatSaverBinaryInstance::write_variant(const Variant& p_property, f->store_32(val.get_width()); f->store_32(val.get_height()); - f->store_32(val.get_mipmaps()); - switch(val.get_format()) { - - case Image::FORMAT_GRAYSCALE: f->store_32(IMAGE_FORMAT_GRAYSCALE ); break; ///< one byte per pixel: f->store_32(IMAGE_FORMAT_ ); break; 0-255 - case Image::FORMAT_INTENSITY: f->store_32(IMAGE_FORMAT_INTENSITY ); break; ///< one byte per pixel: f->store_32(IMAGE_FORMAT_ ); break; 0-255 - case Image::FORMAT_GRAYSCALE_ALPHA: f->store_32(IMAGE_FORMAT_GRAYSCALE_ALPHA ); break; ///< two bytes per pixel: f->store_32(IMAGE_FORMAT_ ); break; 0-255. alpha 0-255 - case Image::FORMAT_RGB: f->store_32(IMAGE_FORMAT_RGB ); break; ///< one byte R: f->store_32(IMAGE_FORMAT_ ); break; one byte G: f->store_32(IMAGE_FORMAT_ ); break; one byte B - case Image::FORMAT_RGBA: f->store_32(IMAGE_FORMAT_RGBA ); break; ///< one byte R: f->store_32(IMAGE_FORMAT_ ); break; one byte G: f->store_32(IMAGE_FORMAT_ ); break; one byte B: f->store_32(IMAGE_FORMAT_ ); break; one byte A - case Image::FORMAT_INDEXED: f->store_32(IMAGE_FORMAT_INDEXED ); break; ///< index byte 0-256: f->store_32(IMAGE_FORMAT_ ); break; and after image end: f->store_32(IMAGE_FORMAT_ ); break; 256*3 bytes of palette - case Image::FORMAT_INDEXED_ALPHA: f->store_32(IMAGE_FORMAT_INDEXED_ALPHA ); break; ///< index byte 0-256: f->store_32(IMAGE_FORMAT_ ); break; and after image end: f->store_32(IMAGE_FORMAT_ ); break; 256*4 bytes of palette (alpha) - case Image::FORMAT_BC1: f->store_32(IMAGE_FORMAT_BC1 ); break; // DXT1 - case Image::FORMAT_BC2: f->store_32(IMAGE_FORMAT_BC2 ); break; // DXT3 - case Image::FORMAT_BC3: f->store_32(IMAGE_FORMAT_BC3 ); break; // DXT5 - case Image::FORMAT_BC4: f->store_32(IMAGE_FORMAT_BC4 ); break; // ATI1 - case Image::FORMAT_BC5: f->store_32(IMAGE_FORMAT_BC5 ); break; // ATI2 - case Image::FORMAT_PVRTC2: f->store_32(IMAGE_FORMAT_PVRTC2 ); break; - case Image::FORMAT_PVRTC2_ALPHA: f->store_32(IMAGE_FORMAT_PVRTC2_ALPHA ); break; - case Image::FORMAT_PVRTC4: f->store_32(IMAGE_FORMAT_PVRTC4 ); break; - case Image::FORMAT_PVRTC4_ALPHA: f->store_32(IMAGE_FORMAT_PVRTC4_ALPHA ); break; - case Image::FORMAT_ETC: f->store_32(IMAGE_FORMAT_ETC); break; - case Image::FORMAT_ATC: f->store_32(IMAGE_FORMAT_ATC); break; - case Image::FORMAT_ATC_ALPHA_EXPLICIT: f->store_32(IMAGE_FORMAT_ATC_ALPHA_EXPLICIT); break; - case Image::FORMAT_ATC_ALPHA_INTERPOLATED: f->store_32(IMAGE_FORMAT_ATC_ALPHA_INTERPOLATED); break; - case Image::FORMAT_CUSTOM: f->store_32(IMAGE_FORMAT_CUSTOM ); break; - default: {} - - } + f->store_32(val.has_mipmaps()); + f->store_32(val.get_format()); //if format changes we can add a compatibility version bit int dlen = val.get_data().size(); f->store_32(dlen); diff --git a/core/io/resource_format_xml.cpp b/core/io/resource_format_xml.cpp index d5793da565..7174c40fdf 100644 --- a/core/io/resource_format_xml.cpp +++ b/core/io/resource_format_xml.cpp @@ -553,39 +553,39 @@ Error ResourceInteractiveLoaderXML::parse_property(Variant& r_v, String &r_name) Image::Format imgformat; - +/* if (format=="grayscale") { - imgformat=Image::FORMAT_GRAYSCALE; + imgformat=Image::FORMAT_L8; } else if (format=="intensity") { imgformat=Image::FORMAT_INTENSITY; } else if (format=="grayscale_alpha") { - imgformat=Image::FORMAT_GRAYSCALE_ALPHA; + imgformat=Image::FORMAT_LA8; } else if (format=="rgb") { - imgformat=Image::FORMAT_RGB; + imgformat=Image::FORMAT_RGB8; } else if (format=="rgba") { - imgformat=Image::FORMAT_RGBA; + imgformat=Image::FORMAT_RGBA8; } else if (format=="indexed") { imgformat=Image::FORMAT_INDEXED; } else if (format=="indexed_alpha") { imgformat=Image::FORMAT_INDEXED_ALPHA; } else if (format=="bc1") { - imgformat=Image::FORMAT_BC1; + imgformat=Image::FORMAT_DXT1; } else if (format=="bc2") { - imgformat=Image::FORMAT_BC2; + imgformat=Image::FORMAT_DXT3; } else if (format=="bc3") { - imgformat=Image::FORMAT_BC3; + imgformat=Image::FORMAT_DXT5; } else if (format=="bc4") { - imgformat=Image::FORMAT_BC4; + imgformat=Image::FORMAT_ATI1; } else if (format=="bc5") { - imgformat=Image::FORMAT_BC5; + imgformat=Image::FORMAT_ATI2; } else if (format=="pvrtc2") { imgformat=Image::FORMAT_PVRTC2; } else if (format=="pvrtc2a") { - imgformat=Image::FORMAT_PVRTC2_ALPHA; + imgformat=Image::FORMAT_PVRTC2A; } else if (format=="pvrtc4") { imgformat=Image::FORMAT_PVRTC4; } else if (format=="pvrtc4a") { - imgformat=Image::FORMAT_PVRTC4_ALPHA; + imgformat=Image::FORMAT_PVRTC4A; } else if (format=="etc") { imgformat=Image::FORMAT_ETC; } else if (format=="atc") { @@ -599,7 +599,7 @@ Error ResourceInteractiveLoaderXML::parse_property(Variant& r_v, String &r_name) } else { ERR_FAIL_V( ERR_FILE_CORRUPT ); - } + }*/ int datasize; @@ -614,13 +614,6 @@ Error ResourceInteractiveLoaderXML::parse_property(Variant& r_v, String &r_name) return OK; }; - if (imgformat==Image::FORMAT_CUSTOM) { - - datasize=custom_size; - } else { - - datasize = Image::get_image_data_size(h,w,imgformat,mipmaps); - } if (datasize==0) { //r_v = Image(w, h, imgformat); @@ -2186,33 +2179,33 @@ void ResourceFormatSaverXMLInstance::write_property(const String& p_name,const V params+="encoding=\"raw\""; params+=" width=\""+itos(img.get_width())+"\""; params+=" height=\""+itos(img.get_height())+"\""; - params+=" mipmaps=\""+itos(img.get_mipmaps())+"\""; - + params+=" mipmaps=\""+itos(img.has_mipmaps())+"\""; +/* switch(img.get_format()) { - case Image::FORMAT_GRAYSCALE: params+=" format=\"grayscale\""; break; + case Image::FORMAT_L8: params+=" format=\"grayscale\""; break; case Image::FORMAT_INTENSITY: params+=" format=\"intensity\""; break; - case Image::FORMAT_GRAYSCALE_ALPHA: params+=" format=\"grayscale_alpha\""; break; - case Image::FORMAT_RGB: params+=" format=\"rgb\""; break; - case Image::FORMAT_RGBA: params+=" format=\"rgba\""; break; + case Image::FORMAT_LA8: params+=" format=\"grayscale_alpha\""; break; + case Image::FORMAT_RGB8: params+=" format=\"rgb\""; break; + case Image::FORMAT_RGBA8: params+=" format=\"rgba\""; break; case Image::FORMAT_INDEXED : params+=" format=\"indexed\""; break; case Image::FORMAT_INDEXED_ALPHA: params+=" format=\"indexed_alpha\""; break; - case Image::FORMAT_BC1: params+=" format=\"bc1\""; break; - case Image::FORMAT_BC2: params+=" format=\"bc2\""; break; - case Image::FORMAT_BC3: params+=" format=\"bc3\""; break; - case Image::FORMAT_BC4: params+=" format=\"bc4\""; break; - case Image::FORMAT_BC5: params+=" format=\"bc5\""; break; + case Image::FORMAT_DXT1: params+=" format=\"bc1\""; break; + case Image::FORMAT_DXT3: params+=" format=\"bc2\""; break; + case Image::FORMAT_DXT5: params+=" format=\"bc3\""; break; + case Image::FORMAT_ATI1: params+=" format=\"bc4\""; break; + case Image::FORMAT_ATI2: params+=" format=\"bc5\""; break; case Image::FORMAT_PVRTC2: params+=" format=\"pvrtc2\""; break; - case Image::FORMAT_PVRTC2_ALPHA: params+=" format=\"pvrtc2a\""; break; + case Image::FORMAT_PVRTC2A: params+=" format=\"pvrtc2a\""; break; case Image::FORMAT_PVRTC4: params+=" format=\"pvrtc4\""; break; - case Image::FORMAT_PVRTC4_ALPHA: params+=" format=\"pvrtc4a\""; break; + case Image::FORMAT_PVRTC4A: params+=" format=\"pvrtc4a\""; break; case Image::FORMAT_ETC: params+=" format=\"etc\""; break; case Image::FORMAT_ATC: params+=" format=\"atc\""; break; case Image::FORMAT_ATC_ALPHA_EXPLICIT: params+=" format=\"atcae\""; break; case Image::FORMAT_ATC_ALPHA_INTERPOLATED: params+=" format=\"atcai\""; break; case Image::FORMAT_CUSTOM: params+=" format=\"custom\" custom_size=\""+itos(img.get_data().size())+"\""; break; default: {} - } + }*/ } break; case Variant::NODE_PATH: type="node_path"; break; case Variant::OBJECT: { diff --git a/core/math/camera_matrix.cpp b/core/math/camera_matrix.cpp index 1ed787160c..7910f5fafc 100644 --- a/core/math/camera_matrix.cpp +++ b/core/math/camera_matrix.cpp @@ -54,7 +54,7 @@ void CameraMatrix::set_zero() { } -Plane CameraMatrix::xform4(const Plane& p_vec4) { +Plane CameraMatrix::xform4(const Plane& p_vec4) const { Plane ret; @@ -495,6 +495,28 @@ void CameraMatrix::set_light_bias() { } +void CameraMatrix::set_light_atlas_rect(const Rect2& p_rect) { + + float *m=&matrix[0][0]; + + m[0]=p_rect.size.width, + m[1]=0.0, + m[2]=0.0, + m[3]=0.0, + m[4]=0.0, + m[5]=p_rect.size.height, + m[6]=0.0, + m[7]=0.0, + m[8]=0.0, + m[9]=0.0, + m[10]=1.0, + m[11]=0.0, + m[12]=p_rect.pos.x, + m[13]=p_rect.pos.y, + m[14]=0.0, + m[15]=1.0; +} + CameraMatrix::operator String() const { String str; @@ -512,6 +534,15 @@ float CameraMatrix::get_aspect() const { return w/h; } +int CameraMatrix::get_pixels_per_meter(int p_for_pixel_width) const { + + + Vector3 result = xform(Vector3(1,0,-1)); + + return int((result.x * 0.5 + 0.5) * p_for_pixel_width); + +} + float CameraMatrix::get_fov() const { const float * matrix = (const float*)this->matrix; diff --git a/core/math/camera_matrix.h b/core/math/camera_matrix.h index 246a5faba5..f9fb4837f1 100644 --- a/core/math/camera_matrix.h +++ b/core/math/camera_matrix.h @@ -30,6 +30,7 @@ #define CAMERA_MATRIX_H #include "transform.h" +#include "math_2d.h" /** @author Juan Linietsky <reduzio@gmail.com> */ @@ -53,6 +54,7 @@ struct CameraMatrix { void set_identity(); void set_zero(); void set_light_bias(); + void set_light_atlas_rect(const Rect2& p_rect); void set_perspective(float p_fovy_degrees, float p_aspect, float p_z_near, float p_z_far,bool p_flip_fov=false); void set_orthogonal(float p_left, float p_right, float p_bottom, float p_top, float p_znear, float p_zfar); void set_orthogonal(float p_size, float p_aspect, float p_znear, float p_zfar,bool p_flip_fov=false); @@ -78,13 +80,14 @@ struct CameraMatrix { CameraMatrix operator*(const CameraMatrix& p_matrix) const; - Plane xform4(const Plane& p_vec4); + Plane xform4(const Plane& p_vec4) const; _FORCE_INLINE_ Vector3 xform(const Vector3& p_vec3) const; operator String() const; void scale_translate_to_fit(const AABB& p_aabb); void make_scale(const Vector3 &p_scale); + int get_pixels_per_meter(int p_for_pixel_width) const; operator Transform() const; CameraMatrix(); diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h index a5195e554b..ec0ed39471 100644 --- a/core/math/math_funcs.h +++ b/core/math/math_funcs.h @@ -175,6 +175,108 @@ public: static double log(double x); static double exp(double x); + + static _FORCE_INLINE_ uint32_t halfbits_to_floatbits(uint16_t h) + { + uint16_t h_exp, h_sig; + uint32_t f_sgn, f_exp, f_sig; + + h_exp = (h&0x7c00u); + f_sgn = ((uint32_t)h&0x8000u) << 16; + switch (h_exp) { + case 0x0000u: /* 0 or subnormal */ + h_sig = (h&0x03ffu); + /* Signed zero */ + if (h_sig == 0) { + return f_sgn; + } + /* Subnormal */ + h_sig <<= 1; + while ((h_sig&0x0400u) == 0) { + h_sig <<= 1; + h_exp++; + } + f_exp = ((uint32_t)(127 - 15 - h_exp)) << 23; + f_sig = ((uint32_t)(h_sig&0x03ffu)) << 13; + return f_sgn + f_exp + f_sig; + case 0x7c00u: /* inf or NaN */ + /* All-ones exponent and a copy of the significand */ + return f_sgn + 0x7f800000u + (((uint32_t)(h&0x03ffu)) << 13); + default: /* normalized */ + /* Just need to adjust the exponent and shift */ + return f_sgn + (((uint32_t)(h&0x7fffu) + 0x1c000u) << 13); + } + } + + static _FORCE_INLINE_ float halfptr_to_float(const uint16_t *h) { + + union { + uint32_t u32; + float f32; + } u; + + u.u32=halfbits_to_floatbits(*h); + return u.f32; + } + + static _FORCE_INLINE_ uint16_t make_half_float(float f) { + + union { + float fv; + uint32_t ui; + } ci; + ci.fv=f; + + uint32_t x = ci.ui; + uint32_t sign = (unsigned short)(x >> 31); + uint32_t mantissa; + uint32_t exp; + uint16_t hf; + + // get mantissa + mantissa = x & ((1 << 23) - 1); + // get exponent bits + exp = x & (0xFF << 23); + if (exp >= 0x47800000) + { + // check if the original single precision float number is a NaN + if (mantissa && (exp == (0xFF << 23))) + { + // we have a single precision NaN + mantissa = (1 << 23) - 1; + } + else + { + // 16-bit half-float representation stores number as Inf + mantissa = 0; + } + hf = (((uint16_t)sign) << 15) | (uint16_t)((0x1F << 10)) | + (uint16_t)(mantissa >> 13); + } + // check if exponent is <= -15 + else if (exp <= 0x38000000) + { + + /*// store a denorm half-float value or zero + exp = (0x38000000 - exp) >> 23; + mantissa >>= (14 + exp); + + hf = (((uint16_t)sign) << 15) | (uint16_t)(mantissa); + */ + hf=0; //denormals do not work for 3D, convert to zero + } + else + { + hf = (((uint16_t)sign) << 15) | + (uint16_t)((exp - 0x38000000) >> 13) | + (uint16_t)(mantissa >> 13); + } + + return hf; + } + + + }; diff --git a/core/os/os.cpp b/core/os/os.cpp index 57ef067051..2640b69996 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -68,6 +68,7 @@ void OS::print_error(const char* p_function,const char* p_file,int p_line,const case ERR_ERROR: err_type="**ERROR**"; break; case ERR_WARNING: err_type="**WARNING**"; break; case ERR_SCRIPT: err_type="**SCRIPT ERROR**"; break; + case ERR_SHADER: err_type="**SHADER ERROR**"; break; } if (p_rationale && *p_rationale) diff --git a/core/os/os.h b/core/os/os.h index 09ce981f66..5ea3216f24 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -120,7 +120,8 @@ public: enum ErrorType { ERR_ERROR, ERR_WARNING, - ERR_SCRIPT + ERR_SCRIPT, + ERR_SHADER }; virtual void print_error(const char* p_function,const char* p_file,int p_line,const char *p_code,const char*p_rationale,ErrorType p_type=ERR_ERROR); diff --git a/core/pair.h b/core/pair.h index fe73377fab..d75cbed642 100644 --- a/core/pair.h +++ b/core/pair.h @@ -34,6 +34,9 @@ struct Pair { F first; S second; + + Pair() {} + Pair( F p_first, S p_second) { first=p_first; second=p_second; } }; #endif // PAIR_H diff --git a/core/rid.cpp b/core/rid.cpp index 35cd83e786..c7e487f91a 100644 --- a/core/rid.cpp +++ b/core/rid.cpp @@ -28,18 +28,16 @@ /*************************************************************************/ #include "rid.h" -static SafeRefCount current_id; -void RID_OwnerBase::init_rid() { +RID_Data::~RID_Data() { - current_id.init(1); } -ID RID_OwnerBase::new_ID() { +SafeRefCount RID_OwnerBase::refcount; - ID id = current_id.refval(); - return id; -} +void RID_OwnerBase::init_rid() { + refcount.init(); +} diff --git a/core/rid.h b/core/rid.h index 83f8418f1f..466e922968 100644 --- a/core/rid.h +++ b/core/rid.h @@ -33,183 +33,197 @@ #include "safe_refcount.h" #include "typedefs.h" #include "os/memory.h" -#include "hash_map.h" +#include "set.h" #include "list.h" /** @author Juan Linietsky <reduzio@gmail.com> */ + class RID_OwnerBase; -typedef uint32_t ID; +class RID_Data { + +friend class RID_OwnerBase; + +#ifndef DEBUG_ENABLED + RID_OwnerBase *_owner; +#endif + uint32_t _id; +public: + _FORCE_INLINE_ uint32_t get_id() const { return _id; } + + virtual ~RID_Data(); +}; + class RID { friend class RID_OwnerBase; - ID _id; - RID_OwnerBase *owner; + + mutable RID_Data *_data; + public: - _FORCE_INLINE_ ID get_id() const { return _id; } - bool operator==(const RID& p_rid) const { + _FORCE_INLINE_ RID_Data *get_data() const { return _data; } + + _FORCE_INLINE_ bool operator==(const RID& p_rid) const { - return _id==p_rid._id; + return _data==p_rid._data; } _FORCE_INLINE_ bool operator<(const RID& p_rid) const { - return _id < p_rid._id; + return _data < p_rid._data; } _FORCE_INLINE_ bool operator<=(const RID& p_rid) const { - return _id <= p_rid._id; + return _data <= p_rid._data; } _FORCE_INLINE_ bool operator>(const RID& p_rid) const { - return _id > p_rid._id; + return _data > p_rid._data; } - bool operator!=(const RID& p_rid) const { + _FORCE_INLINE_ bool operator!=(const RID& p_rid) const { - return _id!=p_rid._id; + return _data!=p_rid._data; } - _FORCE_INLINE_ bool is_valid() const { return _id>0; } + _FORCE_INLINE_ bool is_valid() const { return _data!=NULL; } - operator const void*() const { - return is_valid() ? this : 0; - }; + _FORCE_INLINE_ uint32_t get_id() const { return _data?_data->get_id():0; } _FORCE_INLINE_ RID() { - _id = 0; - owner=0; + _data=NULL; } + }; class RID_OwnerBase { protected: -friend class RID; - void set_id(RID& p_rid, ID p_id) const { p_rid._id=p_id; } - void set_ownage(RID& p_rid) const { p_rid.owner=const_cast<RID_OwnerBase*>(this); } - ID new_ID(); + + static SafeRefCount refcount; + _FORCE_INLINE_ void _set_data(RID& p_rid, RID_Data* p_data) { + p_rid._data=p_data; + refcount.ref(); + p_data->_id=refcount.get(); +#ifndef DEBUG_ENABLED + p_data->_owner=this; +#endif + } + +#ifndef DEBUG_ENABLED + + _FORCE_INLINE_ bool _is_owner(RID& p_rid) const { + + return this==p_rid._owner; + + } + + _FORCE_INLINE_ void _remove_owner(RID& p_rid) { + + return p_rid._owner=NULL; + + } +# +#endif + + public: - virtual bool owns(const RID& p_rid) const=0; - virtual void get_owned_list(List<RID> *p_owned) const=0; - static void init_rid(); + virtual void get_owned_list(List<RID> *p_owned)=0; + static void init_rid(); virtual ~RID_OwnerBase() {} }; -template<class T,bool thread_safe=false> +template<class T> class RID_Owner : public RID_OwnerBase { public: - - typedef void (*ReleaseNotifyFunc)(void*user,T *p_data); -private: - - Mutex *mutex; - mutable HashMap<ID,T*> id_map; - +#ifdef DEBUG_ENABLED + mutable Set<RID_Data*> id_map; +#endif public: - RID make_rid(T * p_data) { + _FORCE_INLINE_ RID make_rid(T * p_data) { - if (thread_safe) { - mutex->lock(); - } - ID id = new_ID(); - id_map[id]=p_data; RID rid; - set_id(rid,id); - set_ownage(rid); + _set_data(rid,p_data); - if (thread_safe) { - mutex->unlock(); - } +#ifdef DEBUG_ENABLED + id_map.insert(p_data) ; +#endif return rid; } _FORCE_INLINE_ T * get(const RID& p_rid) { - if (thread_safe) { - mutex->lock(); - } - - T**elem = id_map.getptr(p_rid.get_id()); +#ifdef DEBUG_ENABLED - if (thread_safe) { - mutex->unlock(); - } - - ERR_FAIL_COND_V(!elem,NULL); - - return *elem; + ERR_FAIL_COND_V(!p_rid.is_valid(),NULL); + ERR_FAIL_COND_V(!id_map.has(p_rid.get_data()),NULL); +#endif + return static_cast<T*>(p_rid.get_data()); } - virtual bool owns(const RID& p_rid) const { + _FORCE_INLINE_ T * getornull(const RID& p_rid) { - if (thread_safe) { - mutex->lock(); - } - - T**elem = id_map.getptr(p_rid.get_id()); +#ifdef DEBUG_ENABLED - if (thread_safe) { - mutex->lock(); + if (p_rid.get_data()) { + ERR_FAIL_COND_V(!id_map.has(p_rid.get_data()),NULL); } +#endif + return static_cast<T*>(p_rid.get_data()); - return elem!=NULL; } - virtual void free(RID p_rid) { - if (thread_safe) { - mutex->lock(); - } - ERR_FAIL_COND(!owns(p_rid)); - id_map.erase(p_rid.get_id()); - } - virtual void get_owned_list(List<RID> *p_owned) const { - - if (thread_safe) { - mutex->lock(); - } + _FORCE_INLINE_ T * getptr(const RID& p_rid) { - const ID*id=NULL; - while((id=id_map.next(id))) { + return static_cast<T*>(p_rid.get_data()); - RID rid; - set_id(rid,*id); - set_ownage(rid); - p_owned->push_back(rid); + } - } - if (thread_safe) { - mutex->lock(); - } + _FORCE_INLINE_ bool owns(const RID& p_rid) const { + if (p_rid.get_data()==NULL) + return false; +#ifdef DEBUG_ENABLED + return id_map.has(p_rid.get_data()); +#else + return _is_owner(p_rid); +#endif } - RID_Owner() { - if (thread_safe) { - - mutex = Mutex::create(); - } + void free(RID p_rid) { +#ifdef DEBUG_ENABLED + id_map.erase(p_rid.get_data()); +#else + _remove_owner(p_rid); +#endif } + void get_owned_list(List<RID> *p_owned) { + - ~RID_Owner() { - if (thread_safe) { +#ifdef DEBUG_ENABLED - memdelete(mutex); + for (typename Set<RID_Data*>::Element *E=id_map.front();E;E=E->next()) { + RID r; + _set_data(r,static_cast<T*>(E->get())); + p_owned->push_back(r); } +#endif + } + }; diff --git a/core/ustring.cpp b/core/ustring.cpp index 5f19a6cff1..0c26fe90c6 100644 --- a/core/ustring.cpp +++ b/core/ustring.cpp @@ -612,6 +612,8 @@ String String::get_slicec(CharType p_splitter, int p_slice) const { if (p_slice==count) { return substr(prev,i-prev); + } else if (c[i]==0) { + return String(); } else { count++; prev=i+1; diff --git a/core/variant_call.cpp b/core/variant_call.cpp index 0707332be9..cedf21b377 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -619,13 +619,9 @@ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Var VCALL_PTR0R(Image,get_width); VCALL_PTR0R(Image,get_height); VCALL_PTR0R(Image,empty); - VCALL_PTR3R(Image,get_pixel); - VCALL_PTR4(Image, put_pixel); VCALL_PTR0R(Image,get_used_rect); - VCALL_PTR3R(Image,brushed); VCALL_PTR1R(Image,load); VCALL_PTR1R(Image,save_png); - VCALL_PTR3(Image,brush_transfer); VCALL_PTR1R(Image,get_rect); VCALL_PTR1R(Image,compressed); VCALL_PTR0R(Image,decompressed); @@ -1528,12 +1524,8 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl ADDFUNC0(IMAGE, INT, Image, get_width, varray()); ADDFUNC0(IMAGE, INT, Image, get_height, varray()); ADDFUNC0(IMAGE, BOOL, Image, empty, varray()); - ADDFUNC3(IMAGE, COLOR, Image, get_pixel, INT, "x", INT, "y", INT, "mipmap_level", varray(0)); - ADDFUNC4(IMAGE, NIL, Image, put_pixel, INT, "x", INT, "y", COLOR, "color", INT, "mipmap_level", varray(0)); - ADDFUNC3(IMAGE, IMAGE, Image, brushed, IMAGE, "src", IMAGE, "brush", VECTOR2, "pos", varray(0)); ADDFUNC1(IMAGE, INT, Image, load, STRING, "path", varray(0)); ADDFUNC1(IMAGE, INT, Image, save_png, STRING, "path", varray(0)); - ADDFUNC3(IMAGE, NIL, Image, brush_transfer, IMAGE, "src", IMAGE, "brush", VECTOR2, "pos", varray(0)); ADDFUNC0(IMAGE, RECT2, Image, get_used_rect, varray(0)); ADDFUNC1(IMAGE, IMAGE, Image, get_rect, RECT2, "area", varray(0)); ADDFUNC1(IMAGE, IMAGE, Image, compressed, INT, "format", varray(0)); @@ -1792,34 +1784,53 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl _VariantCall::add_constant(Variant::INPUT_EVENT,"ACTION",InputEvent::ACTION); - _VariantCall::add_constant(Variant::IMAGE,"COMPRESS_BC",Image::COMPRESS_BC); + _VariantCall::add_constant(Variant::IMAGE,"COMPRESS_16BIT",Image::COMPRESS_16BIT); + _VariantCall::add_constant(Variant::IMAGE,"COMPRESS_S3TC",Image::COMPRESS_S3TC); _VariantCall::add_constant(Variant::IMAGE,"COMPRESS_PVRTC2",Image::COMPRESS_PVRTC2); _VariantCall::add_constant(Variant::IMAGE,"COMPRESS_PVRTC4",Image::COMPRESS_PVRTC4); _VariantCall::add_constant(Variant::IMAGE,"COMPRESS_ETC",Image::COMPRESS_ETC); - - _VariantCall::add_constant(Variant::IMAGE,"FORMAT_GRAYSCALE",Image::FORMAT_GRAYSCALE); - _VariantCall::add_constant(Variant::IMAGE,"FORMAT_INTENSITY",Image::FORMAT_INTENSITY); - _VariantCall::add_constant(Variant::IMAGE,"FORMAT_GRAYSCALE_ALPHA",Image::FORMAT_GRAYSCALE_ALPHA); - _VariantCall::add_constant(Variant::IMAGE,"FORMAT_RGB",Image::FORMAT_RGB); - _VariantCall::add_constant(Variant::IMAGE,"FORMAT_RGBA",Image::FORMAT_RGBA); - _VariantCall::add_constant(Variant::IMAGE,"FORMAT_INDEXED",Image::FORMAT_INDEXED); - _VariantCall::add_constant(Variant::IMAGE,"FORMAT_INDEXED_ALPHA",Image::FORMAT_INDEXED_ALPHA); - _VariantCall::add_constant(Variant::IMAGE,"FORMAT_YUV_422",Image::FORMAT_YUV_422); - _VariantCall::add_constant(Variant::IMAGE,"FORMAT_YUV_444",Image::FORMAT_YUV_444); - _VariantCall::add_constant(Variant::IMAGE,"FORMAT_BC1",Image::FORMAT_BC1); - _VariantCall::add_constant(Variant::IMAGE,"FORMAT_BC2",Image::FORMAT_BC2); - _VariantCall::add_constant(Variant::IMAGE,"FORMAT_BC3",Image::FORMAT_BC3); - _VariantCall::add_constant(Variant::IMAGE,"FORMAT_BC4",Image::FORMAT_BC4); - _VariantCall::add_constant(Variant::IMAGE,"FORMAT_BC5",Image::FORMAT_BC5); + _VariantCall::add_constant(Variant::IMAGE,"COMPRESS_ETC2",Image::COMPRESS_ETC2); + + + + _VariantCall::add_constant(Variant::IMAGE,"FORMAT_L8",Image::FORMAT_L8); + _VariantCall::add_constant(Variant::IMAGE,"FORMAT_LA8",Image::FORMAT_LA8); + _VariantCall::add_constant(Variant::IMAGE,"FORMAT_R8",Image::FORMAT_R8); + _VariantCall::add_constant(Variant::IMAGE,"FORMAT_RG8",Image::FORMAT_RG8); + _VariantCall::add_constant(Variant::IMAGE,"FORMAT_RGB8",Image::FORMAT_RGB8); + _VariantCall::add_constant(Variant::IMAGE,"FORMAT_RGBA8",Image::FORMAT_RGBA8); + _VariantCall::add_constant(Variant::IMAGE,"FORMAT_RGB565",Image::FORMAT_RGB565); + _VariantCall::add_constant(Variant::IMAGE,"FORMAT_RGBA4444",Image::FORMAT_RGBA4444); + _VariantCall::add_constant(Variant::IMAGE,"FORMAT_RGBA5551",Image::FORMAT_DXT1); + _VariantCall::add_constant(Variant::IMAGE,"FORMAT_RF",Image::FORMAT_RF); + _VariantCall::add_constant(Variant::IMAGE,"FORMAT_RGF",Image::FORMAT_RGF); + _VariantCall::add_constant(Variant::IMAGE,"FORMAT_RGBF",Image::FORMAT_RGBF); + _VariantCall::add_constant(Variant::IMAGE,"FORMAT_RGBAF",Image::FORMAT_RGBAF); + _VariantCall::add_constant(Variant::IMAGE,"FORMAT_RH",Image::FORMAT_RH); + _VariantCall::add_constant(Variant::IMAGE,"FORMAT_RGH",Image::FORMAT_RGH); + _VariantCall::add_constant(Variant::IMAGE,"FORMAT_RGBH",Image::FORMAT_RGBH); + _VariantCall::add_constant(Variant::IMAGE,"FORMAT_RGBAH",Image::FORMAT_RGBAH); + _VariantCall::add_constant(Variant::IMAGE,"FORMAT_DXT1",Image::FORMAT_DXT1); + _VariantCall::add_constant(Variant::IMAGE,"FORMAT_DXT3",Image::FORMAT_DXT3); + _VariantCall::add_constant(Variant::IMAGE,"FORMAT_DXT5",Image::FORMAT_DXT5); + _VariantCall::add_constant(Variant::IMAGE,"FORMAT_ATI1",Image::FORMAT_ATI1); + _VariantCall::add_constant(Variant::IMAGE,"FORMAT_ATI2",Image::FORMAT_ATI2); + _VariantCall::add_constant(Variant::IMAGE,"FORMAT_BPTC_RGBA",Image::FORMAT_BPTC_RGBA); + _VariantCall::add_constant(Variant::IMAGE,"FORMAT_BPTC_RGBF",Image::FORMAT_BPTC_RGBF); + _VariantCall::add_constant(Variant::IMAGE,"FORMAT_BPTC_RGBFU",Image::FORMAT_BPTC_RGBFU); _VariantCall::add_constant(Variant::IMAGE,"FORMAT_PVRTC2",Image::FORMAT_PVRTC2); - _VariantCall::add_constant(Variant::IMAGE,"FORMAT_PVRTC2_ALPHA",Image::FORMAT_PVRTC2_ALPHA); + _VariantCall::add_constant(Variant::IMAGE,"FORMAT_PVRTC2A",Image::FORMAT_PVRTC2A); _VariantCall::add_constant(Variant::IMAGE,"FORMAT_PVRTC4",Image::FORMAT_PVRTC4); - _VariantCall::add_constant(Variant::IMAGE,"FORMAT_PVRTC4_ALPHA",Image::FORMAT_PVRTC4_ALPHA); + _VariantCall::add_constant(Variant::IMAGE,"FORMAT_PVRTC4A",Image::FORMAT_PVRTC4A); _VariantCall::add_constant(Variant::IMAGE,"FORMAT_ETC",Image::FORMAT_ETC); - _VariantCall::add_constant(Variant::IMAGE,"FORMAT_ATC",Image::FORMAT_ATC); - _VariantCall::add_constant(Variant::IMAGE,"FORMAT_ATC_ALPHA_EXPLICIT",Image::FORMAT_ATC_ALPHA_EXPLICIT); - _VariantCall::add_constant(Variant::IMAGE,"FORMAT_ATC_ALPHA_INTERPOLATED",Image::FORMAT_ATC_ALPHA_INTERPOLATED); - _VariantCall::add_constant(Variant::IMAGE,"FORMAT_CUSTOM",Image::FORMAT_CUSTOM); + _VariantCall::add_constant(Variant::IMAGE,"FORMAT_ETC2_R11",Image::FORMAT_ETC2_R11); + _VariantCall::add_constant(Variant::IMAGE,"FORMAT_ETC2_R11S",Image::FORMAT_ETC2_R11S); + _VariantCall::add_constant(Variant::IMAGE,"FORMAT_ETC2_RG11",Image::FORMAT_ETC2_RG11); + _VariantCall::add_constant(Variant::IMAGE,"FORMAT_ETC2_RG11S",Image::FORMAT_ETC2_RG11S); + _VariantCall::add_constant(Variant::IMAGE,"FORMAT_ETC2_RGB8",Image::FORMAT_ETC2_RGB8); + _VariantCall::add_constant(Variant::IMAGE,"FORMAT_ETC2_RGBA8",Image::FORMAT_ETC2_RGBA8); + _VariantCall::add_constant(Variant::IMAGE,"FORMAT_ETC2_RGB8A1",Image::FORMAT_ETC2_RGB8A1); + _VariantCall::add_constant(Variant::IMAGE,"FORMAT_MAX",Image::FORMAT_MAX); _VariantCall::add_constant(Variant::IMAGE,"INTERPOLATE_NEAREST",Image::INTERPOLATE_NEAREST); _VariantCall::add_constant(Variant::IMAGE,"INTERPOLATE_BILINEAR",Image::INTERPOLATE_BILINEAR); diff --git a/core/variant_parser.cpp b/core/variant_parser.cpp index 7c830b1384..597e975873 100644 --- a/core/variant_parser.cpp +++ b/core/variant_parser.cpp @@ -755,8 +755,17 @@ Error VariantParser::parse_value(Token& token,Variant &value,Stream *p_stream,in } get_token(p_stream,token,line,r_err_str); - if (token.type!=TK_NUMBER) { - r_err_str="Expected number (mipmaps)"; + + bool has_mipmaps=false; + + if (token.type==TK_NUMBER) { + has_mipmaps=bool(token.value); + } else if (token.type==TK_IDENTIFIER && String(token.value)=="true") { + has_mipmaps=true; + } else if (token.type==TK_IDENTIFIER && String(token.value)=="false") { + has_mipmaps=false; + } else { + r_err_str="Expected number/true/false (mipmaps)"; return ERR_PARSE_ERROR; } @@ -778,32 +787,18 @@ Error VariantParser::parse_value(Token& token,Variant &value,Stream *p_stream,in String sformat=token.value; - Image::Format format; - - if (sformat=="GRAYSCALE") format=Image::FORMAT_GRAYSCALE; - else if (sformat=="INTENSITY") format=Image::FORMAT_INTENSITY; - else if (sformat=="GRAYSCALE_ALPHA") format=Image::FORMAT_GRAYSCALE_ALPHA; - else if (sformat=="RGB") format=Image::FORMAT_RGB; - else if (sformat=="RGBA") format=Image::FORMAT_RGBA; - else if (sformat=="INDEXED") format=Image::FORMAT_INDEXED; - else if (sformat=="INDEXED_ALPHA") format=Image::FORMAT_INDEXED_ALPHA; - else if (sformat=="BC1") format=Image::FORMAT_BC1; - else if (sformat=="BC2") format=Image::FORMAT_BC2; - else if (sformat=="BC3") format=Image::FORMAT_BC3; - else if (sformat=="BC4") format=Image::FORMAT_BC4; - else if (sformat=="BC5") format=Image::FORMAT_BC5; - else if (sformat=="PVRTC2") format=Image::FORMAT_PVRTC2; - else if (sformat=="PVRTC2_ALPHA") format=Image::FORMAT_PVRTC2_ALPHA; - else if (sformat=="PVRTC4") format=Image::FORMAT_PVRTC4; - else if (sformat=="PVRTC4_ALPHA") format=Image::FORMAT_PVRTC4_ALPHA; - else if (sformat=="ATC") format=Image::FORMAT_ATC; - else if (sformat=="ATC_ALPHA_EXPLICIT") format=Image::FORMAT_ATC_ALPHA_EXPLICIT; - else if (sformat=="ATC_ALPHA_INTERPOLATED") format=Image::FORMAT_ATC_ALPHA_INTERPOLATED; - else if (sformat=="CUSTOM") format=Image::FORMAT_CUSTOM; - else { - r_err_str="Invalid image format: '"+sformat+"'"; + Image::Format format=Image::FORMAT_MAX; + + for(int i=0;i<Image::FORMAT_MAX;i++) { + if (Image::get_format_name(format)==sformat) { + format=Image::Format(i); + } + } + + if (format==Image::FORMAT_MAX) { + r_err_str="Unknown image format: "+String(sformat); return ERR_PARSE_ERROR; - }; + } int len = Image::get_image_data_size(width,height,format,mipmaps); @@ -1986,35 +1981,8 @@ Error VariantWriter::write(const Variant& p_variant, StoreStringFunc p_store_str String imgstr="Image( "; imgstr+=itos(img.get_width()); imgstr+=", "+itos(img.get_height()); - imgstr+=", "+itos(img.get_mipmaps()); - imgstr+=", "; - - switch(img.get_format()) { - - case Image::FORMAT_GRAYSCALE: imgstr+="GRAYSCALE"; break; - case Image::FORMAT_INTENSITY: imgstr+="INTENSITY"; break; - case Image::FORMAT_GRAYSCALE_ALPHA: imgstr+="GRAYSCALE_ALPHA"; break; - case Image::FORMAT_RGB: imgstr+="RGB"; break; - case Image::FORMAT_RGBA: imgstr+="RGBA"; break; - case Image::FORMAT_INDEXED : imgstr+="INDEXED"; break; - case Image::FORMAT_INDEXED_ALPHA: imgstr+="INDEXED_ALPHA"; break; - case Image::FORMAT_BC1: imgstr+="BC1"; break; - case Image::FORMAT_BC2: imgstr+="BC2"; break; - case Image::FORMAT_BC3: imgstr+="BC3"; break; - case Image::FORMAT_BC4: imgstr+="BC4"; break; - case Image::FORMAT_BC5: imgstr+="BC5"; break; - case Image::FORMAT_PVRTC2: imgstr+="PVRTC2"; break; - case Image::FORMAT_PVRTC2_ALPHA: imgstr+="PVRTC2_ALPHA"; break; - case Image::FORMAT_PVRTC4: imgstr+="PVRTC4"; break; - case Image::FORMAT_PVRTC4_ALPHA: imgstr+="PVRTC4_ALPHA"; break; - case Image::FORMAT_ETC: imgstr+="ETC"; break; - case Image::FORMAT_ATC: imgstr+="ATC"; break; - case Image::FORMAT_ATC_ALPHA_EXPLICIT: imgstr+="ATC_ALPHA_EXPLICIT"; break; - case Image::FORMAT_ATC_ALPHA_INTERPOLATED: imgstr+="ATC_ALPHA_INTERPOLATED"; break; - case Image::FORMAT_CUSTOM: imgstr+="CUSTOM"; break; - default: {} - } - + imgstr+=", "+String(img.has_mipmaps()?"true":"false"); + imgstr+=", "+Image::get_format_name(img.get_format()); String s; |