long AudioStreamPlaybackOGGVorbis::_ov_tell_func(void *_f) {

	//printf("close %p\n",_f);

	FileAccess *fa = (FileAccess *)_f;
	return fa->get_position();
}
int AudioStreamPlaybackOGGVorbis::_ov_seek_func(void *_f, ogg_int64_t offs, int whence) {

	//printf("seek to %p, offs %i, whence %i\n",_f,(int)offs,whence);

#ifdef SEEK_SET
	//printf("seek set defined\n");
	FileAccess *fa = (FileAccess *)_f;

	if (whence == SEEK_SET) {

		fa->seek(offs);
	} else if (whence == SEEK_CUR) {

		fa->seek(fa->get_position() + offs);
	} else if (whence == SEEK_END) {

		fa->seek_end(offs);
	} else {

		ERR_PRINT("Vorbis seek function failure: Unexpected value in _whence\n");
	}
	int ret = fa->eof_reached() ? -1 : 0;
	//printf("returning %i\n",ret);
	return ret;

#else
	return -1; // no seeking
#endif
}
int64_t GDAPI godot_videodecoder_file_seek(void *ptr, int64_t pos, int whence) {
	// file
	FileAccess *file = reinterpret_cast<FileAccess *>(ptr);

	if (file) {
		size_t len = file->get_len();
		switch (whence) {
			case SEEK_SET: {
				// Just for explicitness
				size_t new_pos = static_cast<size_t>(pos);
				if (new_pos > len) {
					return -1;
				}
				file->seek(new_pos);
				pos = static_cast<int64_t>(file->get_position());
				return pos;
			} break;
			case SEEK_CUR: {
				// Just in case it doesn't exist
				if (pos < 0 && (size_t)-pos > file->get_position()) {
					return -1;
				}
				pos = pos + static_cast<int>(file->get_position());
				file->seek(pos);
				pos = static_cast<int64_t>(file->get_position());
				return pos;
			} break;
			case SEEK_END: {
				// Just in case something goes wrong
				if ((size_t)-pos > len) {
					return -1;
				}
				file->seek_end(pos);
				pos = static_cast<int64_t>(file->get_position());
				return pos;
			} break;
			default: {
				// Only 4 possible options, hence default = AVSEEK_SIZE
				// Asks to return the length of file
				return static_cast<int64_t>(len);
			} break;
		}
	}
	// In case nothing works out.
	return -1;
}
Beispiel #4
0
Error DirAccess::copy(String p_from, String p_to, int p_chmod_flags) {

	//printf("copy %s -> %s\n",p_from.ascii().get_data(),p_to.ascii().get_data());
	Error err;
	FileAccess *fsrc = FileAccess::open(p_from, FileAccess::READ, &err);

	if (err) {
		ERR_PRINTS("Failed to open " + p_from);
		return err;
	}

	FileAccess *fdst = FileAccess::open(p_to, FileAccess::WRITE, &err);
	if (err) {

		fsrc->close();
		memdelete(fsrc);
		ERR_PRINTS("Failed to open " + p_to);
		return err;
	}

	fsrc->seek_end(0);
	int size = fsrc->get_position();
	fsrc->seek(0);
	err = OK;
	while (size--) {

		if (fsrc->get_error() != OK) {
			err = fsrc->get_error();
			break;
		}
		if (fdst->get_error() != OK) {
			err = fdst->get_error();
			break;
		}

		fdst->store_8(fsrc->get_8());
	}

	if (err == OK && p_chmod_flags != -1) {
		fdst->close();
		err = FileAccess::set_unix_permissions(p_to, p_chmod_flags);
		// If running on a platform with no chmod support (i.e., Windows), don't fail
		if (err == ERR_UNAVAILABLE)
			err = OK;
	}

	memdelete(fsrc);
	memdelete(fdst);

	return err;
}
Beispiel #5
0
static long godot_seek(voidpf opaque, voidpf stream, uLong offset, int origin) {

	FileAccess *f = (FileAccess *)opaque;

	int pos = offset;
	switch (origin) {

		case ZLIB_FILEFUNC_SEEK_CUR:
			pos = f->get_position() + offset;
			break;
		case ZLIB_FILEFUNC_SEEK_END:
			pos = f->get_len() + offset;
			break;
		default:
			break;
	};

	f->seek(pos);
	return 0;
};
Beispiel #6
0
Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, const String &p_path, Vector<SharedObject> *p_so_files) {

	EditorProgress ep("savepack", TTR("Packing"), 102, true);

	String tmppath = EditorSettings::get_singleton()->get_cache_dir().plus_file("packtmp");
	FileAccess *ftmp = FileAccess::open(tmppath, FileAccess::WRITE);
	ERR_FAIL_COND_V(!ftmp, ERR_CANT_CREATE)

	PackData pd;
	pd.ep = &ep;
	pd.f = ftmp;
	pd.so_files = p_so_files;

	Error err = export_project_files(p_preset, _save_pack_file, &pd, _add_shared_object);

	memdelete(ftmp); //close tmp file

	if (err)
		return err;

	pd.file_ofs.sort(); //do sort, so we can do binary search later

	FileAccess *f = FileAccess::open(p_path, FileAccess::WRITE);
	ERR_FAIL_COND_V(!f, ERR_CANT_CREATE)
	f->store_32(0x43504447); //GDPK
	f->store_32(1); //pack version
	f->store_32(VERSION_MAJOR);
	f->store_32(VERSION_MINOR);
	f->store_32(0); //hmph
	for (int i = 0; i < 16; i++) {
		//reserved
		f->store_32(0);
	}

	f->store_32(pd.file_ofs.size()); //amount of files

	size_t header_size = f->get_position();

	//precalculate header size

	for (int i = 0; i < pd.file_ofs.size(); i++) {
		header_size += 4; // size of path string (32 bits is enough)
		uint32_t string_len = pd.file_ofs[i].path_utf8.length();
		header_size += string_len + _get_pad(4, string_len); ///size of path string
		header_size += 8; // offset to file _with_ header size included
		header_size += 8; // size of file
		header_size += 16; // md5
	}

	size_t header_padding = _get_pad(PCK_PADDING, header_size);

	for (int i = 0; i < pd.file_ofs.size(); i++) {

		uint32_t string_len = pd.file_ofs[i].path_utf8.length();
		uint32_t pad = _get_pad(4, string_len);
		;
		f->store_32(string_len + pad);
		f->store_buffer((const uint8_t *)pd.file_ofs[i].path_utf8.get_data(), string_len);
		for (uint32_t j = 0; j < pad; j++) {
			f->store_8(0);
		}

		f->store_64(pd.file_ofs[i].ofs + header_padding + header_size);
		f->store_64(pd.file_ofs[i].size); // pay attention here, this is where file is
		f->store_buffer(pd.file_ofs[i].md5.ptr(), 16); //also save md5 for file
	}

	for (uint32_t j = 0; j < header_padding; j++) {
		f->store_8(0);
	}

	//save the rest of the data

	ftmp = FileAccess::open(tmppath, FileAccess::READ);
	if (!ftmp) {
		memdelete(f);
		ERR_FAIL_COND_V(!ftmp, ERR_CANT_CREATE)
	}
Beispiel #7
0
static long godot_tell(voidpf opaque, voidpf stream) {

	FileAccess *f = (FileAccess *)opaque;
	return f->get_position();
};
Beispiel #8
0
Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &flags, Ref<Image> &image, int p_size_limit) {

	ERR_FAIL_COND_V(image.is_null(), ERR_INVALID_PARAMETER);

	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));
	*/
#ifdef TOOLS_ENABLED

	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 {
		//print_line("not requesting detect srgb at " + p_path);
		VS::get_singleton()->texture_set_detect_srgb_callback(texture, NULL, NULL);
	}

	if (request_srgb_callback && df & FORMAT_BIT_DETECT_NORMAL) {
		//print_line("request detect srgb at " + p_path);
		VS::get_singleton()->texture_set_detect_normal_callback(texture, _requested_normal, this);
	} else {
		//print_line("not requesting detect normal at " + p_path);
		VS::get_singleton()->texture_set_detect_normal_callback(texture, NULL, NULL);
	}
#endif
	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_position() + 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<Ref<Image> > mipmap_images;
		int total_size = 0;

		for (uint32_t i = 0; i < mipmaps; i++) {

			if (i) {
				size = f->get_32();
			}

			PoolVector<uint8_t> pv;
			pv.resize(size);
			{
				PoolVector<uint8_t>::Write w = pv.write();
				f->get_buffer(w.ptr(), size);
			}

			Ref<Image> img;
			if (df & FORMAT_BIT_LOSSLESS) {
				img = Image::lossless_unpacker(pv);
			} else {
				img = Image::lossy_unpacker(pv);
			}

			if (img.is_null() || img->empty()) {
				memdelete(f);
				ERR_FAIL_COND_V(img.is_null() || 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->create(sw, sh, true, mipmap_images[0]->get_format(), img_data);
			return OK;
		}

	} else {