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()); }
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; }
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)); }