add ability to view remote image file

This commit is contained in:
Chee Yee
2023-04-04 20:39:10 -07:00
parent 4ea584e092
commit 4aabf850b8
11 changed files with 238 additions and 45 deletions
+1
View File
@@ -52,6 +52,7 @@ add_executable(ezremote_client
source/main.cpp
source/orbis_jbc.c
source/system.cpp
source/sfo.cpp
source/textures.cpp
source/windows.cpp
source/zip_util.cpp
+4 -1
View File
@@ -53,7 +53,10 @@ enum ACTIONS
ACTION_NEW_REMOTE_FILE,
ACTION_SET_DEFAULT_LOCAL_FOLDER,
ACTION_SET_DEFAULT_REMOTE_FOLDER,
ACTION_VIEW_IMAGE
ACTION_VIEW_LOCAL_IMAGE,
ACTION_VIEW_REMOTE_IMAGE,
ACTION_VIEW_LOCAL_PKG,
ACTION_VIEW_REMOTE_PKG
};
enum OverWriteType
+4
View File
@@ -28,6 +28,8 @@ char display_site[32];
char language[128];
std::vector<std::string> sites;
std::vector<std::string> http_servers;
std::set<std::string> text_file_extensions;
std::set<std::string> image_file_extensions;
std::map<std::string, RemoteSettings> site_settings;
PackageUrlInfo install_pkg_url;
char favorite_urls[MAX_FAVORITE_URLS][512];
@@ -142,6 +144,8 @@ namespace CONFIG
"Site 11", "Site 12", "Site 13", "Site 14", "Site 15", "Site 16", "Site 17", "Site 18", "Site 19", "Site 20"};
http_servers = {HTTP_SERVER_APACHE, HTTP_SERVER_MS_IIS, HTTP_SERVER_NGINX, HTTP_SERVER_NPX_SERVE};
text_file_extensions = { ".txt", ".ini", ".json", ".xml", ".html", ".xhtml", ".conf" };
image_file_extensions = { ".bmp", ".jpg", ".jpeg", ".png", ".webp" };
OpenIniFile(CONFIG_INI_FILE);
+5
View File
@@ -6,6 +6,7 @@
#include <string>
#include <algorithm>
#include <map>
#include <set>
#include "clients/remote_client.h"
@@ -14,6 +15,8 @@
#define CONFIG_INI_FILE DATA_PATH "/config.ini"
#define COOKIE_FILE DATA_PATH "/cookies.txt"
#define TMP_EDITOR_FILE DATA_PATH "/tmp_editor.txt"
#define TMP_SFO_PATH DATA_PATH "/tmp_pkg.sfo"
#define TMP_ICON_PATH DATA_PATH "/tmp_icon.png"
#define CONFIG_GLOBAL "Global"
@@ -110,6 +113,8 @@ struct PackageUrlInfo
extern std::vector<std::string> sites;
extern std::vector<std::string> http_servers;
extern std::set<std::string> text_file_extensions;
extern std::set<std::string> image_file_extensions;
extern std::map<std::string, RemoteSettings> site_settings;
extern char local_directory[255];
extern char remote_directory[255];
+81 -3
View File
@@ -116,7 +116,7 @@ namespace INSTALLER
path = uri.quote(curl);
curl_easy_cleanup(curl);
}
return host + path;
}
else
@@ -265,7 +265,8 @@ namespace INSTALLER
goto retry;
}
}
else if (ret > 0) goto err;
else if (ret > 0)
goto err;
ret = sceBgftServiceDownloadStartTask(task_id);
if (ret)
@@ -346,7 +347,8 @@ namespace INSTALLER
FS::Rm(filename);
}
}
else if (ret > 0) goto err;
else if (ret > 0)
goto err;
ret = sceBgftServiceDownloadStartTask(task_id);
if (ret)
@@ -380,4 +382,80 @@ namespace INSTALLER
err:
return 0;
}
bool ExtractLocalPkg(const std::string &filename, pkg_header *pkg_hdr, const std::string sfo_path, const std::string icon_path)
{
pkg_header tmp_hdr;
pkg_header *p_hdr = pkg_hdr;
if (p_hdr == nullptr)
{
FS::Head(filename, &tmp_hdr, sizeof(pkg_header));
p_hdr = &tmp_hdr;
}
size_t entry_count = BE32(p_hdr->pkg_entry_count);
uint32_t entry_table_offset = BE32(p_hdr->pkg_table_offset);
uint64_t entry_table_size = entry_count * sizeof(pkg_table_entry);
void *entry_table_data = malloc(entry_table_size);
FILE *fd = FS::OpenRead(filename);
FS::Seek(fd, entry_table_offset);
FS::Read(fd, entry_table_data, entry_table_size);
pkg_table_entry *entries = (pkg_table_entry *)entry_table_data;
void* param_sfo_data = NULL;
uint32_t param_sfo_offset = 0;
uint32_t param_sfo_size = 0;
void *icon0_png_data = NULL;
uint32_t icon0_png_offset = 0;
uint32_t icon0_png_size = 0;
short items = 0;
for (size_t i = 0; i < entry_count; ++i)
{
switch (BE32(entries[i].id))
{
case PKG_ENTRY_ID__PARAM_SFO:
param_sfo_offset = BE32(entries[i].offset);
param_sfo_size = BE32(entries[i].size);
items++;
break;
case PKG_ENTRY_ID__ICON0_PNG:
icon0_png_offset = BE32(entries[i].offset);
icon0_png_size = BE32(entries[i].size);
items++;
break;
default:
continue;
}
if (items == 2)
break;
}
free(entry_table_data);
if (param_sfo_offset > 0 && param_sfo_size > 0)
{
param_sfo_data = malloc(param_sfo_size);
FILE *out = FS::Create(sfo_path);
FS::Seek(fd, param_sfo_offset);
FS::Read(fd, param_sfo_data, param_sfo_size);
FS::Write(out, param_sfo_data, param_sfo_size);
FS::Close(out);
free(param_sfo_data);
}
if (icon0_png_offset > 0 && icon0_png_size > 0)
{
icon0_png_data = malloc(icon0_png_size);
FILE *out = FS::Create(icon_path);
FS::Seek(fd, icon0_png_offset);
FS::Read(fd, icon0_png_data, icon0_png_size);
FS::Write(out, icon0_png_data, icon0_png_size);
FS::Close(out);
free(icon0_png_data);
}
FS::Close(fd);
return true;
}
}
+40 -30
View File
@@ -1,30 +1,24 @@
#pragma once
#define SWAP16(x) \
((uint16_t)( \
(((uint16_t)(x) & UINT16_C(0x00FF)) << 8) | \
(((uint16_t)(x) & UINT16_C(0xFF00)) >> 8) \
))
#define SWAP16(x) \
((uint16_t)((((uint16_t)(x)&UINT16_C(0x00FF)) << 8) | \
(((uint16_t)(x)&UINT16_C(0xFF00)) >> 8)))
#define SWAP32(x) \
((uint32_t)( \
(((uint32_t)(x) & UINT32_C(0x000000FF)) << 24) | \
(((uint32_t)(x) & UINT32_C(0x0000FF00)) << 8) | \
(((uint32_t)(x) & UINT32_C(0x00FF0000)) >> 8) | \
(((uint32_t)(x) & UINT32_C(0xFF000000)) >> 24) \
))
#define SWAP32(x) \
((uint32_t)((((uint32_t)(x)&UINT32_C(0x000000FF)) << 24) | \
(((uint32_t)(x)&UINT32_C(0x0000FF00)) << 8) | \
(((uint32_t)(x)&UINT32_C(0x00FF0000)) >> 8) | \
(((uint32_t)(x)&UINT32_C(0xFF000000)) >> 24)))
#define SWAP64(x) \
((uint64_t)( \
(uint64_t)(((uint64_t)(x) & UINT64_C(0x00000000000000FF)) << 56) | \
(uint64_t)(((uint64_t)(x) & UINT64_C(0x000000000000FF00)) << 40) | \
(uint64_t)(((uint64_t)(x) & UINT64_C(0x0000000000FF0000)) << 24) | \
(uint64_t)(((uint64_t)(x) & UINT64_C(0x00000000FF000000)) << 8) | \
(uint64_t)(((uint64_t)(x) & UINT64_C(0x000000FF00000000)) >> 8) | \
(uint64_t)(((uint64_t)(x) & UINT64_C(0x0000FF0000000000)) >> 24) | \
(uint64_t)(((uint64_t)(x) & UINT64_C(0x00FF000000000000)) >> 40) | \
(uint64_t)(((uint64_t)(x) & UINT64_C(0xFF00000000000000)) >> 56) \
))
#define SWAP64(x) \
((uint64_t)((uint64_t)(((uint64_t)(x)&UINT64_C(0x00000000000000FF)) << 56) | \
(uint64_t)(((uint64_t)(x)&UINT64_C(0x000000000000FF00)) << 40) | \
(uint64_t)(((uint64_t)(x)&UINT64_C(0x0000000000FF0000)) << 24) | \
(uint64_t)(((uint64_t)(x)&UINT64_C(0x00000000FF000000)) << 8) | \
(uint64_t)(((uint64_t)(x)&UINT64_C(0x000000FF00000000)) >> 8) | \
(uint64_t)(((uint64_t)(x)&UINT64_C(0x0000FF0000000000)) >> 24) | \
(uint64_t)(((uint64_t)(x)&UINT64_C(0x00FF000000000000)) >> 40) | \
(uint64_t)(((uint64_t)(x)&UINT64_C(0xFF00000000000000)) >> 56)))
#define LE16(x) (x)
#define LE32(x) (x)
@@ -47,6 +41,9 @@
#define PKG_CONTENT_FLAGS_DELTA_PATCH 0x41000000
#define PKG_CONTENT_FLAGS_CUMULATIVE_PATCH 0x60000000
#define PKG_ENTRY_ID__PARAM_SFO 0x1000
#define PKG_ENTRY_ID__ICON0_PNG 0x1200
typedef struct
{
uint32_t pkg_magic; // 0x000 - 0x7F434E54
@@ -98,11 +95,23 @@ typedef struct
unsigned char pkg_digest[0x20]; // 0xFE0
} pkg_header;
enum pkg_content_type {
PKG_CONTENT_TYPE_GD = 0x1A, /* pkg_ps4_app, pkg_ps4_patch, pkg_ps4_remaster */
PKG_CONTENT_TYPE_AC = 0x1B, /* pkg_ps4_ac_data, pkg_ps4_sf_theme, pkg_ps4_theme */
PKG_CONTENT_TYPE_AL = 0x1C, /* pkg_ps4_ac_nodata */
PKG_CONTENT_TYPE_DP = 0x1E, /* pkg_ps4_delta_patch */
typedef struct
{
uint32_t id; // File ID, useful for files without a filename entry
uint32_t filename_offset; // Offset into the filenames table (ID 0x200) where this file's name is located
uint32_t flags1; // Flags including encrypted flag, etc
uint32_t flags2; // Flags including encryption key index, etc
uint32_t offset; // Offset into PKG to find the file
uint32_t size; // Size of the file
uint64_t padding; // blank padding
} pkg_table_entry;
enum pkg_content_type
{
PKG_CONTENT_TYPE_GD = 0x1A, /* pkg_ps4_app, pkg_ps4_patch, pkg_ps4_remaster */
PKG_CONTENT_TYPE_AC = 0x1B, /* pkg_ps4_ac_data, pkg_ps4_sf_theme, pkg_ps4_theme */
PKG_CONTENT_TYPE_AL = 0x1C, /* pkg_ps4_ac_nodata */
PKG_CONTENT_TYPE_DP = 0x1E, /* pkg_ps4_delta_patch */
};
namespace INSTALLER
@@ -111,7 +120,8 @@ namespace INSTALLER
void Exit(void);
bool canInstallRemotePkg(const std::string &url);
std::string getRemoteUrl(const std::string filename, bool encodeUrl=false);
std::string getRemoteUrl(const std::string filename, bool encodeUrl = false);
int InstallRemotePkg(const std::string &filename, pkg_header *header);
int InstallLocalPkg(const std::string &filename, pkg_header *header, bool remove_after_install=false);
int InstallLocalPkg(const std::string &filename, pkg_header *header, bool remove_after_install = false);
bool ExtractLocalPkg(const std::string &filename, pkg_header *pkg_header, const std::string sfo_path, const std::string icon_path);
}
+1 -2
View File
@@ -11,7 +11,7 @@
#include <orbis/Pad.h>
#include <orbis/AudioOut.h>
#include <orbis/Net.h>
#include <dbglogger.h>
// #include <dbglogger.h>
#include "imgui.h"
#include "SDL2/SDL.h"
@@ -26,7 +26,6 @@
#include "installer.h"
#include "system.h"
#include "textures.h"
// #include "dbglogger.h"
extern "C"
{
+30
View File
@@ -0,0 +1,30 @@
#include <cstring>
#include "sfo.h"
static constexpr uint32_t SFO_MAGIC = 0x46535000;
namespace SFO {
const char* GetString(const char* buffer, size_t size, const char *name)
{
if (size < sizeof(SfoHeader))
return nullptr;
const SfoHeader* header = reinterpret_cast<const SfoHeader*>(buffer);
const SfoEntry* entries =
reinterpret_cast<const SfoEntry*>(buffer + sizeof(SfoHeader));
if (header->magic != SFO_MAGIC)
return nullptr;
if (size < sizeof(SfoHeader) + header->count * sizeof(SfoEntry))
return nullptr;
for (uint32_t i = 0; i < header->count; i++) {
const char* key = reinterpret_cast<const char*>(buffer + header->keyofs + entries[i].nameofs);
if (strcmp(key, name) == 0)
return reinterpret_cast<const char*>(buffer + header->valofs + entries[i].dataofs);
}
return {};
}
}
+32
View File
@@ -0,0 +1,32 @@
#ifndef LAUNCHER_SFO_H
#define LAUNCHER_SFO_H
#pragma once
#include <cstdint>
#include <string>
struct SfoHeader
{
uint32_t magic;
uint32_t version;
uint32_t keyofs;
uint32_t valofs;
uint32_t count;
} __attribute__((packed));
struct SfoEntry
{
uint16_t nameofs;
uint8_t alignment;
uint8_t type;
uint32_t valsize;
uint32_t totalsize;
uint32_t dataofs;
} __attribute__((packed));
namespace SFO {
const char* GetString(const char* buffer, size_t size, const char *name);
}
#endif
+11 -4
View File
@@ -10,16 +10,23 @@ namespace Textures {
SDL_Surface *image = IMG_Load(filename.c_str());
if (image == nullptr)
return false;
image = SDL_ConvertSurfaceFormat(image, SDL_PIXELFORMAT_RGBA8888, 0);
SDL_Texture *sdl_texture = SDL_CreateTextureFromSurface(renderer, image);
SDL_Surface *formated_image = SDL_ConvertSurfaceFormat(image, SDL_PIXELFORMAT_RGBA8888, 0);
if (formated_image == nullptr)
{
SDL_FreeSurface(image);
}
SDL_Texture *sdl_texture = SDL_CreateTextureFromSurface(renderer, formated_image);
if (sdl_texture == nullptr)
{
SDL_FreeSurface(formated_image);
SDL_FreeSurface(image);
return false;
}
texture->id = sdl_texture;
texture->height = image->h;
texture->width = image->w;
texture->height = formated_image->h;
texture->width = formated_image->w;
SDL_FreeSurface(formated_image);
SDL_FreeSurface(image);
return true;
+29 -5
View File
@@ -587,10 +587,13 @@ namespace Windows
if (dot_pos != std::string::npos)
{
std::string ext = filename.substr(dot_pos);
if (ext.compare(".bmp") == 0 || ext.compare(".jpg") == 0 || ext.compare(".png") == 0 ||
ext.compare(".jpeg") == 0 || ext.compare(".webp") == 0)
if (image_file_extensions.find(ext) != image_file_extensions.end())
{
selected_action = ACTION_VIEW_IMAGE;
selected_action = ACTION_VIEW_LOCAL_IMAGE;
}
else if (ext.compare(".pkg") == 0)
{
INSTALLER::ExtractLocalPkg(selected_local_file.path, nullptr, TMP_SFO_PATH, TMP_ICON_PATH);
}
}
}
@@ -734,11 +737,24 @@ namespace Windows
ImGui::PushID(i);
if (ImGui::Selectable(item.name, false, ImGuiSelectableFlags_SpanAllColumns, ImVec2(919, 0)))
{
selected_remote_file = item;
if (item.isDir)
{
selected_remote_file = item;
selected_action = ACTION_CHANGE_REMOTE_DIRECTORY;
}
else
{
std::string filename = Util::ToLower(selected_remote_file.name);
size_t dot_pos = filename.find_last_of(".");
if (dot_pos != std::string::npos)
{
std::string ext = filename.substr(dot_pos);
if (image_file_extensions.find(ext) != image_file_extensions.end())
{
selected_action = ACTION_VIEW_REMOTE_IMAGE;
}
}
}
}
if (ImGui::IsItemFocused())
{
@@ -2022,13 +2038,21 @@ namespace Windows
sprintf(status_message, "\"%s\" %s", remote_directory, lang_strings[STR_SET_DEFAULT_DIRECTORY_MSG]);
selected_action = ACTION_NONE;
break;
case ACTION_VIEW_IMAGE:
case ACTION_VIEW_LOCAL_IMAGE:
if (Textures::LoadImageFile(selected_local_file.path, &texture))
{
view_image = true;
}
selected_action = ACTION_NONE;
break;
case ACTION_VIEW_REMOTE_IMAGE:
remoteclient->Get(TMP_ICON_PATH, selected_remote_file.path);
if (Textures::LoadImageFile(TMP_ICON_PATH, &texture))
{
view_image = true;
}
selected_action = ACTION_NONE;
break;
default:
break;
}