N64FlashcartMenu/src/menu/png_decoder.c

172 lines
4.4 KiB
C
Raw Normal View History

Use `stdio` calls for file/directory interaction instead of `fatfs` (#95) <!--- Provide a general summary of your changes in the Title above --> ## Description <!--- Describe your changes in detail --> This PR changes most of the calls to the fatfs lib with the standard C ones. Additionally, there's couple of changes required to adapt to new interface and several bug fixes. As a bonus menu can now be run in ares emulator and on the iQue player, adapting to the available storage options - DragonFS in the ROM and iQue flash modules (bbfs). ## Motivation and Context <!--- What does this sample do? What problem does it solve? --> <!--- If it fixes/closes/resolves an open issue, please link to the issue here --> To make it easier to use storage medium other than SD cards on platforms other than N64 with flashcart. ## How Has This Been Tested? <!-- (if applicable) --> <!--- Please describe in detail how you tested your sample/changes. --> <!--- Include details of your testing environment, and the tests you ran to --> <!--- see how your change affects other areas of the code, etc. --> SummerCart64 flashcart and ares emulator ## Screenshots <!-- (if appropriate): --> N/A ## Types of changes <!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: --> - [x] Improvement (non-breaking change that adds a new feature) - [x] Bug fix (fixes an issue) - [x] Breaking change (breaking change) - [x] Config and build (change in the configuration and build system, has no impact on code or features) ## Checklist: <!--- Go over all the following points, and put an `x` in all the boxes that apply. --> <!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! --> - [x] My code follows the code style of this project. - [x] My change requires a change to the documentation. - [ ] I have updated the documentation accordingly. - [ ] I have added tests to cover my changes. - [ ] All new and existing tests passed. <!--- It would be nice if you could sign off your contribution by replacing the name with your GitHub user name and GitHub email contact. --> Signed-off-by: Polprzewodnikowy <sc@mateuszfaderewski.pl>
2024-04-24 02:45:09 +02:00
#include <stdio.h>
#include <libspng/spng/spng.h>
#include "png_decoder.h"
2023-07-28 21:24:47 +02:00
#include "utils/fs.h"
Documentation updates (#65) <!--- Provide a general summary of your changes in the Title above --> ## Description <!--- Describe your changes in detail --> ## Motivation and Context <!--- What does this sample do? What problem does it solve? --> <!--- If it fixes/closes/resolves an open issue, please link to the issue here --> ## How Has This Been Tested? <!-- (if applicable) --> <!--- Please describe in detail how you tested your sample/changes. --> <!--- Include details of your testing environment, and the tests you ran to --> <!--- see how your change affects other areas of the code, etc. --> ## Screenshots <!-- (if appropriate): --> ## Types of changes <!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: --> - [ ] Improvement (non-breaking change that adds a new feature) - [ ] Bug fix (fixes an issue) - [ ] Breaking change (breaking change) - [ ] Config and build (change in the configuration and build system, has no impact on code or features) ## Checklist: <!--- Go over all the following points, and put an `x` in all the boxes that apply. --> <!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! --> - [ ] My code follows the code style of this project. - [ ] My change requires a change to the documentation. - [ ] I have updated the documentation accordingly. - [ ] I have added tests to cover my changes. - [ ] All new and existing tests passed. <!--- It would be nice if you could sign off your contribution by replacing the name with your GitHub user name and GitHub email contact. --> Signed-off-by: GITHUB_USER <GITHUB_USER_EMAIL>
2023-11-10 17:39:09 +01:00
/** @brief PNG File Information Structure. */
typedef struct {
Use `stdio` calls for file/directory interaction instead of `fatfs` (#95) <!--- Provide a general summary of your changes in the Title above --> ## Description <!--- Describe your changes in detail --> This PR changes most of the calls to the fatfs lib with the standard C ones. Additionally, there's couple of changes required to adapt to new interface and several bug fixes. As a bonus menu can now be run in ares emulator and on the iQue player, adapting to the available storage options - DragonFS in the ROM and iQue flash modules (bbfs). ## Motivation and Context <!--- What does this sample do? What problem does it solve? --> <!--- If it fixes/closes/resolves an open issue, please link to the issue here --> To make it easier to use storage medium other than SD cards on platforms other than N64 with flashcart. ## How Has This Been Tested? <!-- (if applicable) --> <!--- Please describe in detail how you tested your sample/changes. --> <!--- Include details of your testing environment, and the tests you ran to --> <!--- see how your change affects other areas of the code, etc. --> SummerCart64 flashcart and ares emulator ## Screenshots <!-- (if appropriate): --> N/A ## Types of changes <!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: --> - [x] Improvement (non-breaking change that adds a new feature) - [x] Bug fix (fixes an issue) - [x] Breaking change (breaking change) - [x] Config and build (change in the configuration and build system, has no impact on code or features) ## Checklist: <!--- Go over all the following points, and put an `x` in all the boxes that apply. --> <!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! --> - [x] My code follows the code style of this project. - [x] My change requires a change to the documentation. - [ ] I have updated the documentation accordingly. - [ ] I have added tests to cover my changes. - [ ] All new and existing tests passed. <!--- It would be nice if you could sign off your contribution by replacing the name with your GitHub user name and GitHub email contact. --> Signed-off-by: Polprzewodnikowy <sc@mateuszfaderewski.pl>
2024-04-24 02:45:09 +02:00
FILE *f;
spng_ctx *ctx;
struct spng_ihdr ihdr;
surface_t *image;
uint8_t *row_buffer;
int decoded_rows;
png_callback_t *callback;
void *callback_data;
} png_decoder_t;
static png_decoder_t *decoder;
static void png_decoder_deinit (bool free_image) {
if (decoder != NULL) {
Use `stdio` calls for file/directory interaction instead of `fatfs` (#95) <!--- Provide a general summary of your changes in the Title above --> ## Description <!--- Describe your changes in detail --> This PR changes most of the calls to the fatfs lib with the standard C ones. Additionally, there's couple of changes required to adapt to new interface and several bug fixes. As a bonus menu can now be run in ares emulator and on the iQue player, adapting to the available storage options - DragonFS in the ROM and iQue flash modules (bbfs). ## Motivation and Context <!--- What does this sample do? What problem does it solve? --> <!--- If it fixes/closes/resolves an open issue, please link to the issue here --> To make it easier to use storage medium other than SD cards on platforms other than N64 with flashcart. ## How Has This Been Tested? <!-- (if applicable) --> <!--- Please describe in detail how you tested your sample/changes. --> <!--- Include details of your testing environment, and the tests you ran to --> <!--- see how your change affects other areas of the code, etc. --> SummerCart64 flashcart and ares emulator ## Screenshots <!-- (if appropriate): --> N/A ## Types of changes <!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: --> - [x] Improvement (non-breaking change that adds a new feature) - [x] Bug fix (fixes an issue) - [x] Breaking change (breaking change) - [x] Config and build (change in the configuration and build system, has no impact on code or features) ## Checklist: <!--- Go over all the following points, and put an `x` in all the boxes that apply. --> <!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! --> - [x] My code follows the code style of this project. - [x] My change requires a change to the documentation. - [ ] I have updated the documentation accordingly. - [ ] I have added tests to cover my changes. - [ ] All new and existing tests passed. <!--- It would be nice if you could sign off your contribution by replacing the name with your GitHub user name and GitHub email contact. --> Signed-off-by: Polprzewodnikowy <sc@mateuszfaderewski.pl>
2024-04-24 02:45:09 +02:00
fclose(decoder->f);
if (decoder->ctx != NULL) {
spng_ctx_free(decoder->ctx);
}
if ((decoder->image != NULL) && free_image) {
surface_free(decoder->image);
free(decoder->image);
}
if (decoder->row_buffer != NULL) {
free(decoder->row_buffer);
}
free(decoder);
decoder = NULL;
}
}
2023-07-28 21:24:47 +02:00
png_err_t png_decoder_start (char *path, int max_width, int max_height, png_callback_t *callback, void *callback_data) {
if (decoder != NULL) {
return PNG_ERR_BUSY;
}
decoder = calloc(1, sizeof(png_decoder_t));
if (decoder == NULL) {
return PNG_ERR_OUT_OF_MEM;
}
Use `stdio` calls for file/directory interaction instead of `fatfs` (#95) <!--- Provide a general summary of your changes in the Title above --> ## Description <!--- Describe your changes in detail --> This PR changes most of the calls to the fatfs lib with the standard C ones. Additionally, there's couple of changes required to adapt to new interface and several bug fixes. As a bonus menu can now be run in ares emulator and on the iQue player, adapting to the available storage options - DragonFS in the ROM and iQue flash modules (bbfs). ## Motivation and Context <!--- What does this sample do? What problem does it solve? --> <!--- If it fixes/closes/resolves an open issue, please link to the issue here --> To make it easier to use storage medium other than SD cards on platforms other than N64 with flashcart. ## How Has This Been Tested? <!-- (if applicable) --> <!--- Please describe in detail how you tested your sample/changes. --> <!--- Include details of your testing environment, and the tests you ran to --> <!--- see how your change affects other areas of the code, etc. --> SummerCart64 flashcart and ares emulator ## Screenshots <!-- (if appropriate): --> N/A ## Types of changes <!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: --> - [x] Improvement (non-breaking change that adds a new feature) - [x] Bug fix (fixes an issue) - [x] Breaking change (breaking change) - [x] Config and build (change in the configuration and build system, has no impact on code or features) ## Checklist: <!--- Go over all the following points, and put an `x` in all the boxes that apply. --> <!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! --> - [x] My code follows the code style of this project. - [x] My change requires a change to the documentation. - [ ] I have updated the documentation accordingly. - [ ] I have added tests to cover my changes. - [ ] All new and existing tests passed. <!--- It would be nice if you could sign off your contribution by replacing the name with your GitHub user name and GitHub email contact. --> Signed-off-by: Polprzewodnikowy <sc@mateuszfaderewski.pl>
2024-04-24 02:45:09 +02:00
if ((decoder->f = fopen(path, "rb")) == NULL) {
png_decoder_deinit(false);
return PNG_ERR_NO_FILE;
}
Use `stdio` calls for file/directory interaction instead of `fatfs` (#95) <!--- Provide a general summary of your changes in the Title above --> ## Description <!--- Describe your changes in detail --> This PR changes most of the calls to the fatfs lib with the standard C ones. Additionally, there's couple of changes required to adapt to new interface and several bug fixes. As a bonus menu can now be run in ares emulator and on the iQue player, adapting to the available storage options - DragonFS in the ROM and iQue flash modules (bbfs). ## Motivation and Context <!--- What does this sample do? What problem does it solve? --> <!--- If it fixes/closes/resolves an open issue, please link to the issue here --> To make it easier to use storage medium other than SD cards on platforms other than N64 with flashcart. ## How Has This Been Tested? <!-- (if applicable) --> <!--- Please describe in detail how you tested your sample/changes. --> <!--- Include details of your testing environment, and the tests you ran to --> <!--- see how your change affects other areas of the code, etc. --> SummerCart64 flashcart and ares emulator ## Screenshots <!-- (if appropriate): --> N/A ## Types of changes <!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: --> - [x] Improvement (non-breaking change that adds a new feature) - [x] Bug fix (fixes an issue) - [x] Breaking change (breaking change) - [x] Config and build (change in the configuration and build system, has no impact on code or features) ## Checklist: <!--- Go over all the following points, and put an `x` in all the boxes that apply. --> <!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! --> - [x] My code follows the code style of this project. - [x] My change requires a change to the documentation. - [ ] I have updated the documentation accordingly. - [ ] I have added tests to cover my changes. - [ ] All new and existing tests passed. <!--- It would be nice if you could sign off your contribution by replacing the name with your GitHub user name and GitHub email contact. --> Signed-off-by: Polprzewodnikowy <sc@mateuszfaderewski.pl>
2024-04-24 02:45:09 +02:00
setbuf(decoder->f, NULL);
if ((decoder->ctx = spng_ctx_new(SPNG_CTX_IGNORE_ADLER32)) == NULL) {
png_decoder_deinit(false);
return PNG_ERR_OUT_OF_MEM;
}
if (spng_set_crc_action(decoder->ctx, SPNG_CRC_USE, SPNG_CRC_USE) != SPNG_OK) {
png_decoder_deinit(false);
return PNG_ERR_INT;
}
if (spng_set_image_limits(decoder->ctx, max_width, max_height) != SPNG_OK) {
png_decoder_deinit(false);
return PNG_ERR_INT;
}
Use `stdio` calls for file/directory interaction instead of `fatfs` (#95) <!--- Provide a general summary of your changes in the Title above --> ## Description <!--- Describe your changes in detail --> This PR changes most of the calls to the fatfs lib with the standard C ones. Additionally, there's couple of changes required to adapt to new interface and several bug fixes. As a bonus menu can now be run in ares emulator and on the iQue player, adapting to the available storage options - DragonFS in the ROM and iQue flash modules (bbfs). ## Motivation and Context <!--- What does this sample do? What problem does it solve? --> <!--- If it fixes/closes/resolves an open issue, please link to the issue here --> To make it easier to use storage medium other than SD cards on platforms other than N64 with flashcart. ## How Has This Been Tested? <!-- (if applicable) --> <!--- Please describe in detail how you tested your sample/changes. --> <!--- Include details of your testing environment, and the tests you ran to --> <!--- see how your change affects other areas of the code, etc. --> SummerCart64 flashcart and ares emulator ## Screenshots <!-- (if appropriate): --> N/A ## Types of changes <!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: --> - [x] Improvement (non-breaking change that adds a new feature) - [x] Bug fix (fixes an issue) - [x] Breaking change (breaking change) - [x] Config and build (change in the configuration and build system, has no impact on code or features) ## Checklist: <!--- Go over all the following points, and put an `x` in all the boxes that apply. --> <!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! --> - [x] My code follows the code style of this project. - [x] My change requires a change to the documentation. - [ ] I have updated the documentation accordingly. - [ ] I have added tests to cover my changes. - [ ] All new and existing tests passed. <!--- It would be nice if you could sign off your contribution by replacing the name with your GitHub user name and GitHub email contact. --> Signed-off-by: Polprzewodnikowy <sc@mateuszfaderewski.pl>
2024-04-24 02:45:09 +02:00
if (spng_set_png_file(decoder->ctx, decoder->f) != SPNG_OK) {
png_decoder_deinit(false);
return PNG_ERR_INT;
}
2023-07-28 21:24:47 +02:00
size_t image_size;
if (spng_decoded_image_size(decoder->ctx, SPNG_FMT_RGB8, &image_size) != SPNG_OK) {
png_decoder_deinit(false);
return PNG_ERR_BAD_FILE;
}
if (spng_decode_image(decoder->ctx, NULL, image_size, SPNG_FMT_RGB8, SPNG_DECODE_PROGRESSIVE) != SPNG_OK) {
png_decoder_deinit(false);
return PNG_ERR_BAD_FILE;
}
if (spng_get_ihdr(decoder->ctx, &decoder->ihdr) != SPNG_OK) {
png_decoder_deinit(false);
return PNG_ERR_BAD_FILE;
}
decoder->image = calloc(1, sizeof(surface_t));
if (decoder->image == NULL) {
png_decoder_deinit(false);
return PNG_ERR_OUT_OF_MEM;
}
*decoder->image = surface_alloc(FMT_RGBA16, decoder->ihdr.width, decoder->ihdr.height);
if (decoder->image->buffer == NULL) {
png_decoder_deinit(true);
return PNG_ERR_OUT_OF_MEM;
}
if ((decoder->row_buffer = malloc(decoder->ihdr.width * 3)) == NULL) {
png_decoder_deinit(true);
return PNG_ERR_OUT_OF_MEM;
}
decoder->decoded_rows = 0;
decoder->callback = callback;
decoder->callback_data = callback_data;
return PNG_OK;
}
void png_decoder_abort (void) {
png_decoder_deinit(true);
}
float png_decoder_get_progress (void) {
if (!decoder) {
return 0.0f;
}
return (float) (decoder->decoded_rows) / (decoder->ihdr.height);
}
2023-07-26 18:41:38 +02:00
void png_decoder_poll (void) {
if (!decoder) {
return;
}
enum spng_errno err;
struct spng_row_info row_info;
if ((err = spng_get_row_info(decoder->ctx, &row_info)) != SPNG_OK) {
decoder->callback(PNG_ERR_BAD_FILE, NULL, decoder->callback_data);
png_decoder_deinit(true);
return;
}
err = spng_decode_row(decoder->ctx, decoder->row_buffer, decoder->ihdr.width * 3);
if (err == SPNG_OK || err == SPNG_EOI) {
decoder->decoded_rows += 1;
uint16_t *image_buffer = decoder->image->buffer + (row_info.row_num * decoder->image->stride);
for (int i = 0; i < decoder->ihdr.width * 3; i += 3) {
uint8_t r = decoder->row_buffer[i + 0] >> 3;
uint8_t g = decoder->row_buffer[i + 1] >> 3;
uint8_t b = decoder->row_buffer[i + 2] >> 3;
*image_buffer++ = (r << 11) | (g << 6) | (b << 1) | 1;
}
}
if (err == SPNG_EOI) {
decoder->callback(PNG_OK, decoder->image, decoder->callback_data);
png_decoder_deinit(false);
} else if (err != SPNG_OK) {
decoder->callback(PNG_ERR_BAD_FILE, NULL, decoder->callback_data);
png_decoder_deinit(true);
}
}