RES ResourceFormatPKM::load(const String &p_path, const String &p_original_path, Error *r_error) { if (r_error) *r_error = ERR_CANT_OPEN; Error err; FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err); if (!f) return RES(); FileAccessRef fref(f); if (r_error) *r_error = ERR_FILE_CORRUPT; ERR_EXPLAIN("Unable to open PKM texture file: " + p_path); ERR_FAIL_COND_V(err != OK, RES()); // big endian f->set_endian_swap(true); ETC1Header h; ERR_EXPLAIN("Invalid or Unsupported PKM texture file: " + p_path); f->get_buffer((uint8_t *)&h.tag, sizeof(h.tag)); if (strncmp(h.tag, "PKM 10", sizeof(h.tag))) ERR_FAIL_V(RES()); h.format = f->get_16(); h.texWidth = f->get_16(); h.texHeight = f->get_16(); h.origWidth = f->get_16(); h.origHeight = f->get_16(); PoolVector<uint8_t> src_data; uint32_t size = h.texWidth * h.texHeight / 2; src_data.resize(size); PoolVector<uint8_t>::Write wb = src_data.write(); f->get_buffer(wb.ptr(), size); wb = PoolVector<uint8_t>::Write(); int mipmaps = h.format; int width = h.origWidth; int height = h.origHeight; Ref<Image> img = memnew(Image(width, height, mipmaps, Image::FORMAT_ETC, src_data)); Ref<ImageTexture> texture = memnew(ImageTexture); texture->create_from_image(img); if (r_error) *r_error = OK; return texture; }
void AudioStreamSpeex::set_file(const String& p_file) { if (this->file == p_file) return; this->file=p_file; if (p_file == "") { data.resize(0); return; }; Error err; FileAccess* file = FileAccess::open(p_file, FileAccess::READ,&err); if (err != OK) { data.resize(0); }; ERR_FAIL_COND(err != OK); this->file = p_file; data.resize(file->get_len()); int read = file->get_buffer(&data[0], data.size()); memdelete(file); }
String FileAccess::get_sha256(const String &p_file) { FileAccess *f = FileAccess::open(p_file, READ); if (!f) return String(); sha256_context sha256; sha256_init(&sha256); unsigned char step[32768]; while (true) { int br = f->get_buffer(step, 32768); if (br > 0) { sha256_hash(&sha256, step, br); } if (br < 4096) break; } unsigned char hash[32]; sha256_done(&sha256, hash); memdelete(f); return String::hex_encode_buffer(hash, 32); }
int read(void* output,int nBytes) { if (!fa) return -1; return fa->get_buffer((uint8_t*)output, nBytes); };
String FileAccess::get_md5(const String &p_file) { FileAccess *f = FileAccess::open(p_file, READ); if (!f) return String(); MD5_CTX md5; MD5Init(&md5); unsigned char step[32768]; while (true) { int br = f->get_buffer(step, 32768); if (br > 0) { MD5Update(&md5, step, br); } if (br < 4096) break; } MD5Final(&md5); String ret = String::md5(md5.digest); memdelete(f); return ret; }
String FileAccess::get_multiple_md5(const Vector<String> &p_file) { MD5_CTX md5; MD5Init(&md5); for (int i = 0; i < p_file.size(); i++) { FileAccess *f = FileAccess::open(p_file[i], READ); ERR_CONTINUE(!f); unsigned char step[32768]; while (true) { int br = f->get_buffer(step, 32768); if (br > 0) { MD5Update(&md5, step, br); } if (br < 4096) break; } memdelete(f); } MD5Final(&md5); String ret = String::md5(md5.digest); return ret; }
Error ResourceImporterImage::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files) { FileAccess *f = FileAccess::open(p_source_file, FileAccess::READ); if (!f) { ERR_FAIL_COND_V(!f, ERR_CANT_OPEN); } size_t len = f->get_len(); Vector<uint8_t> data; data.resize(len); f->get_buffer(data.ptrw(), len); memdelete(f); f = FileAccess::open(p_save_path + ".image", FileAccess::WRITE); //save the header GDIM const uint8_t header[4] = { 'G', 'D', 'I', 'M' }; f->store_buffer(header, 4); //SAVE the extension (so it can be recognized by the loader later f->store_pascal_string(p_source_file.get_extension().to_lower()); //SAVE the actual image f->store_buffer(data.ptr(), len); memdelete(f); return OK; }
Error ResourceImporterOGGVorbis::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files) { bool loop = p_options["loop"]; FileAccess *f = FileAccess::open(p_source_file, FileAccess::READ); if (!f) { ERR_FAIL_COND_V(!f, ERR_CANT_OPEN); } size_t len = f->get_len(); PoolVector<uint8_t> data; data.resize(len); PoolVector<uint8_t>::Write w = data.write(); f->get_buffer(w.ptr(), len); memdelete(f); Ref<AudioStreamOGGVorbis> ogg_stream; ogg_stream.instance(); ogg_stream->set_data(data); ogg_stream->set_loop(loop); return ResourceSaver::save(p_save_path + ".asogg", ogg_stream); }
RES ResourceFormatLoaderDynamicFont::load(const String &p_path, const String& p_original_path, Error *r_error) { if (r_error) *r_error=ERR_FILE_CANT_OPEN; FileAccess *f = FileAccess::open(p_path,FileAccess::READ); ERR_FAIL_COND_V(!f,RES()); DVector<uint8_t> data; data.resize(f->get_len()); ERR_FAIL_COND_V(data.size()==0,RES()); { DVector<uint8_t>::Write w = data.write(); f->get_buffer(w.ptr(),data.size()); } Ref<DynamicFontData> dfd; dfd.instance(); dfd->set_font_data(data); if (r_error) *r_error=OK; return dfd; }
Vector<uint8_t> FileAccess::get_file_as_array(const String &p_path) { FileAccess *f = FileAccess::open(p_path, READ); ERR_FAIL_COND_V(!f, Vector<uint8_t>()); Vector<uint8_t> data; data.resize(f->get_len()); f->get_buffer(data.ptrw(), data.size()); memdelete(f); return data; }
Vector<uint8_t> EditorExportPlatform::get_exported_file(String& p_fname) const { Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(p_fname); if (rimd.is_valid()) { if (rimd->get_editor()!="") { Ref<EditorImportPlugin> pl = EditorImportExport::get_singleton()->get_import_plugin_by_name(rimd->get_editor()); if (pl.is_valid()) { Vector<uint8_t> ce = pl->custom_export(p_fname,EditorImportExport::get_singleton()->get_export_platform(get_name())); if (ce.size()) return ce; } } } else if (EditorImportExport::get_singleton()->image_get_export_group(p_fname)) { Ref<EditorImportPlugin> pl = EditorImportExport::get_singleton()->get_import_plugin_by_name("texture_2d"); if (pl.is_valid()) { Vector<uint8_t> ce = pl->custom_export(p_fname,EditorImportExport::get_singleton()->get_export_platform(get_name())); if (ce.size()) { p_fname=p_fname.basename()+".tex"; return ce; } } } else if (EditorImportExport::get_singleton()->get_export_image_action()!=EditorImportExport::IMAGE_ACTION_NONE){ String xt = p_fname.extension().to_lower(); print_line("TRY FOR: "+p_fname); if (EditorImportExport::get_singleton()->get_image_formats().has(xt)) { //should check for more I guess? Ref<EditorImportPlugin> pl = EditorImportExport::get_singleton()->get_import_plugin_by_name("texture_2d"); if (pl.is_valid()) { Vector<uint8_t> ce = pl->custom_export(p_fname,EditorImportExport::get_singleton()->get_export_platform(get_name())); if (ce.size()) { p_fname=p_fname.basename()+".tex"; return ce; } } } } FileAccess *f = FileAccess::open(p_fname,FileAccess::READ); ERR_FAIL_COND_V(!f,Vector<uint8_t>()); Vector<uint8_t> ret; ret.resize(f->get_len()); int rbs = f->get_buffer(ret.ptr(),ret.size()); memdelete(f); return ret; }
godot_int GDAPI godot_videodecoder_file_read(void *ptr, uint8_t *buf, int buf_size) { // ptr is a FileAccess FileAccess *file = reinterpret_cast<FileAccess *>(ptr); // if file exists if (file) { long bytes_read = file->get_buffer(buf, buf_size); // No bytes to read => EOF if (bytes_read == 0) { return 0; } return bytes_read; } return -1; }
size_t AudioStreamPlaybackOGGVorbis::_ov_read_func(void *p_dst, size_t p_data, size_t p_count, void *_f) { //printf("read to %p, %i bytes, %i nmemb, %p\n",p_dst,p_data,p_count,_f); FileAccess *fa = (FileAccess *)_f; size_t read_total = p_data * p_count; if (fa->eof_reached()) return 0; uint8_t *dst = (uint8_t *)p_dst; int read = fa->get_buffer(dst, read_total); return read; }
void EditorExportPlatformOSX::_make_icon(const Image& p_icon,Vector<uint8_t>& icon) { Ref<ImageTexture> it = memnew( ImageTexture ); int size=512; Vector<uint8_t> data; data.resize(8); data[0]='i'; data[1]='c'; data[2]='n'; data[3]='s'; const char *name[]={"ic09","ic08","ic07","icp6","icp5","icp4"}; int index=0; while(size>=16) { Image copy = p_icon; copy.convert(Image::FORMAT_RGBA); copy.resize(size,size); it->create_from_image(copy); String path = EditorSettings::get_singleton()->get_settings_path()+"/tmp/icon.png"; ResourceSaver::save(path,it); FileAccess *f = FileAccess::open(path,FileAccess::READ); ERR_FAIL_COND(!f); int ofs = data.size(); uint32_t len = f->get_len(); data.resize(data.size()+len+8); f->get_buffer(&data[ofs+8],len); memdelete(f); len+=8; len=BSWAP32(len); copymem(&data[ofs],name[index],4); encode_uint32(len,&data[ofs+4]); index++; size/=2; } uint32_t total_len = data.size(); total_len = BSWAP32(total_len); encode_uint32(total_len,&data[4]); icon=data; }
MainLoop *test() { print_line("this is test io"); DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); da->change_dir("."); print_line("Opening current dir " + da->get_current_dir()); String entry; da->list_dir_begin(); while ((entry = da->get_next()) != "") { print_line("entry " + entry + " is dir: " + Variant(da->current_is_dir())); }; da->list_dir_end(); RES texture = ResourceLoader::load("test_data/rock.png"); ERR_FAIL_COND_V(texture.is_null(), NULL); ResourceSaver::save("test_data/rock.xml", texture); print_line("localize paths"); print_line(ProjectSettings::get_singleton()->localize_path("algo.xml")); print_line(ProjectSettings::get_singleton()->localize_path("c:\\windows\\algo.xml")); print_line(ProjectSettings::get_singleton()->localize_path(ProjectSettings::get_singleton()->get_resource_path() + "/something/something.xml")); print_line(ProjectSettings::get_singleton()->localize_path("somedir/algo.xml")); { FileAccess *z = FileAccess::open("test_data/archive.zip", FileAccess::READ); int len = z->get_len(); Vector<uint8_t> zip; zip.resize(len); z->get_buffer(&zip[0], len); z->close(); memdelete(z); FileAccessMemory::register_file("a_package", zip); FileAccess::make_default<FileAccessMemory>(FileAccess::ACCESS_RESOURCES); FileAccess::make_default<FileAccessMemory>(FileAccess::ACCESS_FILESYSTEM); FileAccess::make_default<FileAccessMemory>(FileAccess::ACCESS_USERDATA); print_line("archive test"); }; print_line("test done"); return memnew(TestMainLoop); }
void EditorExportPlatformOSX::_make_icon(const Ref<Image> &p_icon, Vector<uint8_t> &p_data) { Ref<ImageTexture> it = memnew(ImageTexture); int size = 512; Vector<uint8_t> data; data.resize(8); data[0] = 'i'; data[1] = 'c'; data[2] = 'n'; data[3] = 's'; const char *name[] = { "ic09", "ic08", "ic07", "icp6", "icp5", "icp4" }; int index = 0; while (size >= 16) { Ref<Image> copy = p_icon; // does this make sense? doesn't this just increase the reference count instead of making a copy? Do we even need a copy? copy->convert(Image::FORMAT_RGBA8); copy->resize(size, size); it->create_from_image(copy); String path = EditorSettings::get_singleton()->get_cache_dir().plus_file("icon.png"); ResourceSaver::save(path, it); FileAccess *f = FileAccess::open(path, FileAccess::READ); ERR_FAIL_COND(!f); int ofs = data.size(); uint32_t len = f->get_len(); data.resize(data.size() + len + 8); f->get_buffer(&data[ofs + 8], len); memdelete(f); len += 8; len = BSWAP32(len); copymem(&data[ofs], name[index], 4); encode_uint32(len, &data[ofs + 4]); index++; size /= 2; } uint32_t total_len = data.size(); total_len = BSWAP32(total_len); encode_uint32(total_len, &data[4]); p_data = data; }
Vector<uint8_t> EditorExportPlatform::get_exported_file(String& p_fname) const { Ref<EditorExportPlatform> ep=EditorImportExport::get_singleton()->get_export_platform(get_name()); for(int i=0;i<EditorImportExport::get_singleton()->get_export_plugin_count();i++) { Vector<uint8_t> data = EditorImportExport::get_singleton()->get_export_plugin(i)->custom_export(p_fname,ep); if (data.size()) return data; } FileAccess *f = FileAccess::open(p_fname,FileAccess::READ); ERR_FAIL_COND_V(!f,Vector<uint8_t>()); Vector<uint8_t> ret; ret.resize(f->get_len()); int rbs = f->get_buffer(ret.ptr(),ret.size()); memdelete(f); return ret; }
Error read_all_file_utf8(const String &p_path, String &r_content) { PoolVector<uint8_t> sourcef; Error err; FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err); ERR_FAIL_COND_V(err != OK, err); int len = f->get_len(); sourcef.resize(len + 1); PoolVector<uint8_t>::Write w = sourcef.write(); int r = f->get_buffer(w.ptr(), len); f->close(); memdelete(f); ERR_FAIL_COND_V(r != len, ERR_CANT_OPEN); w[len] = 0; String source; if (source.parse_utf8((const char *)w.ptr())) { ERR_FAIL_V(ERR_INVALID_DATA); } r_content = source; return OK; }
void StreamPeerMbedTLS::initialize_ssl() { _create = _create_func; load_certs_func = _load_certs; mbedtls_x509_crt_init(&cacert); #ifdef DEBUG_ENABLED mbedtls_debug_set_threshold(1); #endif String certs_path = GLOBAL_DEF("network/ssl/certificates", ""); ProjectSettings::get_singleton()->set_custom_property_info("network/ssl/certificates", PropertyInfo(Variant::STRING, "network/ssl/certificates", PROPERTY_HINT_FILE, "*.crt")); if (certs_path != "") { FileAccess *f = FileAccess::open(certs_path, FileAccess::READ); if (f) { PoolByteArray arr; int flen = f->get_len(); arr.resize(flen + 1); { PoolByteArray::Write w = arr.write(); f->get_buffer(w.ptr(), flen); w[flen] = 0; //end f string } memdelete(f); _load_certs(arr); print_line("Loaded certs from '" + certs_path); } } available = true; }
Error DynamicFontAtSize::_load() { int error = FT_Init_FreeType(&library); ERR_EXPLAIN(TTR("Error initializing FreeType.")); ERR_FAIL_COND_V(error != 0, ERR_CANT_CREATE); // FT_OPEN_STREAM is extremely slow only on Android. if (OS::get_singleton()->get_name() == "Android" && font->font_mem == NULL && font->font_path != String()) { // cache font only once for each font->font_path if (_fontdata.has(font->font_path)) { font->set_font_ptr(_fontdata[font->font_path].ptr(), _fontdata[font->font_path].size()); } else { FileAccess *f = FileAccess::open(font->font_path, FileAccess::READ); ERR_FAIL_COND_V(!f, ERR_CANT_OPEN); size_t len = f->get_len(); _fontdata[font->font_path] = Vector<uint8_t>(); Vector<uint8_t> &fontdata = _fontdata[font->font_path]; fontdata.resize(len); f->get_buffer(fontdata.ptr(), len); font->set_font_ptr(fontdata.ptr(), len); f->close(); } } if (font->font_mem == NULL && font->font_path != String()) { FileAccess *f = FileAccess::open(font->font_path, FileAccess::READ); ERR_FAIL_COND_V(!f, ERR_CANT_OPEN); memset(&stream, 0, sizeof(FT_StreamRec)); stream.base = NULL; stream.size = f->get_len(); stream.pos = 0; stream.descriptor.pointer = f; stream.read = _ft_stream_io; stream.close = _ft_stream_close; FT_Open_Args fargs; memset(&fargs, 0, sizeof(FT_Open_Args)); fargs.flags = FT_OPEN_STREAM; fargs.stream = &stream; error = FT_Open_Face(library, &fargs, 0, &face); } else if (font->font_mem) { memset(&stream, 0, sizeof(FT_StreamRec)); stream.base = (unsigned char *)font->font_mem; stream.size = font->font_mem_size; stream.pos = 0; FT_Open_Args fargs; memset(&fargs, 0, sizeof(FT_Open_Args)); fargs.memory_base = (unsigned char *)font->font_mem; fargs.memory_size = font->font_mem_size; fargs.flags = FT_OPEN_MEMORY; fargs.stream = &stream; error = FT_Open_Face(library, &fargs, 0, &face); } else { ERR_EXPLAIN("DynamicFont uninitialized"); ERR_FAIL_V(ERR_UNCONFIGURED); } //error = FT_New_Face( library, src_path.utf8().get_data(),0,&face ); if (error == FT_Err_Unknown_File_Format) { ERR_EXPLAIN(TTR("Unknown font format.")); FT_Done_FreeType(library); } else if (error) { ERR_EXPLAIN(TTR("Error loading font.")); FT_Done_FreeType(library); } ERR_FAIL_COND_V(error, ERR_FILE_CANT_OPEN); /*error = FT_Set_Char_Size(face,0,64*size,512,512); if ( error ) { FT_Done_FreeType( library ); ERR_EXPLAIN(TTR("Invalid font size.")); ERR_FAIL_COND_V( error, ERR_INVALID_PARAMETER ); }*/ error = FT_Set_Pixel_Sizes(face, 0, id.size); ascent = face->size->metrics.ascender >> 6; descent = -face->size->metrics.descender >> 6; linegap = 0; texture_flags = 0; if (id.mipmaps) texture_flags |= Texture::FLAG_MIPMAPS; if (id.filter) texture_flags |= Texture::FLAG_FILTER; //print_line("ASCENT: "+itos(ascent)+" descent "+itos(descent)+" hinted: "+itos(face->face_flags&FT_FACE_FLAG_HINTER)); valid = true; return OK; }
Error EditorExportPlatformWindows::export_project(const String& p_path, bool p_debug, int p_flags) { Error err = EditorExportPlatformPC::export_project(p_path, p_debug, p_flags); if(err != OK) { return err; } EditorProgress ep("editexe","Edit EXE File",102); ep.step("Create ico file..",0); DVector<uint8_t> icon_content; if (this->icon_ico!="" && this->icon_ico.ends_with(".ico")) { FileAccess *f = FileAccess::open(this->icon_ico,FileAccess::READ); if (f) { icon_content.resize(f->get_len()); DVector<uint8_t>::Write write = icon_content.write(); f->get_buffer(write.ptr(),icon_content.size()); f->close(); memdelete(f); } } else if (this->icon_png!="" && this->icon_png.ends_with(".png") && (icon16 || icon32 || icon48 || icon64 || icon128 || icon256)) { #ifdef PNG_ENABLED Vector<Image> pngs; Image png; Error err_png = png.load(this->icon_png); if (err_png==OK && !png.empty()) { if(icon256) { Image icon_256(png); if(!(png.get_height()==256 && png.get_width()==256)) icon_256.resize(256,256); pngs.push_back(icon_256); } if(icon128) { Image icon_128(png); if(!(png.get_height()==128 && png.get_width()==128)) icon_128.resize(128,128); pngs.push_back(icon_128); } if(icon64) { Image icon_64(png); if(!(png.get_height()==64 && png.get_width()==64)) icon_64.resize(64,64); pngs.push_back(icon_64); } if(icon48) { Image icon_48(png); if(!(png.get_height()==48 && png.get_width()==48)) icon_48.resize(48,48); pngs.push_back(icon_48); } if(icon32) { Image icon_32(png); if(!(png.get_height()==32 && png.get_width()==32)) icon_32.resize(32,32); pngs.push_back(icon_32); } if(icon16) { Image icon_16(png); if(!(png.get_height()==16 && png.get_width()==16)) icon_16.resize(16,16); pngs.push_back(icon_16); } // create icon according to https://www.daubnet.com/en/file-format-ico store_16(icon_content,0); //Reserved store_16(icon_content,1); //Type store_16(icon_content,pngs.size()); //Count int offset = 6+pngs.size()*16; //List of bitmaps for(int i=0;i<pngs.size();i++) { int w = pngs[i].get_width(); int h = pngs[i].get_height(); icon_content.push_back(w<256?w:0); //width icon_content.push_back(h<256?h:0); //height icon_content.push_back(0); //ColorCount = 0 icon_content.push_back(0); //Reserved store_16(icon_content,1); //Planes store_16(icon_content,32); //BitCount (bit per pixel) int size = 40 + (w * h * 4) + (w * h / 8); store_32(icon_content,size); //Size of (InfoHeader + ANDbitmap + XORbitmap) store_32(icon_content,offset); //FileOffset offset += size; } //Write bmp files. for(int i=0;i<pngs.size();i++) { int w = pngs[i].get_width(); int h = pngs[i].get_height(); store_32(icon_content,40); //Size of InfoHeader structure = 40 store_32(icon_content,w); //Width store_32(icon_content,h*2); //Height store_16(icon_content,1); //Planes store_16(icon_content,32); //BitCount store_32(icon_content,0); //Compression store_32(icon_content,w*h*4); //ImageSize = Size of Image in Bytes store_32(icon_content,0); //unused = 0 store_32(icon_content,0); //unused = 0 store_32(icon_content,0); //unused = 0 store_32(icon_content,0); //unused = 0 //XORBitmap for(int y=h-1;y>=0;y--) { for(int x=0;x<w;x++) { store_32(icon_content,pngs[i].get_pixel(x,y).to_32()); } } //ANDBitmap for(int m=0;m<(w * h / 8);m+=4) store_32(icon_content,0x00000000); // Add empty ANDBitmap , TODO create full ANDBitmap Structure if need. } } #endif } ep.step("Add rsrc..",50); String basename = Globals::get_singleton()->get("application/name"); product_name=product_name.replace("$genname",basename); String godot_version; if(set_godot_version) godot_version = String( VERSION_MKSTRING ); String ret = pe_bliss_add_resrc(p_path.utf8(), version_major, version_minor, company_name, file_description, legal_copyright, version_text, product_name, godot_version, icon_content); if (ret.empty()) { return OK; } else { EditorNode::add_io_error(ret); return ERR_FILE_CANT_WRITE; } }
void ImageLoaderPNG::_read_png_data(png_structp png_ptr, png_bytep data, png_size_t p_length) { FileAccess *f = (FileAccess *)png_get_io_ptr(png_ptr); f->get_buffer((uint8_t *)data, p_length); }
MainLoop* test() { print_line("this is test io"); DirAccess* da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); da->change_dir("."); print_line("Opening current dir "+ da->get_current_dir()); String entry; da->list_dir_begin(); while ( (entry = da->get_next()) != "") { print_line("entry "+entry+" is dir: " + Variant(da->current_is_dir())); }; da->list_dir_end(); RES texture = ResourceLoader::load("test_data/rock.png"); ERR_FAIL_COND_V(texture.is_null(), NULL); ResourceSaver::save("test_data/rock.xml",texture); print_line("localize paths"); print_line(Globals::get_singleton()->localize_path("algo.xml")); print_line(Globals::get_singleton()->localize_path("c:\\windows\\algo.xml")); print_line(Globals::get_singleton()->localize_path(Globals::get_singleton()->get_resource_path()+"/something/something.xml")); print_line(Globals::get_singleton()->localize_path("somedir/algo.xml")); { FileAccess* z = FileAccess::open("test_data/archive.zip", FileAccess::READ); int len = z->get_len(); Vector<uint8_t> zip; zip.resize(len); z->get_buffer(&zip[0], len); z->close(); memdelete(z); FileAccessMemory::register_file("a_package", zip); FileAccess::make_default<FileAccessMemory>(FileAccess::ACCESS_RESOURCES); FileAccess::make_default<FileAccessMemory>(FileAccess::ACCESS_FILESYSTEM); FileAccess::make_default<FileAccessMemory>(FileAccess::ACCESS_USERDATA); print_line("archive test"); #if 0 Archive arch; Archive::get_singleton()->add_package("a_package"); FileAccessArchive f; print_line("opening for read"); f._open("file.txt", FileAccess::READ); int pos = f.get_pos(); printf("file has %i bytes, initial pos %i\n", (int)f.get_len(), pos); do { printf("%c", f.get_8()); } while (!f.eof_reached()); print_line("opening for stored seek"); f.open("seek.bin", FileAccess::READ); pos = f.get_pos(); printf("byte at pos %i is %i\n", pos, (int)f.get_8()); f.seek(128); pos = f.get_pos(); printf("byte at pos %i is %i\n", pos, (int)f.get_8()); print_line("opening for deflated seek"); f.open("seek_deflated.bin", FileAccess::READ); pos = f.get_pos(); printf("byte at pos %i is %i\n", pos, (int)f.get_8()); f.seek(128); pos = f.get_pos(); printf("byte at pos %i is %i\n", pos, (int)f.get_8()); pos = f.get_pos(); printf("byte at pos %i is %i\n", pos, (int)f.get_8()); pos = f.get_pos(); printf("byte at pos %i is %i\n", pos, (int)f.get_8()); f.seek(256); pos = f.get_pos(); printf("byte at pos %i is %i\n", pos, (int)f.get_8()); pos = f.get_pos(); printf("byte at pos %i is %i\n", pos, (int)f.get_8()); pos = f.get_pos(); printf("byte at pos %i is %i\n", pos, (int)f.get_8()); f.seek(4); pos = f.get_pos(); printf("byte at pos %i is %i\n", pos, (int)f.get_8()); pos = f.get_pos(); printf("byte at pos %i is %i\n", pos, (int)f.get_8()); pos = f.get_pos(); printf("byte at pos %i is %i\n", pos, (int)f.get_8()); f.close(); DirAccessArchive d; String dir = "../blah1/blah2/blahask/../blah3/.//blah4/"; printf("changing dir to %s\n", dir.utf8().get_data()); d.change_dir(dir); printf("current dir is %s\n", d.get_current_dir().utf8().get_data()); FileAccessMemory::cleanup(); #endif }; print_line("test done"); return memnew( TestMainLoop ); }
MainLoop *test(TestType p_type) { List<String> cmdlargs = OS::get_singleton()->get_cmdline_args(); if (cmdlargs.empty()) { //try editor! return NULL; } String test = cmdlargs.back()->get(); FileAccess *fa = FileAccess::open(test, FileAccess::READ); if (!fa) { ERR_EXPLAIN("Could not open file: " + test); ERR_FAIL_V(NULL); } Vector<uint8_t> buf; int flen = fa->get_len(); buf.resize(fa->get_len() + 1); fa->get_buffer(buf.ptrw(), flen); buf.write[flen] = 0; String code; code.parse_utf8((const char *)&buf[0]); Vector<String> lines; int last = 0; for (int i = 0; i <= code.length(); i++) { if (code[i] == '\n' || code[i] == 0) { lines.push_back(code.substr(last, i - last)); last = i + 1; } } if (p_type == TEST_TOKENIZER) { GDScriptTokenizerText tk; tk.set_code(code); int line = -1; while (tk.get_token() != GDScriptTokenizer::TK_EOF) { String text; if (tk.get_token() == GDScriptTokenizer::TK_IDENTIFIER) text = "'" + tk.get_token_identifier() + "' (identifier)"; else if (tk.get_token() == GDScriptTokenizer::TK_CONSTANT) { Variant c = tk.get_token_constant(); if (c.get_type() == Variant::STRING) text = "\"" + String(c) + "\""; else text = c; text = text + " (" + Variant::get_type_name(c.get_type()) + " constant)"; } else if (tk.get_token() == GDScriptTokenizer::TK_ERROR) text = "ERROR: " + tk.get_token_error(); else if (tk.get_token() == GDScriptTokenizer::TK_NEWLINE) text = "newline (" + itos(tk.get_token_line()) + ") + indent: " + itos(tk.get_token_line_indent()); else if (tk.get_token() == GDScriptTokenizer::TK_BUILT_IN_FUNC) text = "'" + String(GDScriptFunctions::get_func_name(tk.get_token_built_in_func())) + "' (built-in function)"; else text = tk.get_token_name(tk.get_token()); if (tk.get_token_line() != line) { int from = line + 1; line = tk.get_token_line(); for (int i = from; i <= line; i++) { int l = i - 1; if (l >= 0 && l < lines.size()) { print_line("\n" + itos(i) + ": " + lines[l] + "\n"); } } } print_line("\t(" + itos(tk.get_token_column()) + "): " + text); tk.advance(); } } if (p_type == TEST_PARSER) { GDScriptParser parser; Error err = parser.parse(code); if (err) { print_line("Parse Error:\n" + itos(parser.get_error_line()) + ":" + itos(parser.get_error_column()) + ":" + parser.get_error()); memdelete(fa); return NULL; } const GDScriptParser::Node *root = parser.get_parse_tree(); ERR_FAIL_COND_V(root->type != GDScriptParser::Node::TYPE_CLASS, NULL); const GDScriptParser::ClassNode *cnode = static_cast<const GDScriptParser::ClassNode *>(root); _parser_show_class(cnode, 0, lines); } if (p_type == TEST_COMPILER) { GDScriptParser parser; Error err = parser.parse(code); if (err) { print_line("Parse Error:\n" + itos(parser.get_error_line()) + ":" + itos(parser.get_error_column()) + ":" + parser.get_error()); memdelete(fa); return NULL; } GDScript *script = memnew(GDScript); GDScriptCompiler gdc; err = gdc.compile(&parser, script); if (err) { print_line("Compile Error:\n" + itos(gdc.get_error_line()) + ":" + itos(gdc.get_error_column()) + ":" + gdc.get_error()); memdelete(script); return NULL; } Ref<GDScript> gds = Ref<GDScript>(script); Ref<GDScript> current = gds; while (current.is_valid()) { print_line("** CLASS **"); _disassemble_class(current, lines); current = current->get_base(); } } else if (p_type == TEST_BYTECODE) { Vector<uint8_t> buf = GDScriptTokenizerBuffer::parse_code_string(code); String dst = test.get_basename() + ".gdc"; FileAccess *fw = FileAccess::open(dst, FileAccess::WRITE); fw->store_buffer(buf.ptr(), buf.size()); memdelete(fw); } memdelete(fa); return NULL; }
Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) { String src_pkg_name; EditorProgress ep("export", "Exporting for OSX", 3); if (p_debug) src_pkg_name = p_preset->get("custom_package/debug"); else src_pkg_name = p_preset->get("custom_package/release"); if (src_pkg_name == "") { String err; src_pkg_name = find_export_template("osx.zip", &err); if (src_pkg_name == "") { EditorNode::add_io_error(err); return ERR_FILE_NOT_FOUND; } } FileAccess *src_f = NULL; zlib_filefunc_def io = zipio_create_io_from_file(&src_f); ep.step("Creating app", 0); unzFile src_pkg_zip = unzOpen2(src_pkg_name.utf8().get_data(), &io); if (!src_pkg_zip) { EditorNode::add_io_error("Could not find template app to export:\n" + src_pkg_name); return ERR_FILE_NOT_FOUND; } ERR_FAIL_COND_V(!src_pkg_zip, ERR_CANT_OPEN); int ret = unzGoToFirstFile(src_pkg_zip); String binary_to_use = "godot_osx_" + String(p_debug ? "debug" : "release") + "."; int bits_mode = p_preset->get("application/bits_mode"); binary_to_use += String(bits_mode == 0 ? "fat" : bits_mode == 1 ? "64" : "32"); print_line("binary: " + binary_to_use); String pkg_name; if (p_preset->get("application/name") != "") pkg_name = p_preset->get("application/name"); // app_name else if (String(ProjectSettings::get_singleton()->get("application/config/name")) != "") pkg_name = String(ProjectSettings::get_singleton()->get("application/config/name")); else pkg_name = "Unnamed"; Error err = OK; String tmp_app_path_name = ""; zlib_filefunc_def io2 = io; FileAccess *dst_f = NULL; io2.opaque = &dst_f; zipFile dst_pkg_zip = NULL; if (use_dmg()) { // We're on OSX so we can export to DMG, but first we create our application bundle tmp_app_path_name = EditorSettings::get_singleton()->get_cache_dir().plus_file(pkg_name + ".app"); print_line("Exporting to " + tmp_app_path_name); DirAccess *tmp_app_path = DirAccess::create_for_path(tmp_app_path_name); if (!tmp_app_path) { err = ERR_CANT_CREATE; } // Create our folder structure or rely on unzip? if (err == OK) { print_line("Creating " + tmp_app_path_name + "/Contents/MacOS"); err = tmp_app_path->make_dir_recursive(tmp_app_path_name + "/Contents/MacOS"); } if (err == OK) { print_line("Creating " + tmp_app_path_name + "/Contents/Resources"); err = tmp_app_path->make_dir_recursive(tmp_app_path_name + "/Contents/Resources"); } } else { // Open our destination zip file dst_pkg_zip = zipOpen2(p_path.utf8().get_data(), APPEND_STATUS_CREATE, NULL, &io2); if (!dst_pkg_zip) { err = ERR_CANT_CREATE; } } // Now process our template bool found_binary = false; int total_size = 0; while (ret == UNZ_OK && err == OK) { bool is_execute = false; //get filename unz_file_info info; char fname[16384]; ret = unzGetCurrentFileInfo(src_pkg_zip, &info, fname, 16384, NULL, 0, NULL, 0); String file = fname; print_line("READ: " + file); Vector<uint8_t> data; data.resize(info.uncompressed_size); //read unzOpenCurrentFile(src_pkg_zip); unzReadCurrentFile(src_pkg_zip, data.ptr(), data.size()); unzCloseCurrentFile(src_pkg_zip); //write file = file.replace_first("osx_template.app/", ""); if (file == "Contents/Info.plist") { print_line("parse plist"); _fix_plist(p_preset, data, pkg_name); } if (file.begins_with("Contents/MacOS/godot_")) { if (file != "Contents/MacOS/" + binary_to_use) { ret = unzGoToNextFile(src_pkg_zip); continue; //ignore! } found_binary = true; is_execute = true; file = "Contents/MacOS/" + pkg_name; } if (file == "Contents/Resources/icon.icns") { //see if there is an icon String iconpath; if (p_preset->get("application/icon") != "") iconpath = p_preset->get("application/icon"); else iconpath = ProjectSettings::get_singleton()->get("application/config/icon"); print_line("icon? " + iconpath); if (iconpath != "") { Ref<Image> icon; icon.instance(); icon->load(iconpath); if (!icon->empty()) { print_line("loaded?"); _make_icon(icon, data); } } //bleh? } if (data.size() > 0) { print_line("ADDING: " + file + " size: " + itos(data.size())); total_size += data.size(); if (use_dmg()) { // write it into our application bundle file = tmp_app_path_name + "/" + file; // write the file, need to add chmod FileAccess *f = FileAccess::open(file, FileAccess::WRITE); if (f) { f->store_buffer(data.ptr(), data.size()); f->close(); if (is_execute) { // Chmod with 0755 if the file is executable f->_chmod(file, 0755); } memdelete(f); } else { err = ERR_CANT_CREATE; } } else { // add it to our zip file file = pkg_name + ".app/" + file; zip_fileinfo fi; fi.tmz_date.tm_hour = info.tmu_date.tm_hour; fi.tmz_date.tm_min = info.tmu_date.tm_min; fi.tmz_date.tm_sec = info.tmu_date.tm_sec; fi.tmz_date.tm_mon = info.tmu_date.tm_mon; fi.tmz_date.tm_mday = info.tmu_date.tm_mday; fi.tmz_date.tm_year = info.tmu_date.tm_year; fi.dosDate = info.dosDate; fi.internal_fa = info.internal_fa; fi.external_fa = info.external_fa; int zerr = zipOpenNewFileInZip(dst_pkg_zip, file.utf8().get_data(), &fi, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION); print_line("OPEN ERR: " + itos(zerr)); zerr = zipWriteInFileInZip(dst_pkg_zip, data.ptr(), data.size()); print_line("WRITE ERR: " + itos(zerr)); zipCloseFileInZip(dst_pkg_zip); } } ret = unzGoToNextFile(src_pkg_zip); } // we're done with our source zip unzClose(src_pkg_zip); if (!found_binary) { ERR_PRINTS("Requested template binary '" + binary_to_use + "' not found. It might be missing from your template archive."); err = ERR_FILE_NOT_FOUND; } if (err == OK) { ep.step("Making PKG", 1); if (use_dmg()) { String pack_path = tmp_app_path_name + "/Contents/Resources/" + pkg_name + ".pck"; err = save_pack(p_preset, pack_path); // see if we can code sign our new package String identity = p_preset->get("codesign/identity"); if (err == OK && identity != "") { ep.step("Code signing bundle", 2); // the order in which we code sign is important, this is a bit of a shame or we could do this in our loop that extracts the files from our ZIP // start with our application err = _code_sign(p_preset, tmp_app_path_name + "/Contents/MacOS/" + pkg_name); ///@TODO we should check the contents of /Contents/Frameworks for frameworks to sign } if (err == OK && identity != "") { // we should probably loop through all resources and sign them? err = _code_sign(p_preset, tmp_app_path_name + "/Contents/Resources/icon.icns"); } if (err == OK && identity != "") { err = _code_sign(p_preset, pack_path); } if (err == OK && identity != "") { err = _code_sign(p_preset, tmp_app_path_name + "/Contents/Info.plist"); } // and finally create a DMG if (err == OK) { ep.step("Making DMG", 3); err = _create_dmg(p_path, pkg_name, tmp_app_path_name); } // Clean up temporary .app dir OS::get_singleton()->move_to_trash(tmp_app_path_name); } else { String pack_path = EditorSettings::get_singleton()->get_cache_dir().plus_file(pkg_name + ".pck"); Error err = save_pack(p_preset, pack_path); if (err == OK) { zipOpenNewFileInZip(dst_pkg_zip, (pkg_name + ".app/Contents/Resources/" + pkg_name + ".pck").utf8().get_data(), NULL, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION); FileAccess *pf = FileAccess::open(pack_path, FileAccess::READ); if (pf) { const int BSIZE = 16384; uint8_t buf[BSIZE]; while (true) { int r = pf->get_buffer(buf, BSIZE); if (r <= 0) break; zipWriteInFileInZip(dst_pkg_zip, buf, r); } zipCloseFileInZip(dst_pkg_zip); memdelete(pf); } else { err = ERR_CANT_OPEN; } } } } if (dst_pkg_zip) { zipClose(dst_pkg_zip, NULL); } return OK; }
static uLong godot_read(void* data, void* fdata, void* buf, uLong size) { FileAccess* f = (FileAccess*)data; f->get_buffer((uint8_t*)buf, size); return size; };
Error EditorExportPlatformOSX::export_project(const String& p_path, bool p_debug, bool p_dumb) { String src_pkg; EditorProgress ep("export","Exporting for OSX",104); String pkg_path = EditorSettings::get_singleton()->get_settings_path()+"/templates/osx.zip"; if (p_debug) { src_pkg=custom_debug_package!=""?custom_debug_package:pkg_path; } else { src_pkg=custom_release_package!=""?custom_release_package:pkg_path; } FileAccess *src_f=NULL; zlib_filefunc_def io = zipio_create_io_from_file(&src_f); ep.step("Creating app",0); unzFile pkg = unzOpen2(src_pkg.utf8().get_data(), &io); if (!pkg) { EditorNode::add_io_error("Could not find template app to export:\n"+src_pkg); return ERR_FILE_NOT_FOUND; } ERR_FAIL_COND_V(!pkg, ERR_CANT_OPEN); int ret = unzGoToFirstFile(pkg); zlib_filefunc_def io2=io; FileAccess *dst_f=NULL; io2.opaque=&dst_f; zipFile dpkg=zipOpen2(p_path.utf8().get_data(),APPEND_STATUS_CREATE,NULL,&io2); String binary_to_use="godot_osx_"+String(p_debug?"debug":"release")+"."+String(use64?"64":"32"); print_line("binary: "+binary_to_use); String pkg_name; if (app_name!="") pkg_name=app_name; else if (String(Globals::get_singleton()->get("application/name"))!="") pkg_name=String(Globals::get_singleton()->get("application/name")); else pkg_name="Unnamed"; while(ret==UNZ_OK) { //get filename unz_file_info info; char fname[16384]; ret = unzGetCurrentFileInfo(pkg,&info,fname,16384,NULL,0,NULL,0); String file=fname; print_line("READ: "+file); Vector<uint8_t> data; data.resize(info.uncompressed_size); //read unzOpenCurrentFile(pkg); unzReadCurrentFile(pkg,data.ptr(),data.size()); unzCloseCurrentFile(pkg); //write file = file.replace_first("osx_template.app/",""); if (file=="Contents/Info.plist") { print_line("parse plist"); _fix_plist(data,pkg_name); } if (file.begins_with("Contents/MacOS/godot_")) { if (file!="Contents/MacOS/"+binary_to_use) { ret = unzGoToNextFile(pkg); continue; //ignore! } file="Contents/MacOS/"+pkg_name; } if (file=="Contents/Resources/icon.icns") { //see if there is an icon String iconpath = Globals::get_singleton()->get("application/icon"); print_line("icon? "+iconpath); if (iconpath!="") { Image icon; icon.load(iconpath); if (!icon.empty()) { print_line("loaded?"); _make_icon(icon,data); } } //bleh? } file=pkg_name+".app/"+file; if (data.size()>0) { print_line("ADDING: "+file+" size: "+itos(data.size())); zip_fileinfo fi; fi.tmz_date.tm_hour=info.tmu_date.tm_hour; fi.tmz_date.tm_min=info.tmu_date.tm_min; fi.tmz_date.tm_sec=info.tmu_date.tm_sec; fi.tmz_date.tm_mon=info.tmu_date.tm_mon; fi.tmz_date.tm_mday=info.tmu_date.tm_mday; fi.tmz_date.tm_year=info.tmu_date.tm_year; fi.dosDate=info.dosDate; fi.internal_fa=info.internal_fa; fi.external_fa=info.external_fa; int err = zipOpenNewFileInZip(dpkg, file.utf8().get_data(), &fi, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION); print_line("OPEN ERR: "+itos(err)); err = zipWriteInFileInZip(dpkg,data.ptr(),data.size()); print_line("WRITE ERR: "+itos(err)); zipCloseFileInZip(dpkg); } ret = unzGoToNextFile(pkg); } ep.step("Making PKG",1); String pack_path=EditorSettings::get_singleton()->get_settings_path()+"/tmp/data.pck"; FileAccess *pfs = FileAccess::open(pack_path,FileAccess::WRITE); Error err = save_pack(pfs); memdelete(pfs); if (err) { zipClose(dpkg,NULL); unzClose(pkg); return err; } { //write datapack int err = zipOpenNewFileInZip(dpkg, (pkg_name+".app/Contents/Resources/data.pck").utf8().get_data(), NULL, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_DEFAULT_COMPRESSION); FileAccess *pf = FileAccess::open(pack_path,FileAccess::READ); ERR_FAIL_COND_V(!pf,ERR_CANT_OPEN); const int BSIZE = 16384; uint8_t buf[BSIZE]; while(true) { int r = pf->get_buffer(buf,BSIZE); if (r<=0) break; zipWriteInFileInZip(dpkg,buf,r); } zipCloseFileInZip(dpkg); memdelete(pf); } zipClose(dpkg,NULL); unzClose(pkg); return OK; }
Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &flags, Image &image, int p_size_limit) { FileAccess *f = FileAccess::open(p_path, FileAccess::READ); ERR_FAIL_COND_V(!f, ERR_CANT_OPEN); uint8_t header[4]; f->get_buffer(header, 4); if (header[0] != 'G' || header[1] != 'D' || header[2] != 'S' || header[3] != 'T') { memdelete(f); ERR_FAIL_COND_V(header[0] != 'G' || header[1] != 'D' || header[2] != 'S' || header[3] != 'T', ERR_FILE_CORRUPT); } tw = f->get_32(); th = f->get_32(); flags = f->get_32(); //texture flags! uint32_t df = f->get_32(); //data format print_line("width: " + itos(tw)); print_line("height: " + itos(th)); print_line("flags: " + itos(flags)); print_line("df: " + itos(df)); if (request_3d_callback && df & FORMAT_BIT_DETECT_3D) { print_line("request detect 3D at " + p_path); VS::get_singleton()->texture_set_detect_3d_callback(texture, _requested_3d, this); } else { print_line("not requesting detect 3D at " + p_path); VS::get_singleton()->texture_set_detect_3d_callback(texture, NULL, NULL); } if (request_srgb_callback && df & FORMAT_BIT_DETECT_SRGB) { print_line("request detect srgb at " + p_path); VS::get_singleton()->texture_set_detect_srgb_callback(texture, _requested_srgb, this); } else { VS::get_singleton()->texture_set_detect_srgb_callback(texture, NULL, NULL); print_line("not requesting detect srgb at " + p_path); } if (!(df & FORMAT_BIT_STREAM)) { p_size_limit = 0; } if (df & FORMAT_BIT_LOSSLESS || df & FORMAT_BIT_LOSSY) { //look for a PNG or WEBP file inside int sw = tw; int sh = th; uint32_t mipmaps = f->get_32(); uint32_t size = f->get_32(); print_line("mipmaps: " + itos(mipmaps)); while (mipmaps > 1 && p_size_limit > 0 && (sw > p_size_limit || sh > p_size_limit)) { f->seek(f->get_pos() + size); mipmaps = f->get_32(); size = f->get_32(); sw = MAX(sw >> 1, 1); sh = MAX(sh >> 1, 1); mipmaps--; } //mipmaps need to be read independently, they will be later combined Vector<Image> mipmap_images; int total_size = 0; for (int i = 0; i < mipmaps; i++) { if (i > 0) { size = f->get_32(); } PoolVector<uint8_t> pv; pv.resize(size); { PoolVector<uint8_t>::Write w = pv.write(); f->get_buffer(w.ptr(), size); } Image img; if (df & FORMAT_BIT_LOSSLESS) { img = Image::lossless_unpacker(pv); } else { img = Image::lossy_unpacker(pv); } if (img.empty()) { memdelete(f); ERR_FAIL_COND_V(img.empty(), ERR_FILE_CORRUPT); } total_size += img.get_data().size(); mipmap_images.push_back(img); } print_line("mipmap read total: " + itos(mipmap_images.size())); memdelete(f); //no longer needed if (mipmap_images.size() == 1) { image = mipmap_images[0]; return OK; } else { PoolVector<uint8_t> img_data; img_data.resize(total_size); { PoolVector<uint8_t>::Write w = img_data.write(); int ofs = 0; for (int i = 0; i < mipmap_images.size(); i++) { PoolVector<uint8_t> id = mipmap_images[i].get_data(); int len = id.size(); PoolVector<uint8_t>::Read r = id.read(); copymem(&w[ofs], r.ptr(), len); ofs += len; } } image = Image(sw, sh, true, mipmap_images[0].get_format(), img_data); return OK; } } else {
Error PCKPacker::flush(bool p_verbose) { if (!file) { ERR_FAIL_COND_V(!file, ERR_INVALID_PARAMETER); return ERR_INVALID_PARAMETER; }; // write the index file->store_32(files.size()); for (int i=0; i<files.size(); i++) { file->store_pascal_string(files[i].path); files[i].offset_offset = file->get_pos(); file->store_64(0); // offset file->store_64(files[i].size); // size // # empty md5 file->store_32(0); file->store_32(0); file->store_32(0); file->store_32(0); }; uint64_t ofs = file->get_pos(); ofs = _align(ofs, alignment); _pad(file, ofs - file->get_pos()); const uint32_t buf_max = 65536; uint8_t *buf = memnew_arr(uint8_t, buf_max); int count = 0; for (int i=0; i<files.size(); i++) { FileAccess* src = FileAccess::open(files[i].src_path, FileAccess::READ); uint64_t to_write = files[i].size; while (to_write > 0) { int read = src->get_buffer(buf, MIN(to_write, buf_max)); file->store_buffer(buf, read); to_write -= read; }; uint64_t pos = file->get_pos(); file->seek(files[i].offset_offset); // go back to store the file's offset file->store_64(ofs); file->seek(pos); ofs = _align(ofs + files[i].size, alignment); _pad(file, ofs - pos); src->close(); memdelete(src); count += 1; if (p_verbose) { if (count % 100 == 0) { printf("%i/%i (%.2f)\r", count, files.size(), float(count) / files.size() * 100); fflush(stdout); }; }; }; if (p_verbose) printf("\n"); file->close(); return OK; };
RES ResourceFormatLoaderImage::load(const String &p_path, const String &p_original_path, Error *r_error) { FileAccess *f = FileAccess::open(p_path, FileAccess::READ); if (!f) { if (r_error) { *r_error = ERR_CANT_OPEN; } return RES(); } uint8_t header[4] = { 0, 0, 0, 0 }; f->get_buffer(header, 4); bool unrecognized = header[0] != 'G' || header[1] != 'D' || header[2] != 'I' || header[3] != 'M'; if (unrecognized) { memdelete(f); if (r_error) { *r_error = ERR_FILE_UNRECOGNIZED; } ERR_FAIL_V(RES()); } String extension = f->get_pascal_string(); int idx = -1; for (int i = 0; i < ImageLoader::loader.size(); i++) { if (ImageLoader::loader[i]->recognize(extension)) { idx = i; break; } } if (idx == -1) { memdelete(f); if (r_error) { *r_error = ERR_FILE_UNRECOGNIZED; } ERR_FAIL_V(RES()); } Ref<Image> image; image.instance(); Error err = ImageLoader::loader[idx]->load_image(image, f, false, 1.0); memdelete(f); if (err != OK) { if (r_error) { *r_error = err; } return RES(); } if (r_error) { *r_error = OK; } return image; }