Skip to content

Commit

Permalink
More moves to new file API.
Browse files Browse the repository at this point in the history
  • Loading branch information
indigoparadox committed Jun 4, 2024
1 parent 80ee7ad commit 19b08f9
Show file tree
Hide file tree
Showing 3 changed files with 163 additions and 29 deletions.
111 changes: 99 additions & 12 deletions src/mfile.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,13 @@ typedef struct MFILE_CADDY mfile_t;
error_printf( "unknown file type: %d", (p_file)->type ); \
break;

#define mfile_has_bytes( p_file ) \
((MFILE_CADDY_TYPE_FILE_READ == ((p_file)->type) ? \
(off_t)ftell( (p_file)->h.file ) : \
(p_file)->mem_cursor) < (p_file)->sz)

#ifdef MFILE_LEGACY_MACROS

#define mfile_seek( p_file, idx ) \
switch( (p_file)->type ) { \
case MFILE_CADDY_TYPE_FILE_READ: \
Expand All @@ -85,16 +92,14 @@ typedef struct MFILE_CADDY mfile_t;
mfile_default_case( p_file ); \
}

#define mfile_has_bytes( p_file ) \
((MFILE_CADDY_TYPE_FILE_READ == ((p_file)->type) ? \
(off_t)ftell( (p_file)->h.file ) : \
(p_file)->mem_cursor) < (p_file)->sz)

#define mfile_cread( p_file, p_c ) \
switch( (p_file)->type ) { \
case MFILE_CADDY_TYPE_FILE_READ: \
(p_file)->last_read = fread( p_c, 1, 1, (p_file)->h.file ); \
break; \
case MFILE_CADDY_TYPE_MEM_BUFFER: \
((uint8_t*)(p_c))[0] = (p_file)->mem_buffer[(p_file)->mem_cursor++]; \
break; \
mfile_default_case( p_file ); \
}

Expand Down Expand Up @@ -196,6 +201,8 @@ typedef struct MFILE_CADDY mfile_t;
mfile_default_case( p_file ); \
}

#endif /* MFILE_LEGACY_MACROS */

#define mfile_get_sz( p_file ) ((p_file)->sz)

#define mfile_reset( p_file ) \
Expand All @@ -216,7 +223,7 @@ MERROR_RETVAL mfile_read_line( mfile_t*, char* buffer, off_t buffer_sz );
/**
* \brief Lock a buffer and assign it to an ::mfile_t to read/write.
*/
MERROR_RETVAL mfile_lock_buffer( MAUG_MHANDLE, mfile_t* p_file );
MERROR_RETVAL mfile_lock_buffer( MAUG_MHANDLE, off_t, mfile_t* p_file );

/**
* \brief Open a file and read it into memory or memory-map it.
Expand Down Expand Up @@ -248,11 +255,12 @@ MERROR_RETVAL mfile_file_read_int(
MERROR_RETVAL retval = MERROR_OK;
ssize_t last_read = 0;

assert( MFILE_CADDY_TYPE_FILE_READ == p_file->type );

if( MFILE_READ_FLAG_LSBF == (MFILE_READ_FLAG_LSBF & flags) ) {
/* Shrink the buffer moving right and read into it. */
while( 0 < buf_sz ) {
last_read = fread( buf, 1, 1, p_file->h.file );
debug_printf( 1, "byte: 0x%02x", *(buf + (buf_sz - 1)) );
if( 0 >= last_read ) {
error_printf( "unable to read from file!" );
retval = MERROR_FILE;
Expand All @@ -266,7 +274,6 @@ MERROR_RETVAL mfile_file_read_int(
/* Move to the end of the output buffer and read backwards. */
while( 0 < buf_sz ) {
last_read = fread( (buf + (buf_sz - 1)), 1, 1, p_file->h.file );
debug_printf( 1, "byte: 0x%02x", *(buf + (buf_sz - 1)) );
if( 0 >= last_read ) {
error_printf( "unable to read from file!" );
retval = MERROR_FILE;
Expand All @@ -286,6 +293,8 @@ MERROR_RETVAL mfile_file_read_int(
MERROR_RETVAL mfile_file_seek( struct MFILE_CADDY* p_file, off_t pos ) {
MERROR_RETVAL retval = MERROR_OK;

assert( MFILE_CADDY_TYPE_FILE_READ == p_file->type );

if( fseek( p_file->h.file, pos, SEEK_SET ) ) {
error_printf( "unable to seek file!" );
retval = MERROR_FILE;
Expand All @@ -296,6 +305,76 @@ MERROR_RETVAL mfile_file_seek( struct MFILE_CADDY* p_file, off_t pos ) {

/* === */

MERROR_RETVAL mfile_mem_read_int(
struct MFILE_CADDY* p_file, uint8_t* buf, size_t buf_sz, uint8_t flags
) {
MERROR_RETVAL retval = MERROR_OK;

assert( MFILE_CADDY_TYPE_MEM_BUFFER == p_file->type );

if( MFILE_READ_FLAG_LSBF != (MFILE_READ_FLAG_LSBF & flags) ) {
/* Shrink the buffer moving right and read into it. */
while( 0 < buf_sz ) {
/* Check for EOF. */
if( p_file->mem_cursor >= p_file->sz ) {
retval = MERROR_FILE;
error_printf(
"cursor " OFF_T_FMT " beyond end of buffer " OFF_T_FMT "!",
p_file->mem_cursor, p_file->sz );
goto cleanup;
}

buf[buf_sz - 1] = p_file->mem_buffer[p_file->mem_cursor];
debug_printf( 1, "byte #" SIZE_T_FMT " = # " OFF_T_FMT,
buf_sz - 1, p_file->mem_cursor );
buf_sz--;
p_file->mem_cursor++;
}

} else {
/* Move to the end of the output buffer and read backwards. */
while( 0 < buf_sz ) {
/* Check for EOF. */
if( p_file->mem_cursor >= p_file->sz ) {
retval = MERROR_FILE;
error_printf(
"cursor " OFF_T_FMT " beyond end of buffer " OFF_T_FMT "!",
p_file->mem_cursor, p_file->sz );
goto cleanup;
}

buf[buf_sz - 1] = p_file->mem_buffer[p_file->mem_cursor];
debug_printf( 1, "byte #" SIZE_T_FMT " = # " OFF_T_FMT,
buf_sz - 1, p_file->mem_cursor );
buf_sz--;
buf++;
p_file->mem_cursor++;
}
}

cleanup:

return retval;
}

/* === */

MERROR_RETVAL mfile_mem_seek( struct MFILE_CADDY* p_file, off_t pos ) {
MERROR_RETVAL retval = MERROR_OK;

assert( MFILE_CADDY_TYPE_MEM_BUFFER == p_file->type );

p_file->mem_cursor = pos;

debug_printf( 1,
"seeking memory buffer to position " OFF_T_FMT " (" OFF_T_FMT ")",
pos, p_file->mem_cursor );

return retval;
}

/* === */

MERROR_RETVAL mfile_read_block( mfile_t* p_f, uint8_t* buf, off_t buf_sz ) {
MERROR_RETVAL retval = MERROR_OK;
off_t i_read = 0;
Expand Down Expand Up @@ -346,7 +425,7 @@ MERROR_RETVAL mfile_read_line( mfile_t* p_f, char* buffer, off_t buffer_sz ) {
break;
}

mfile_cread( p_f, &(buffer[i]) );
p_f->read_int( p_f, (uint8_t*)&(buffer[i]), 1, 0 );
if( '\n' == buffer[i] ) {
/* Break on newline and overwrite it below. */
break;
Expand All @@ -364,15 +443,23 @@ MERROR_RETVAL mfile_read_line( mfile_t* p_f, char* buffer, off_t buffer_sz ) {
return retval;
}

MERROR_RETVAL mfile_lock_buffer( MAUG_MHANDLE handle, mfile_t* p_file ) {
MERROR_RETVAL mfile_lock_buffer(
MAUG_MHANDLE handle, off_t handle_sz, mfile_t* p_file
) {
MERROR_RETVAL retval = MERROR_OK;

debug_printf( 1, "locking handle %p as file %p...", handle, p_file );
debug_printf( 1,
"locking handle %p as file %p (" OFF_T_FMT " bytes)...",
handle, p_file, handle_sz );

maug_mzero( p_file, sizeof( mfile_t ) );
maug_mzero( p_file, sizeof( struct MFILE_CADDY ) );
maug_mlock( handle, p_file->mem_buffer );
p_file->type = MFILE_CADDY_TYPE_MEM_BUFFER;

p_file->read_int = mfile_mem_read_int;
p_file->seek = mfile_mem_seek;
p_file->sz = handle_sz;

return retval;
}

Expand Down
79 changes: 63 additions & 16 deletions src/mfmt.h
Original file line number Diff line number Diff line change
Expand Up @@ -257,8 +257,15 @@ MERROR_RETVAL mfmt_decode_rle(
maug_mlock( buffer_out_h, buffer_out );

do {
retval = p_file_in->seek( p_file_in, file_offset + in_byte_cur++ );
maug_cleanup_if_not_ok();
retval = p_file_in->read_int( p_file_in, &byte_buffer, 1, 0 );
maug_cleanup_if_not_ok();

/*
mfile_cread_at(
p_file_in, &(byte_buffer), file_offset + in_byte_cur++ );
*/
debug_printf( MFMT_TRACE_RLE_LVL, "in byte " SIZE_T_FMT
": 0x%02x, out byte " SIZE_T_FMT ", line px: %u",
in_byte_cur, byte_buffer, out_byte_cur, line_px_written );
Expand Down Expand Up @@ -433,7 +440,8 @@ MERROR_RETVAL mfmt_read_bmp_header(
header_offset = 14; /* Size of info header. */

/* Grab file header info. */
p_file_in->seek( p_file_in, file_offset + 2 );
retval = p_file_in->seek( p_file_in, file_offset + 2 );
maug_cleanup_if_not_ok();
retval = p_file_in->read_int( p_file_in,
(uint8_t*)&(header_bmp_file->file_sz), 4, MFILE_READ_FLAG_LSBF );
maug_cleanup_if_not_ok();
Expand Down Expand Up @@ -474,32 +482,55 @@ MERROR_RETVAL mfmt_read_bmp_header(
}

/* Read bitmap image dimensions. */
mfile_u32read_lsbf_at( p_file_in, &(header_bmp_info->width),
retval = p_file_in->seek( p_file_in,
file_offset + header_offset + MFMT_BMPINFO_OFS_WIDTH );
mfile_u32read_lsbf_at( p_file_in, &(header_bmp_info->height),
maug_cleanup_if_not_ok();
retval = p_file_in->read_int( p_file_in,
(uint8_t*)&(header_bmp_info->width), 4, MFILE_READ_FLAG_LSBF );
maug_cleanup_if_not_ok();

retval = p_file_in->seek( p_file_in,
file_offset + header_offset + MFMT_BMPINFO_OFS_HEIGHT );
maug_cleanup_if_not_ok();
retval = p_file_in->read_int( p_file_in,
(uint8_t*)&(header_bmp_info->height), 4, MFILE_READ_FLAG_LSBF );
maug_cleanup_if_not_ok();

if( 0 > header_bmp_info->height ) {
debug_printf(
MFMT_TRACE_BMP_LVL, "bitmap Y coordinate is inverted..." );
*p_flags |= MFMT_PX_FLAG_INVERT_Y;
}

mfile_u32read_lsbf_at( p_file_in, &(header_bmp_info->img_sz),
retval = p_file_in->seek( p_file_in,
file_offset + header_offset + MFMT_BMPINFO_OFS_SZ );
maug_cleanup_if_not_ok();
retval = p_file_in->read_int( p_file_in,
(uint8_t*)&(header_bmp_info->img_sz), 4, MFILE_READ_FLAG_LSBF );
maug_cleanup_if_not_ok();

/* Check that we're a palettized image. */
mfile_u16read_lsbf_at( p_file_in, &(header_bmp_info->bpp),
retval = p_file_in->seek( p_file_in,
file_offset + header_offset + MFMT_BMPINFO_OFS_BPP );
maug_cleanup_if_not_ok();
retval = p_file_in->read_int( p_file_in,
(uint8_t*)&(header_bmp_info->bpp), 2, MFILE_READ_FLAG_LSBF );
maug_cleanup_if_not_ok();

if( 8 < header_bmp_info->bpp ) {
error_printf( "invalid bitmap bpp: %u", header_bmp_info->bpp );
retval = MERROR_FILE;
goto cleanup;
}

/* Make sure there's no weird compression. */
mfile_u32read_lsbf_at( p_file_in,
&(header_bmp_info->compression),
retval = p_file_in->seek( p_file_in,
file_offset + header_offset + MFMT_BMPINFO_OFS_COMPRESSION );
maug_cleanup_if_not_ok();
retval = p_file_in->read_int( p_file_in,
(uint8_t*)&(header_bmp_info->compression), 4, MFILE_READ_FLAG_LSBF );
maug_cleanup_if_not_ok();

if(
MFMT_BMP_COMPRESSION_NONE != header_bmp_info->compression &&
MFMT_BMP_COMPRESSION_RLE4 != header_bmp_info->compression
Expand All @@ -510,9 +541,14 @@ MERROR_RETVAL mfmt_read_bmp_header(
goto cleanup;
}

mfile_u32read_lsbf_at( p_file_in,
&(header_bmp_info->palette_ncolors),
/* Get the number of palette colors. */

retval = p_file_in->seek( p_file_in,
file_offset + header_offset + MFMT_BMPINFO_OFS_PAL_SZ );
maug_cleanup_if_not_ok();
retval = p_file_in->read_int( p_file_in,
(uint8_t*)&(header_bmp_info->palette_ncolors), 4, MFILE_READ_FLAG_LSBF );
maug_cleanup_if_not_ok();

debug_printf( 2, "bitmap is " UPRINTF_S32_FMT " x " UPRINTF_S32_FMT
", %u bpp (palette has " UPRINTF_U32_FMT " colors)",
Expand All @@ -535,14 +571,19 @@ MERROR_RETVAL mfmt_read_bmp_palette(

mfmt_bmp_check_header();

mfile_seek( p_file_in, file_offset );
retval = p_file_in->seek( p_file_in, file_offset );
maug_cleanup_if_not_ok();
for( i = 0 ; header_bmp_info->palette_ncolors > i ; i++ ) {
if( i * 4 > palette_sz ) {
error_printf( "palette overflow!" );
retval = MERROR_OVERFLOW;
goto cleanup;
}
mfile_u32read_lsbf( p_file_in, &(palette[i]) );

retval = p_file_in->read_int( p_file_in,
(uint8_t*)&(palette[i]), 4, MFILE_READ_FLAG_LSBF );
maug_cleanup_if_not_ok();

debug_printf( MFMT_TRACE_BMP_LVL,
"set palette entry " SIZE_T_FMT " to " UPRINTF_X32_FMT,
i, palette[i] );
Expand Down Expand Up @@ -617,7 +658,9 @@ MERROR_RETVAL mfmt_read_bmp_px(
MFMT_DECOMP_FLAG_4BIT );
maug_cleanup_if_not_ok();

retval = mfile_lock_buffer( decomp_buffer_h, &file_decomp );
retval = mfile_lock_buffer(
decomp_buffer_h, header_bmp_info->width * header_bmp_info->height,
&file_decomp );
maug_cleanup_if_not_ok();

/* Switch out the file used below for the decomp buffer mfile_t. */
Expand All @@ -634,7 +677,7 @@ MERROR_RETVAL mfmt_read_bmp_px(

y = header_bmp_info->height - 1;
byte_out_idx = mfmt_read_bmp_px_out_idx();
mfile_seek( p_file_bmp, file_offset );
p_file_bmp->seek( p_file_bmp, file_offset );
while( 0 <= y ) {
/* Each iteration is a single, fresh pixel. */
pixel_buffer = 0;
Expand Down Expand Up @@ -666,8 +709,12 @@ MERROR_RETVAL mfmt_read_bmp_px(
}

/* Move on to a new byte. */
mfile_cread(
p_file_bmp, &(byte_buffer) );
/* TODO: Bad cursor? */
retval = p_file_bmp->read_int( p_file_bmp, &byte_buffer, 1, 0 );
maug_cleanup_if_not_ok();
/*
mfile_cread( p_file_bmp, &(byte_buffer) );
*/
byte_in_idx++;

/* Start at 8 bits from the right (0 from the left). */
Expand Down Expand Up @@ -717,7 +764,7 @@ MERROR_RETVAL mfmt_read_bmp_px(
x = 0;
while( byte_in_idx % 4 != 0 ) {
byte_in_idx++;
mfile_seek( p_file_bmp, file_offset + byte_in_idx );
p_file_bmp->seek( p_file_bmp, file_offset + byte_in_idx );
}

/* Move to the next row of the output. */
Expand Down
2 changes: 1 addition & 1 deletion src/retrotil.h
Original file line number Diff line number Diff line change
Expand Up @@ -794,7 +794,7 @@ MERROR_RETVAL retrotile_parse_json_file(
}

while( mfile_has_bytes( &buffer ) ) {
mfile_cread( &buffer, &c );
buffer.read_int( &buffer, (uint8_t*)&c, 1, 0 );
retval = mjson_parse_c( &(parser->jparser), c );
if( MERROR_OK != retval ) {
error_printf( "error parsing JSON!" );
Expand Down

0 comments on commit 19b08f9

Please sign in to comment.