diff --git a/Backends/System/Android/Sources/kinc/backend/system.c.h b/Backends/System/Android/Sources/kinc/backend/system.c.h index 656a19cf8..5e4fc3492 100644 --- a/Backends/System/Android/Sources/kinc/backend/system.c.h +++ b/Backends/System/Android/Sources/kinc/backend/system.c.h @@ -1251,23 +1251,43 @@ void initAndroidFileReader(void) { (*activity->vm)->DetachCurrentThread(activity->vm); } +static void kinc_aasset_reader_close(kinc_file_reader_t *reader) +{ + AAsset_close((struct AAsset *)reader->data); +} + +static size_t kinc_aasset_reader_read(kinc_file_reader_t *reader, void *data, size_t size) +{ + return AAsset_read((struct AAsset *)reader->data, data, size); +} + +static size_t kinc_aasset_reader_pos(kinc_file_reader_t *reader) +{ + return (size_t)AAsset_seek((struct AAsset *)reader->data, 0, SEEK_CUR); +} + +static void kinc_aasset_reader_seek(kinc_file_reader_t *reader, size_t pos) +{ + AAsset_seek((struct AAsset *)reader->data, pos, SEEK_SET); +} + bool kinc_file_reader_open(kinc_file_reader_t *reader, const char *filename, int type) { - reader->pos = 0; - reader->file = NULL; - reader->asset = NULL; + memset(reader, 0, sizeof(kinc_file_reader_t)); + reader->type = type; + if (type == KINC_FILE_TYPE_SAVE) { char filepath[1001]; strcpy(filepath, kinc_internal_save_path()); strcat(filepath, filename); - reader->file = fopen(filepath, "rb"); - if (reader->file == NULL) { + reader->data = fopen(filepath, "rb"); + if (reader->data == NULL) { return false; } - fseek(reader->file, 0, SEEK_END); - reader->size = ftell(reader->file); - fseek(reader->file, 0, SEEK_SET); + fseek((FILE *)reader->data, 0, SEEK_END); + reader->size = ftell((FILE *)reader->data); + fseek((FILE *)reader->data, 0, SEEK_SET); return true; } else { @@ -1282,18 +1302,23 @@ bool kinc_file_reader_open(kinc_file_reader_t *reader, const char *filename, int strcat(filepath, filename); } - reader->file = fopen(filepath, "rb"); - if (reader->file != NULL) { - fseek(reader->file, 0, SEEK_END); - reader->size = ftell(reader->file); - fseek(reader->file, 0, SEEK_SET); + FILE *stream = fopen(filepath, "rb"); + if (stream != NULL) { + reader->data = stream; + fseek(stream, 0, SEEK_END); + reader->size = ftell(stream); + fseek(stream, 0, SEEK_SET); return true; } else { - reader->asset = AAssetManager_open(kinc_android_get_asset_manager(), filename, AASSET_MODE_RANDOM); - if (reader->asset == NULL) + reader->data = AAssetManager_open(kinc_android_get_asset_manager(), filename, AASSET_MODE_RANDOM); + if (reader->data == NULL) return false; - reader->size = AAsset_getLength(reader->asset); + reader->size = AAsset_getLength((struct AAsset *)reader->data); + reader->close = kinc_aasset_reader_close; + reader->read = kinc_aasset_reader_read; + reader->pos = kinc_aasset_reader_pos; + reader->seek = kinc_aasset_reader_seek; return true; } } diff --git a/Sources/kinc/image.h b/Sources/kinc/image.h index b8787733e..c94e8da4f 100644 --- a/Sources/kinc/image.h +++ b/Sources/kinc/image.h @@ -39,13 +39,13 @@ typedef struct kinc_image { unsigned internal_format; kinc_image_compression_t compression; void *data; - int data_size; + size_t data_size; } kinc_image_t; typedef struct kinc_image_read_callbacks { - int (*read)(void *user_data, void *data, size_t size); - void (*seek)(void *user_data, int pos); - int (*pos)(void *user_data); + size_t (*read)(void *user_data, void *data, size_t size); + void (*seek)(void *user_data, size_t pos); + size_t (*pos)(void *user_data); size_t (*size)(void *user_data); } kinc_image_read_callbacks_t; @@ -236,13 +236,13 @@ typedef struct { // fill 'data' with 'size' bytes. return number of bytes actually read static int stb_read(void *user, char *data, int size) { read_data *reader = (read_data *)user; - return reader->callbacks.read(reader->user_data, data, size); + return (int)reader->callbacks.read(reader->user_data, data, (size_t)size); } // skip the next 'n' bytes, or 'unget' the last -n bytes if negative static void stb_skip(void *user, int n) { read_data *reader = (read_data *)user; - reader->callbacks.seek(reader->user_data, reader->callbacks.pos(reader->user_data) + n); + reader->callbacks.seek(reader->user_data, reader->callbacks.pos(reader->user_data) + (size_t)n); } // returns nonzero if we are at end of file/data @@ -336,7 +336,7 @@ static size_t loadImageSize(kinc_image_read_callbacks_t callbacks, void *user_da } } -static bool loadImage(kinc_image_read_callbacks_t callbacks, void *user_data, const char *filename, uint8_t *output, int *outputSize, int *width, int *height, +static bool loadImage(kinc_image_read_callbacks_t callbacks, void *user_data, const char *filename, uint8_t *output, size_t *outputSize, int *width, int *height, kinc_image_compression_t *compression, kinc_image_format_t *format, unsigned *internalFormat) { *format = KINC_IMAGE_FORMAT_RGBA32; if (endsWith(filename, "k")) { @@ -355,25 +355,25 @@ static bool loadImage(kinc_image_read_callbacks_t callbacks, void *user_data, co if (strcmp(fourcc, "LZ4 ") == 0) { *compression = KINC_IMAGE_COMPRESSION_NONE; *internalFormat = 0; - *outputSize = *width * *height * 4; + *outputSize = (size_t)(*width * *height * 4); callbacks.read(user_data, buffer, compressedSize); - LZ4_decompress_safe((char *)buffer, (char *)output, compressedSize, *outputSize); + LZ4_decompress_safe((char *)buffer, (char *)output, compressedSize, (int)*outputSize); return true; } else if (strcmp(fourcc, "LZ4F") == 0) { *compression = KINC_IMAGE_COMPRESSION_NONE; *internalFormat = 0; - *outputSize = *width * *height * 16; + *outputSize = (size_t)(*width * *height * 16); callbacks.read(user_data, buffer, compressedSize); - LZ4_decompress_safe((char *)buffer, (char *)output, compressedSize, *outputSize); + LZ4_decompress_safe((char *)buffer, (char *)output, compressedSize, (int)*outputSize); *format = KINC_IMAGE_FORMAT_RGBA128; return true; } else if (strcmp(fourcc, "ASTC") == 0) { *compression = KINC_IMAGE_COMPRESSION_ASTC; - *outputSize = *width * *height * 4; + *outputSize = (size_t)(*width * *height * 4); callbacks.read(user_data, buffer, compressedSize); - *outputSize = LZ4_decompress_safe((char *)buffer, (char *)output, compressedSize, *outputSize); + *outputSize = LZ4_decompress_safe((char *)buffer, (char *)output, compressedSize, (int)*outputSize); uint8_t blockdim_x = 6; uint8_t blockdim_y = 6; @@ -413,9 +413,9 @@ static bool loadImage(kinc_image_read_callbacks_t callbacks, void *user_data, co } else if (strcmp(fourcc, "DXT5") == 0) { *compression = KINC_IMAGE_COMPRESSION_DXT5; - *outputSize = *width * *height; + *outputSize = (size_t)(*width * *height); callbacks.read(user_data, buffer, compressedSize); - *outputSize = LZ4_decompress_safe((char *)buffer, (char *)output, compressedSize, *outputSize); + *outputSize = LZ4_decompress_safe((char *)buffer, (char *)output, compressedSize, (int)*outputSize); *internalFormat = 0; return true; } @@ -472,7 +472,7 @@ static bool loadImage(kinc_image_read_callbacks_t callbacks, void *user_data, co *compression = KINC_IMAGE_COMPRESSION_PVRTC; *internalFormat = 0; - *outputSize = ww * hh / 2; + *outputSize = (size_t)(ww * hh / 2); callbacks.read(user_data, output, *outputSize); return true; } @@ -495,7 +495,7 @@ static bool loadImage(kinc_image_read_callbacks_t callbacks, void *user_data, co kinc_log(KINC_LOG_LEVEL_ERROR, stbi_failure_reason()); return false; } - *outputSize = *width * *height * 16; + *outputSize = (size_t)(*width * *height * 16); memcpy(output, uncompressed, *outputSize); *format = KINC_IMAGE_FORMAT_RGBA128; buffer_offset = 0; @@ -535,7 +535,7 @@ static bool loadImage(kinc_image_read_callbacks_t callbacks, void *user_data, co output[y * *width * 4 + x * 4 + 3] = (uint8_t)kinc_round(a * 255.0f); } } - *outputSize = *width * *height * 4; + *outputSize = (size_t)(*width * *height * 4); buffer_offset = 0; return true; } @@ -593,7 +593,7 @@ void kinc_image_init_from_bytes3d(kinc_image_t *image, void *data, int width, in image->data = data; } -static int read_callback(void *user_data, void *data, size_t size) { +static size_t read_callback(void *user_data, void *data, size_t size) { return kinc_file_reader_read((kinc_file_reader_t *)user_data, data, size); } @@ -601,11 +601,11 @@ static size_t size_callback(void *user_data) { return kinc_file_reader_size((kinc_file_reader_t *)user_data); } -static int pos_callback(void *user_data) { +static size_t pos_callback(void *user_data) { return kinc_file_reader_pos((kinc_file_reader_t *)user_data); } -static void seek_callback(void *user_data, int pos) { +static void seek_callback(void *user_data, size_t pos) { kinc_file_reader_seek((kinc_file_reader_t *)user_data, pos); } @@ -615,12 +615,12 @@ struct kinc_internal_image_memory { size_t offset; }; -static int memory_read_callback(void *user_data, void *data, size_t size) { +static size_t memory_read_callback(void *user_data, void *data, size_t size) { struct kinc_internal_image_memory *memory = (struct kinc_internal_image_memory *)user_data; size_t read_size = memory->size - memory->offset < size ? memory->size - memory->offset : size; memcpy(data, &memory->data[memory->offset], read_size); memory->offset += read_size; - return (int)read_size; + return read_size; } static size_t memory_size_callback(void *user_data) { @@ -628,14 +628,14 @@ static size_t memory_size_callback(void *user_data) { return memory->size; } -static int memory_pos_callback(void *user_data) { +static size_t memory_pos_callback(void *user_data) { struct kinc_internal_image_memory *memory = (struct kinc_internal_image_memory *)user_data; - return (int)memory->offset; + return memory->offset; } -static void memory_seek_callback(void *user_data, int pos) { +static void memory_seek_callback(void *user_data, size_t pos) { struct kinc_internal_image_memory *memory = (struct kinc_internal_image_memory *)user_data; - memory->offset = (size_t)pos; + memory->offset = pos; } size_t kinc_image_size_from_callbacks(kinc_image_read_callbacks_t callbacks, void *user_data, const char *filename) { @@ -674,9 +674,10 @@ size_t kinc_image_size_from_encoded_bytes(void *data, size_t data_size, const ch } size_t kinc_image_init_from_callbacks(kinc_image_t *image, void *memory, kinc_image_read_callbacks_t callbacks, void *user_data, const char *filename) { - int dataSize; + size_t dataSize = 0; loadImage(callbacks, user_data, filename, memory, &dataSize, &image->width, &image->height, &image->compression, &image->format, &image->internal_format); image->data = memory; + image->data_size = dataSize; return dataSize; } @@ -689,7 +690,7 @@ size_t kinc_image_init_from_file(kinc_image_t *image, void *memory, const char * callbacks.pos = pos_callback; callbacks.seek = seek_callback; - int dataSize; + size_t dataSize = 0; loadImage(callbacks, &reader, filename, memory, &dataSize, &image->width, &image->height, &image->compression, &image->format, &image->internal_format); kinc_file_reader_close(&reader); image->data = memory; @@ -712,7 +713,7 @@ size_t kinc_image_init_from_encoded_bytes(kinc_image_t *image, void *memory, voi image_memory.size = data_size; image_memory.offset = 0; - int dataSize; + size_t dataSize = 0; loadImage(callbacks, &image_memory, format, memory, &dataSize, &image->width, &image->height, &image->compression, &image->format, &image->internal_format); image->data = memory; image->data_size = dataSize; diff --git a/Sources/kinc/io/filereader.h b/Sources/kinc/io/filereader.h index 428492b96..9f1714dfe 100644 --- a/Sources/kinc/io/filereader.h +++ b/Sources/kinc/io/filereader.h @@ -31,26 +31,22 @@ typedef struct __sFILE FILE; #define KINC_FILE_TYPE_ASSET 0 #define KINC_FILE_TYPE_SAVE 1 -#ifdef KORE_ANDROID -typedef struct kinc_file_reader { - int pos; - int size; - FILE *file; - struct AAsset *asset; - int type; -} kinc_file_reader_t; -#else typedef struct kinc_file_reader { - void *file; - int size; + void *data; // A file handle or a more complex structure + size_t size; + size_t offset; // Needed by some implementations int type; - int mode; bool mounted; + + void (*close)(struct kinc_file_reader *reader); + size_t (*read)(struct kinc_file_reader *reader, void *data, size_t size); + size_t (*pos)(struct kinc_file_reader *reader); + void (*seek)(struct kinc_file_reader *reader, size_t pos); + #if defined(KORE_SONY) || defined(KORE_SWITCH) kinc_file_reader_impl_t impl; #endif } kinc_file_reader_t; -#endif /// /// Opens a file for reading. @@ -61,6 +57,14 @@ typedef struct kinc_file_reader { /// Whether the file could be opened KINC_FUNC bool kinc_file_reader_open(kinc_file_reader_t *reader, const char *filepath, int type); +/// +/// Opens a memory area for reading using the file reader API. +/// +/// The reader to initialize for reading +/// A pointer to the memory area to read +/// The size of the memory area +KINC_FUNC void kinc_file_reader_from_memory(kinc_file_reader_t *reader, void *data, size_t size); + /// /// Closes a file. /// @@ -74,7 +78,7 @@ KINC_FUNC void kinc_file_reader_close(kinc_file_reader_t *reader); /// A pointer to write the data to /// The amount of data to read in bytes /// The number of bytes that were read - can be less than size if there is not enough data in the file -KINC_FUNC int kinc_file_reader_read(kinc_file_reader_t *reader, void *data, size_t size); +KINC_FUNC size_t kinc_file_reader_read(kinc_file_reader_t *reader, void *data, size_t size); /// /// Figures out the size of a file. @@ -88,14 +92,14 @@ KINC_FUNC size_t kinc_file_reader_size(kinc_file_reader_t *reader); /// /// The reader which's reading-position to figure out /// The current reading-position -KINC_FUNC int kinc_file_reader_pos(kinc_file_reader_t *reader); +KINC_FUNC size_t kinc_file_reader_pos(kinc_file_reader_t *reader); /// /// Sets the reading-position manually. /// /// The reader which's reading-position to set /// The reading-position to set -KINC_FUNC void kinc_file_reader_seek(kinc_file_reader_t *reader, int pos); +KINC_FUNC void kinc_file_reader_seek(kinc_file_reader_t *reader, size_t pos); /// /// Interprets four bytes starting at the provided pointer as a little-endian float. @@ -203,6 +207,36 @@ char *kinc_internal_get_files_location(void); #include #endif +static void memory_close_callback(kinc_file_reader_t *reader) { +} + +static size_t memory_read_callback(kinc_file_reader_t *reader, void *data, size_t size) { + size_t read_size = reader->size - reader->offset < size ? reader->size - reader->offset : size; + memcpy(data, (uint8_t *)reader->data + reader->offset, read_size); + reader->offset += read_size; + return read_size; +} + +static size_t memory_pos_callback(kinc_file_reader_t *reader) { + return reader->offset; +} + +static void memory_seek_callback(kinc_file_reader_t *reader, size_t pos) { + reader->offset = pos; +} + +void kinc_file_reader_from_memory(kinc_file_reader_t *reader, void *data, size_t size) +{ + memset(reader, 0, sizeof(kinc_file_reader_t)); + reader->type = KINC_FILE_TYPE_ASSET; + reader->data = data; + reader->size = size; + reader->read = memory_read_callback; + reader->pos = memory_pos_callback; + reader->seek = memory_seek_callback; + reader->close = memory_close_callback; +} + #ifndef KORE_CONSOLE #ifdef KORE_IOS @@ -245,6 +279,8 @@ void kinc_internal_uwp_installed_location_path(char *path); #ifndef KORE_ANDROID bool kinc_file_reader_open(kinc_file_reader_t *reader, const char *filename, int type) { memset(reader, 0, sizeof(kinc_file_reader_t)); + reader->type = type; + char filepath[1001]; #ifdef KORE_IOS strcpy(filepath, type == KINC_FILE_TYPE_SAVE ? kinc_internal_save_path() : iphonegetresourcepath()); @@ -329,106 +365,91 @@ bool kinc_file_reader_open(kinc_file_reader_t *reader, const char *filename, int #ifdef KORE_WINDOWS MultiByteToWideChar(CP_UTF8, 0, filepath, -1, wfilepath, 1000); - reader->file = CreateFileW(wfilepath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if (reader->file == INVALID_HANDLE_VALUE) { + reader->data = CreateFileW(wfilepath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (reader->data == INVALID_HANDLE_VALUE) { return false; } #else - reader->file = fopen(filepath, "rb"); - if (reader->file == NULL) { + reader->data = fopen(filepath, "rb"); + if (reader->data == NULL) { return false; } #endif #ifdef KORE_WINDOWS - reader->size = GetFileSize(reader->file, NULL); + // TODO: make this 64-bit compliant + reader->size = (size_t)GetFileSize(reader->data, NULL); #else - fseek((FILE *)reader->file, 0, SEEK_END); - reader->size = (int)ftell((FILE *)reader->file); - fseek((FILE *)reader->file, 0, SEEK_SET); + fseek((FILE *)reader->data, 0, SEEK_END); + reader->size = ftell((FILE *)reader->data); + fseek((FILE *)reader->data, 0, SEEK_SET); #endif return true; } #endif -int kinc_file_reader_read(kinc_file_reader_t *reader, void *data, size_t size) { -#ifdef KORE_ANDROID - if (reader->file != NULL) { - return (int)fread(data, 1, size, reader->file); - } - else { - int read = AAsset_read(reader->asset, data, size); - reader->pos += read; - return read; +size_t kinc_file_reader_read(kinc_file_reader_t *reader, void *data, size_t size) { + if (reader->read != NULL) { + return reader->read(reader, data, size); } -#elif defined(KORE_WINDOWS) +#if defined(KORE_WINDOWS) DWORD readBytes = 0; - if (ReadFile(reader->file, data, (DWORD)size, &readBytes, NULL)) { - return (int)readBytes; + if (ReadFile(reader->data, data, (DWORD)size, &readBytes, NULL)) { + return (size_t)readBytes; } else { return 0; } #else - return (int)fread(data, 1, size, (FILE *)reader->file); + return fread(data, 1, size, (FILE *)reader->data); #endif } -void kinc_file_reader_seek(kinc_file_reader_t *reader, int pos) { -#ifdef KORE_ANDROID - if (reader->file != NULL) { - fseek(reader->file, pos, SEEK_SET); - } - else { - AAsset_seek(reader->asset, pos, SEEK_SET); - reader->pos = pos; +void kinc_file_reader_seek(kinc_file_reader_t *reader, size_t pos) { + if (reader->seek != NULL) { + reader->seek(reader, pos); + return; } -#elif defined(KORE_WINDOWS) - SetFilePointer(reader->file, pos, NULL, FILE_BEGIN); +#if defined(KORE_WINDOWS) + // TODO: make this 64-bit compliant + SetFilePointer(reader->data, (LONG)pos, NULL, FILE_BEGIN); #else - fseek((FILE *)reader->file, pos, SEEK_SET); + fseek((FILE *)reader->data, pos, SEEK_SET); #endif } void kinc_file_reader_close(kinc_file_reader_t *reader) { -#ifdef KORE_ANDROID - if (reader->file != NULL) { - fclose(reader->file); - reader->file = NULL; - } - if (reader->asset != NULL) { - AAsset_close(reader->asset); - reader->asset = NULL; + if (reader->close != NULL) { + reader->close(reader); + return; } -#elif defined(KORE_WINDOWS) - CloseHandle(reader->file); +#if defined(KORE_WINDOWS) + CloseHandle(reader->data); #else - if (reader->file == NULL) { - return; + if (reader->data != NULL) { + fclose((FILE *)reader->data); + reader->data = NULL; } - fclose((FILE *)reader->file); - reader->file = NULL; #endif } -int kinc_file_reader_pos(kinc_file_reader_t *reader) { -#ifdef KORE_ANDROID - if (reader->file != NULL) - return (int)ftell(reader->file); - else - return reader->pos; -#elif defined(KORE_WINDOWS) - return (int)SetFilePointer(reader->file, 0, NULL, FILE_CURRENT); +size_t kinc_file_reader_pos(kinc_file_reader_t *reader) { + if (reader->pos != NULL) { + return reader->pos(reader); + } +#if defined(KORE_WINDOWS) + // TODO: make this 64-bit compliant + return (size_t)SetFilePointer(reader->data, 0, NULL, FILE_CURRENT); #else - return (int)ftell((FILE *)reader->file); + return ftell((FILE *)reader->data); #endif } size_t kinc_file_reader_size(kinc_file_reader_t *reader) { - return (size_t)reader->size; + return reader->size; } -#endif +#endif // KORE_CONSOLE float kinc_read_f32le(uint8_t *data) { #ifdef KORE_LITTLE_ENDIAN // speed optimization