Moved to uint32_t for asset file and corrected memory allocations form and errors.

This commit is contained in:
Ulysse Cura 2026-08-15 14:21:10 +02:00
parent baa90d957f
commit ae3e040fac
8 changed files with 146 additions and 139 deletions

@ -1 +1 @@
Subproject commit eb01fd4d2b5034228938b5d5b54785111efd4908
Subproject commit 946cc2e4953cdbe5204adb5a5fe71650ba9542ca

View File

@ -2,11 +2,10 @@
| Description | Length |
| :---------------- | :---------------------------------- |
| Assets number | size_t (64 bits) |
| Assets number | unsigned int (32 bits) |
| ... | |
| Asset name | const char * (variable length) |
| Asset start index | size_t (64 bits) |
| Asset end index | size_t (64 bits) |
| Asset start index | unsigned int (32 bits) |
| ... | |
| Asset data | depend on assets content and number |
@ -21,8 +20,8 @@ Image data is in RGB 565.
| Description | Length |
| :---------------- | :------------------------------------------ |
| Image width | size_t (64 bits) |
| Image height | size_t (64 bits) |
| Image width | unsigned int (32 bits) |
| Image height | unsigned int (32 bits) |
| Image data | depend on image size, pixel short (16 bits) |
@ -43,7 +42,7 @@ Image data is in RGB 565.
| Map foreground layer data | depend on map size, tile short (16 bit) |
| Entities number | int (32 bits) |
| ... | |
| Entity ID | size_t (64 bits) |
| Entity ID | int (32 bits) |
| Entity component number | int (32 bits) |
| ... | |
| Component type | int (32 bits) |

View File

@ -1,8 +1,7 @@
# Source files
ASSET_BUILDER_SOURCES := \
main.c \
asset_file.c \
errors.c
main.c
# Compiler and flags
ASSET_BUILDER_CC = gcc

View File

@ -2,6 +2,7 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <png.h>
#include "errors.h"
@ -14,35 +15,50 @@ int parse_file_for_header(const char *input_file_name, asset_header_def_t *asset
if(!file_name_dot)
{
return NO_EXTENSION;
error_printf("File does not have an extension.");
return EXIT_FAILURE;
}
const char *file_name_ext = file_name_dot + 1;
if(!strcmp(file_name_ext, "png"))
{
return parse_png_for_header(input_file_name, asset_header_def);
if(parse_png_for_header(input_file_name, asset_header_def)) return_failure_int;
}
else
{
error_printf("Extension unsupported : %s", file_name_dot);
return EXIT_FAILURE;
}
return EXTENSION_UNSUPPORTED;
return EXIT_SUCCESS;
}
int write_header_to_file(asset_file_header_t *asset_file_header, FILE *output_file)
{
if(fwrite(&asset_file_header->assets_number, sizeof(size_t), 1, output_file) != 1)
return WRITE_FAILED;
if(fwrite(&asset_file_header->assets_number, sizeof(asset_file_header->assets_number), 1, output_file) != 1)
{
error_printf("Failed to write to output file : %d", errno);
return EXIT_FAILURE;
}
for(size_t i = 0; i < asset_file_header->assets_number; i++)
for(uint32_t i = 0; i < asset_file_header->assets_number; i++)
{
size_t name_length = strlen(asset_file_header->assets_header_def[i].name) + 1;
if(fwrite(asset_file_header->assets_header_def[i].name, sizeof(unsigned char), name_length, output_file) != name_length)
return WRITE_FAILED;
{
error_printf("Failed to write to output file : %d", errno);
return EXIT_FAILURE;
}
if(fwrite(&asset_file_header->assets_header_def[i].start, sizeof(size_t), 1, output_file) != 1)
return WRITE_FAILED;
if(fwrite(&asset_file_header->assets_header_def[i].start, sizeof(asset_file_header->assets_header_def[i].start), 1, output_file) != 1)
{
error_printf("Failed to write to output file : %d", errno);
return EXIT_FAILURE;
}
}
return NO_ERROR;
return EXIT_SUCCESS;
}
int parse_file_for_content_and_write(const char *input_file_name, FILE *output_file)
@ -51,17 +67,23 @@ int parse_file_for_content_and_write(const char *input_file_name, FILE *output_f
if(!file_name_dot)
{
return NO_EXTENSION;
error_printf("File does not have an extension.");
return EXIT_FAILURE;
}
const char *file_name_ext = file_name_dot + 1;
if(!strcmp(file_name_ext, "png"))
{
return parse_png_for_content_and_write(input_file_name, output_file);
if(parse_png_for_content_and_write(input_file_name, output_file)) return_failure_int;
}
else
{
error_printf("Extension unsupported : %s", file_name_dot);
return EXIT_FAILURE;
}
return EXTENSION_UNSUPPORTED;
return EXIT_SUCCESS;
}
// File specific functions.
@ -70,20 +92,25 @@ int parse_png_for_header(const char *file_name, asset_header_def_t *asset_header
FILE *input_file = fopen(file_name, "rb");
if(!input_file)
return OPEN_FAILED;
{
error_printf("Failed to open input file.");
return EXIT_FAILURE;
}
// Check png autenticity.
unsigned char sig[8];
if(fread(sig, sizeof(unsigned char), 8, input_file) != 8)
{
fclose(input_file);
return READ_FAILED;
error_printf("Failed to read input file.");
return EXIT_FAILURE;
}
if(!png_check_sig(sig, 8))
{
fclose(input_file);
return BAD_SIGNATURE;
error_printf("Png file is not valid.");
return EXIT_FAILURE;
}
// PNG structs.
@ -91,7 +118,8 @@ int parse_png_for_header(const char *file_name, asset_header_def_t *asset_header
if(!png_ptr)
{
fclose(input_file);
return MEMORY_ALLOC_FAILED;
error_printf("Failed to allocate png ptr.");
return EXIT_FAILURE;
}
png_infop info_ptr = png_create_info_struct(png_ptr);
@ -99,7 +127,8 @@ int parse_png_for_header(const char *file_name, asset_header_def_t *asset_header
{
png_destroy_read_struct(&png_ptr, NULL, NULL);
fclose(input_file);
return MEMORY_ALLOC_FAILED;
error_printf("Failed to allocate png info.");
return EXIT_FAILURE;
}
// Fill structs and load data.
@ -107,8 +136,8 @@ int parse_png_for_header(const char *file_name, asset_header_def_t *asset_header
png_set_sig_bytes(png_ptr, 8);
png_read_info(png_ptr, info_ptr);
size_t width = png_get_image_width(png_ptr, info_ptr);
size_t height = png_get_image_height(png_ptr, info_ptr);
uint32_t width = png_get_image_width(png_ptr, info_ptr);
uint32_t height = png_get_image_height(png_ptr, info_ptr);
uint8_t bit_depth = png_get_bit_depth(png_ptr, info_ptr);
uint8_t color_type = png_get_color_type(png_ptr, info_ptr);
@ -117,7 +146,8 @@ int parse_png_for_header(const char *file_name, asset_header_def_t *asset_header
{
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
fclose(input_file);
return PNG_BIT_DEPTH_UNSUPPORTED;
error_printf("Png bit depth not supported.");
return EXIT_FAILURE;
}
switch(color_type)
@ -129,17 +159,18 @@ int parse_png_for_header(const char *file_name, asset_header_def_t *asset_header
default:
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
fclose(input_file);
return PNG_COLOR_TYPE_UNSUPPORTED;
error_printf("Png color type not supported.");
return EXIT_FAILURE;
}
// Fill asset def.
asset_header_def->start = 0;
asset_header_def->end = height * width * sizeof(uint16_t) + sizeof(size_t) * 2;
asset_header_def->end = sizeof(int) * 2 + height * width * sizeof(uint16_t);
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
fclose(input_file);
return NO_ERROR;
return EXIT_SUCCESS;
}
int parse_png_for_content_and_write(const char *input_file_name, FILE *output_file)
@ -148,7 +179,8 @@ int parse_png_for_content_and_write(const char *input_file_name, FILE *output_fi
if(!input_file)
{
return OPEN_FAILED;
error_printf("Failed to open input file.");
return EXIT_FAILURE;
}
// Check png autenticity.
@ -156,13 +188,15 @@ int parse_png_for_content_and_write(const char *input_file_name, FILE *output_fi
if(fread(sig, sizeof(unsigned char), 8, input_file) != 8)
{
fclose(input_file);
return READ_FAILED;
error_printf("Failed to read input file.");
return EXIT_FAILURE;
}
if(!png_check_sig(sig, 8))
{
fclose(input_file);
return BAD_SIGNATURE;
error_printf("Png file is not valid.");
return EXIT_FAILURE;
}
// PNG structs.
@ -170,7 +204,8 @@ int parse_png_for_content_and_write(const char *input_file_name, FILE *output_fi
if(!png_ptr)
{
fclose(input_file);
return MEMORY_ALLOC_FAILED;
error_printf("Failed to allocate png ptr.");
return EXIT_FAILURE;
}
png_infop info_ptr = png_create_info_struct(png_ptr);
@ -178,7 +213,8 @@ int parse_png_for_content_and_write(const char *input_file_name, FILE *output_fi
{
png_destroy_read_struct(&png_ptr, NULL, NULL);
fclose(input_file);
return MEMORY_ALLOC_FAILED;
error_printf("Failed to allocate png info.");
return EXIT_FAILURE;
}
// Fill structs and load data.
@ -186,23 +222,25 @@ int parse_png_for_content_and_write(const char *input_file_name, FILE *output_fi
png_set_sig_bytes(png_ptr, 8);
png_read_info(png_ptr, info_ptr);
size_t width = png_get_image_width(png_ptr, info_ptr);
size_t height = png_get_image_height(png_ptr, info_ptr);
uint32_t width = png_get_image_width(png_ptr, info_ptr);
uint32_t height = png_get_image_height(png_ptr, info_ptr);
size_t row_length = png_get_rowbytes(png_ptr, info_ptr);
// Write image size.
if(fwrite(&width, sizeof(size_t), 1, output_file) != 1)
if(fwrite(&width, sizeof(width), 1, output_file) != 1)
{
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
fclose(input_file);
return WRITE_FAILED;
error_printf("Failed to write to output file : %d", errno);
return EXIT_FAILURE;
}
if(fwrite(&height, sizeof(size_t), 1, output_file) != 1)
if(fwrite(&height, sizeof(height), 1, output_file) != 1)
{
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
fclose(input_file);
return WRITE_FAILED;
error_printf("Failed to write to output file : %d", errno);
return EXIT_FAILURE;
}
// Prepare storage.
@ -216,9 +254,9 @@ int parse_png_for_content_and_write(const char *input_file_name, FILE *output_fi
uint16_t dst_pixels[width * height * sizeof(uint16_t)];
for(size_t i = 0; i < height; i++)
for(uint32_t i = 0; i < height; i++)
{
for(size_t j = 0; j < width; j += 1)
for(uint32_t j = 0; j < width; j += 1)
{
uint8_t r, g, b;
@ -244,15 +282,16 @@ int parse_png_for_content_and_write(const char *input_file_name, FILE *output_fi
// puts("\033[m");
}
if(fwrite(&dst_pixels, width * height * sizeof(uint16_t), 1, output_file) != 1)
if(fwrite(&dst_pixels, sizeof(uint16_t), width * height, output_file) != width * height)
{
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
fclose(input_file);
return WRITE_FAILED;
error_printf("Failed to write to output file : %d", errno);
return EXIT_FAILURE;
}
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
fclose(input_file);
return NO_ERROR;
return EXIT_SUCCESS;
}

View File

@ -1,47 +0,0 @@
#include "errors.h"
#include <stdio.h>
void print_error(const char *content)
{
printf("\033[31merror\033[m: %s\n", content);
}
void print_error_description(error_t error)
{
switch(error)
{
case NO_EXTENSION:
print_error("file does not have an extension."); break;
case EXTENSION_UNSUPPORTED:
print_error("extension not yet supported."); break;
case OPEN_FAILED:
print_error("failed to open file."); break;
case READ_FAILED:
print_error("failed to read the input file."); break;
case WRITE_FAILED:
print_error("failed to write to output file."); break;
case BAD_SIGNATURE:
print_error("file not valid."); break;
case MEMORY_ALLOC_FAILED:
print_error("memory allocation failed."); break;
case PNG_BIT_DEPTH_UNSUPPORTED:
print_error("png bit depth not supported."); break;
case PNG_COLOR_TYPE_UNSUPPORTED:
print_error("png color type not supported."); break;
case NO_ERROR:
return;
default:
print_error("unknown error"); break;
}
}

View File

@ -6,11 +6,11 @@
typedef struct asset_header_def_t {
char *name;
size_t start, end;
uint32_t start, end;
} asset_header_def_t;
typedef struct asset_file_header_t {
size_t assets_number;
uint32_t assets_number;
asset_header_def_t *assets_header_def;
size_t header_size;

View File

@ -1,23 +1,47 @@
#ifndef ERROR_H
#define ERROR_H
#ifndef ERRORS_H
#define ERRORS_H
typedef enum error_t {
NO_ERROR,
NO_EXTENSION,
EXTENSION_UNSUPPORTED,
OPEN_FAILED,
READ_FAILED,
WRITE_FAILED,
BAD_SIGNATURE,
MEMORY_ALLOC_FAILED,
#include <stdio.h>
#include <errno.h>
#include <assert.h>
// File-format specific errors
PNG_BIT_DEPTH_UNSUPPORTED,
PNG_COLOR_TYPE_UNSUPPORTED
} error_t;
#ifndef DEBUG
#define DEBUG 0
#endif
void print_error(const char *content);
#if DEBUG > 0
#define debug_printf(...) \
do { \
fprintf(stderr, "\033[32mINFO\033[m: " __VA_ARGS__); \
fputc('\n', stderr); \
} while (0)
#else
#define debug_printf(...)
#endif
void print_error_description(error_t error);
#define warning_printf(...) \
do { \
fprintf(stderr, "\033[35mWARNING\033[m: " __VA_ARGS__); \
fputc('\n', stderr); \
} while (0)
#endif // ERROR_H
#define error_printf(...) \
do { \
fprintf(stderr, "\033[31mERROR\033[m: %s:%d:%s(): ", __FILE__, __LINE__, __func__); \
fprintf(stderr, __VA_ARGS__); \
fputc('\n', stderr); \
} while (0)
#define return_failure_int \
do { \
fprintf(stderr, " in %s:%d:%s()\n", __FILE__, __LINE__, __func__); \
return EXIT_FAILURE; \
} while (0);
#define return_failure_ptr \
do { \
fprintf(stderr, " in %s:%d:%s()\n", __FILE__, __LINE__, __func__); \
return NULL; \
} while (0);
#endif // ERRORS_H

View File

@ -20,17 +20,17 @@ int main(int argc, char *argv[])
// Header size and content.
asset_file_header_t asset_file_header;
asset_file_header.assets_number = argc - 2;
asset_file_header.header_size = sizeof(size_t) + sizeof(size_t) * asset_file_header.assets_number;
asset_file_header.header_size = sizeof(asset_file_header.assets_number) + sizeof(uint32_t) * asset_file_header.assets_number;
asset_file_header.assets_header_def = malloc(asset_file_header.assets_number * sizeof(asset_header_def_t));
if(!asset_file_header.assets_header_def)
{
print_error("memory allocation failed.");
error_printf("Failed to allocate memory.");
goto end;
}
// Set assets name.
for(size_t i = 0; i < asset_file_header.assets_number; i++)
for(uint32_t i = 0; i < asset_file_header.assets_number; i++)
{
const char *file_name = argv[i + 2];
@ -54,19 +54,13 @@ int main(int argc, char *argv[])
output_asset_file = fopen(argv[1], "wb");
if(!output_asset_file)
{
print_error("could not create output file.");
error_printf("could not create output file.");
goto end;
}
for(size_t i = 0; i < asset_file_header.assets_number; i++)
for(uint32_t i = 0; i < asset_file_header.assets_number; i++)
{
int ret = parse_file_for_header(argv[i + 2], &asset_file_header.assets_header_def[i]);
if(ret)
{
print_error_description(ret);
goto end;
}
if(parse_file_for_header(argv[i + 2], &asset_file_header.assets_header_def[i])) return_failure_int;
// Calculate absolute position of assets in the file.
if(i) asset_file_header.assets_header_def[i].start = asset_file_header.assets_header_def[i - 1].end;
@ -76,19 +70,13 @@ int main(int argc, char *argv[])
if(write_header_to_file(&asset_file_header, output_asset_file))
{
print_error("can't write to output file.");
error_printf("Failed to write to output file : %d", errno);
goto end;
}
for(size_t i = 0; i < asset_file_header.assets_number; i++)
for(uint32_t i = 0; i < asset_file_header.assets_number; i++)
{
int ret = parse_file_for_content_and_write(argv[i + 2], output_asset_file);
if(ret)
{
print_error_description(ret);
goto end;
}
if(parse_file_for_content_and_write(argv[i + 2], output_asset_file)) return_failure_int;
}
exit_status = EXIT_SUCCESS;
@ -96,8 +84,13 @@ int main(int argc, char *argv[])
end:
if(asset_file_header.assets_header_def)
{
for(size_t i = 0; i < asset_file_header.assets_number; i++)
free(asset_file_header.assets_header_def[i].name);
for(uint32_t i = 0; i < asset_file_header.assets_number; i++)
{
if(asset_file_header.assets_header_def[i].name)
{
free(asset_file_header.assets_header_def[i].name);
}
}
free(asset_file_header.assets_header_def);
}