예제 #1
0
void Texture2dData::store(const util::Path& file) const {
	log::log(MSG(info) << "Saving texture data to " << file);

	if (this->info.get_format() != pixel_format::rgba8) {
		throw Error(MSG(err) << "Storing 2D textures into files is unimplemented. PRs welcome :D");
	}

	auto size = this->info.get_size();

// If an older SDL2 is used, we have to specify the format manually.
#ifndef SDL_PIXELFORMAT_RGBA32
	uint32_t rmask, gmask, bmask, amask;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
	rmask = 0xff000000;
	gmask = 0x00ff0000;
	bmask = 0x0000ff00;
	amask = 0x000000ff;
#else // little endian, like x86
	rmask = 0x000000ff;
	gmask = 0x0000ff00;
	bmask = 0x00ff0000;
	amask = 0xff000000;
#endif

	std::unique_ptr<SDL_Surface, decltype(&SDL_FreeSurface)> surf(
		SDL_CreateRGBSurfaceFrom(
			// const_cast is okay, because the surface doesn't modify data
			const_cast<void*>(static_cast<void const*>(this->data.data())),
			size.first,
			size.second,
			32,
			this->info.get_row_size(),
			rmask, gmask, bmask, amask
		),
		&SDL_FreeSurface
	);
#else
	std::unique_ptr<SDL_Surface, decltype(&SDL_FreeSurface)> surf(
		SDL_CreateRGBSurfaceWithFormatFrom(
			// const_cast is okay, because the surface doesn't modify data
			const_cast<void*>(static_cast<void const*>(this->data.data())),
			size.first,
			size.second,
			32,
			this->info.get_row_size(),
			SDL_PIXELFORMAT_RGBA32
		),
		&SDL_FreeSurface
	);
#endif

	// Call sdl_image for saving the screenshot to PNG
	std::string path = file.resolve_native_path_w();
	IMG_SavePNG(surf.get(), path.c_str());
}
예제 #2
0
opus_file_t open_opus_file(const util::Path &path) {
	if (not path.is_file()) {
		throw audio::Error{
			ERR << "Audio file not found: " << path
		};
	}

	opus_file_t op_file;
	int op_err = 0;

	//asm("int $3");

	// check if the file can be opened directly
	auto native_path = path.resolve_native_path();
	if (false && native_path.size() > 0) {

		op_file.handle = {
			op_open_file(native_path.c_str(), &op_err),
			opus_deleter
		};
	}
	else {
		// open the file and move the handle to the heap
		op_file.file = std::make_unique<util::File>();
		*op_file.file = path.open_r();

		op_file.handle = {
			op_open_callbacks(op_file.file.get(), &opus_access_funcs,
			                  nullptr, 0, &op_err),
			opus_deleter
		};
	}

	if (op_err != 0) {

		const char *reason;

		switch (op_err) {
		case OP_EREAD:
			reason = "read/seek/tell failed or data has changed"; break;
		case OP_EFAULT:
			reason = "opus failed to allocate memory "
			         "or something else bad happened internally"; break;
		case OP_EIMPL:
			reason = "Stream used an unsupported feature"; break;
		case OP_EINVAL:
			reason = "seek() worked, but tell() did not, "
			         "or initial_bytes != start seek pos"; break;
		case OP_ENOTFORMAT:
			reason = "Data didn't contain opus stream"; break;
		case OP_EBADHEADER:
			reason = "Header packet was invalid or missing"; break;
		case OP_EVERSION:
			reason = "ID header has unrecognized version"; break;
		case OP_EBADLINK:
			reason = "Data we already saw before seeking not found"; break;
		case OP_EBADTIMESTAMP:
			reason = "Validity check for first/last timestamp failed"; break;

		default:
			reason = "Unknown other error in opusfile"; break;
		}

		throw audio::Error{
			ERR
			<< "Could not open opus file: "
			<< path << " = '" << native_path << "': "
			<< reason
		};
	}
	return op_file;
}
예제 #3
0
Texture2dData::Texture2dData(const util::Path &path, bool use_metafile) {
	std::string native_path = path.resolve_native_path();
	std::unique_ptr<SDL_Surface, decltype(&SDL_FreeSurface)> surface(
		IMG_Load(native_path.c_str()),
		&SDL_FreeSurface
	);

	if (!surface) {
		throw Error(MSG(err)
		            << "Could not load texture from " << native_path
		            << ": " << IMG_GetError());
	}

	log::log(MSG(dbg) << "Texture has been loaded from " << native_path);

	auto surf_fmt = *surface->format;

	pixel_format pix_fmt;
	switch (surf_fmt.format) {
	case SDL_PIXELFORMAT_RGB24:
		pix_fmt = pixel_format::rgb8;
		break;
	case SDL_PIXELFORMAT_BGR24:
		pix_fmt = pixel_format::bgr8;
		break;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
	case SDL_PIXELFORMAT_RGBA8888:
#else
	case SDL_PIXELFORMAT_ABGR8888:
#endif
		pix_fmt = pixel_format::rgba8;
		break;
	default:
		throw Error(MSG(err) << "Texture " << native_path << " uses an unsupported format.");
	}

	auto w = uint32_t(surface->w);
	auto h = uint32_t(surface->h);

	size_t data_size = surf_fmt.BytesPerPixel * surface->w * surface->h;

	// copy pixel data from surface
	this->data = std::vector<uint8_t>(data_size);
	memcpy(this->data.data(), surface->pixels, data_size);

	std::vector<Texture2dSubInfo> subtextures;
	if (use_metafile) {
		util::Path meta = (path.get_parent() / path.get_stem()).with_suffix(".slp.docx");
		log::log(MSG(info) << "Loading meta file: " << meta);

		// get subtexture information by meta file exported by script
		subtextures = util::read_csv_file<Texture2dSubInfo>(meta);
	}
	else {
		// we don't have a texture description file.
		// use the whole image as one texture then.
		Texture2dSubInfo s{0, 0, w, h, w/2, h/2};

		subtextures.push_back(s);
	}

	size_t align = guess_row_alignment(w, pix_fmt, surface->pitch);
	this->info = Texture2dInfo(w, h, pix_fmt, align, std::move(subtextures));
}