mirror of
https://github.com/weiju/amiga-stuff
synced 2025-11-19 16:01:31 +00:00
fixed bug in IFF reading
char buffer is not automatically aligned on a word boundary on a plain 68000, so we need to ensure about that ourselves checked on a500 setup
This commit is contained in:
@ -1,6 +1,6 @@
|
||||
#CC=vc +aos68k
|
||||
CC=vc +kick13
|
||||
CFLAGS=-c99 -I$(NDK_INC)
|
||||
CFLAGS=-c99 -I$(NDK_INC) -DDEBUG
|
||||
|
||||
all: iffview
|
||||
|
||||
|
||||
@ -69,7 +69,7 @@ struct Gadget gadgets[] = {
|
||||
};
|
||||
|
||||
BOOL initialized = 0;
|
||||
#define PATHBUFFER_SIZE 32
|
||||
#define PATHBUFFER_SIZE 200
|
||||
char dirname[PATHBUFFER_SIZE + 1];
|
||||
BPTR flock;
|
||||
LONG error;
|
||||
@ -101,6 +101,8 @@ struct Requester *open_file(struct Window *window)
|
||||
|
||||
/* scan current directory */
|
||||
puts("scanning directory...");
|
||||
/*
|
||||
// on AmigaOS 1.x, this function does not exist !!!
|
||||
GetCurrentDirName(dirname, PATHBUFFER_SIZE);
|
||||
printf("current dir: '%s'\n", dirname);
|
||||
flock = Lock(dirname, SHARED_LOCK);
|
||||
@ -110,11 +112,11 @@ struct Requester *open_file(struct Window *window)
|
||||
}
|
||||
error = IoErr();
|
||||
if (error != ERROR_NO_MORE_ENTRIES) {
|
||||
/* an error occurred */
|
||||
puts("unknown I/O error, TODO handle");
|
||||
}
|
||||
}
|
||||
UnLock(flock);
|
||||
*/
|
||||
|
||||
initialized = 1;
|
||||
}
|
||||
|
||||
@ -29,6 +29,7 @@
|
||||
#include <clib/alib_stdio_protos.h>
|
||||
#endif
|
||||
#include "filereq.h"
|
||||
#include "ilbm.h"
|
||||
|
||||
#define WIN_LEFT 10
|
||||
#define WIN_TOP 10
|
||||
@ -169,12 +170,29 @@ void setup_menu()
|
||||
SetMenuStrip(window, &menus[0]);
|
||||
}
|
||||
|
||||
struct Image image = { 0, 0, 0, 0, 0, NULL, 0, 0, NULL};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
ILBMData *ilbm_data = NULL;
|
||||
if (window = OpenWindow(&newwin)) {
|
||||
int wordwidth, finalsize;
|
||||
setup_menu();
|
||||
ilbm_data = parse_file("examples/Kickstart13.iff");
|
||||
image.Width = ilbm_data->bmheader->w;
|
||||
image.Height = ilbm_data->bmheader->h;
|
||||
image.Depth = ilbm_data->bmheader->nPlanes;
|
||||
wordwidth = (image.Width + 16) / 16;
|
||||
finalsize = wordwidth * image.Height * image.Depth * sizeof(UWORD);
|
||||
image.ImageData = AllocMem(finalsize, MEMF_CHIP);
|
||||
printf("loaded size: %d, final size: %d\n", ilbm_data->data_bytes, finalsize);
|
||||
memcpy(image.ImageData, ilbm_data->imgdata, ilbm_data->data_bytes);
|
||||
image.PlanePick = (1 << image.Depth) - 1;
|
||||
// Note: rastport is the entire window, including title bars
|
||||
DrawImage(window->RPort, &image, 5, 10);
|
||||
handle_events();
|
||||
}
|
||||
if (ilbm_data) free_ilbm_data(ilbm_data);
|
||||
cleanup();
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -59,13 +59,14 @@ BitMapHeader *read_BMHD(FILE *fp, int datasize)
|
||||
return header;
|
||||
}
|
||||
|
||||
ColorRegister *read_CMAP(FILE *fp, int datasize)
|
||||
ColorRegister *read_CMAP(FILE *fp, int datasize, int *ncols)
|
||||
{
|
||||
int num_colors = datasize / 3, bytes_read;
|
||||
ColorRegister *colors;
|
||||
|
||||
colors = malloc(datasize);
|
||||
bytes_read = fread(colors, sizeof(ColorRegister), num_colors, fp);
|
||||
*ncols = num_colors;
|
||||
return colors;
|
||||
}
|
||||
|
||||
@ -98,12 +99,14 @@ void read_CRNG(FILE *fp, int datasize)
|
||||
#endif
|
||||
}
|
||||
|
||||
UBYTE *read_BODY(FILE *fp, int datasize, BitMapHeader *bmheader)
|
||||
UBYTE *read_BODY(FILE *fp, int datasize, BitMapHeader *bmheader, int *data_bytes)
|
||||
{
|
||||
ULONG bytes_read;
|
||||
BYTE *buffer = malloc(datasize), *dst_buffer;
|
||||
BYTE *buffer, *dst_buffer;
|
||||
int src_i = 0, dst_i = 0, dst_size;
|
||||
|
||||
buffer = malloc(datasize);
|
||||
*data_bytes = datasize;
|
||||
dst_size = bmheader->w * bmheader->h * bmheader->nPlanes / 8;
|
||||
printf("target size: %d, data size: %d\n", dst_size, datasize);
|
||||
bytes_read = fread(buffer, sizeof(char), datasize, fp);
|
||||
@ -113,6 +116,7 @@ UBYTE *read_BODY(FILE *fp, int datasize, BitMapHeader *bmheader)
|
||||
int i;
|
||||
/* decompress data */
|
||||
dst_buffer = malloc(dst_size);
|
||||
*data_bytes = dst_size;
|
||||
while (src_i < datasize) {
|
||||
b0 = buffer[src_i++];
|
||||
if (b0 >= 0) {
|
||||
@ -130,64 +134,58 @@ UBYTE *read_BODY(FILE *fp, int datasize, BitMapHeader *bmheader)
|
||||
|
||||
#define skip_chunk(fp, datasize) fseek(fp, datasize, SEEK_CUR)
|
||||
|
||||
IFFData *read_chunks(FILE *fp, int filesize, int total_read)
|
||||
ILBMData *read_chunks(FILE *fp, int filesize, int total_read)
|
||||
{
|
||||
char id[5], buffer[CHUNK_HEADER_SIZE];
|
||||
int i, bytes_read, datasize;
|
||||
BitMapHeader *bmheader = NULL;
|
||||
ColorRegister *colors = NULL;
|
||||
UBYTE *imgdata = NULL;
|
||||
IFFData *result = malloc(sizeof(IFFData));
|
||||
|
||||
while (total_read < filesize) {
|
||||
|
||||
bytes_read = fread(buffer, sizeof(char), 8, fp);
|
||||
|
||||
for (i = 0; i < 4; i++) id[i] = buffer[i];
|
||||
id[4] = 0;
|
||||
// make sure that our char buffers are aligned on word boundaries
|
||||
unsigned char buffer[CHUNK_HEADER_SIZE], id[5];
|
||||
int i, bytes_read, datasize, imgdata_size;
|
||||
BitMapHeader *bmheader = NULL;
|
||||
ColorRegister *colors = NULL;
|
||||
UBYTE *imgdata = NULL;
|
||||
ILBMData *result = calloc(1, sizeof(ILBMData));
|
||||
|
||||
while (total_read < filesize) {
|
||||
bytes_read = fread(buffer, sizeof(char), 8, fp);
|
||||
for (i = 0; i < 4; i++) id[i] = buffer[i];
|
||||
id[4] = 0;
|
||||
#ifdef LITTLE_ENDIAN
|
||||
datasize = __bswap_32(*((ULONG *) &buffer[4]));
|
||||
datasize = __bswap_32(*((ULONG *) &buffer[4]));
|
||||
#else
|
||||
datasize = *((ULONG *) &buffer[4]);
|
||||
datasize = *((ULONG *) &buffer[4]);
|
||||
#endif
|
||||
|
||||
if (!strncmp("BMHD", buffer, 4)) bmheader = read_BMHD(fp, datasize);
|
||||
else if (!strncmp("CMAP", buffer, 4)) colors = read_CMAP(fp, datasize);
|
||||
else if (!strncmp("CRNG", buffer, 4)) read_CRNG(fp, datasize);
|
||||
else if (!strncmp("CAMG", buffer, 4)) read_CAMG(fp, datasize);
|
||||
else if (!strncmp("BODY", buffer, 4)) imgdata = read_BODY(fp, datasize, bmheader);
|
||||
else {
|
||||
if (!strncmp("BMHD", buffer, 4)) bmheader = read_BMHD(fp, datasize);
|
||||
else if (!strncmp("CMAP", buffer, 4)) colors = read_CMAP(fp, datasize, &result->num_colors);
|
||||
else if (!strncmp("CRNG", buffer, 4)) read_CRNG(fp, datasize);
|
||||
else if (!strncmp("CAMG", buffer, 4)) read_CAMG(fp, datasize);
|
||||
else if (!strncmp("BODY", buffer, 4)) imgdata = read_BODY(fp, datasize, bmheader, &imgdata_size);
|
||||
else {
|
||||
#ifdef DEBUG
|
||||
printf("WARNING - Unsupported chunk '%s', size: %d\n", id, datasize);
|
||||
printf("WARNING - Unsupported chunk '%s', size: %d\n", id, datasize);
|
||||
#endif
|
||||
skip_chunk(fp, datasize);
|
||||
skip_chunk(fp, datasize);
|
||||
}
|
||||
/* Padding to even if necessary */
|
||||
if (datasize % 2) {
|
||||
fseek(fp, 1, SEEK_CUR);
|
||||
datasize++;
|
||||
}
|
||||
total_read += datasize + CHUNK_HEADER_SIZE;
|
||||
}
|
||||
/* Padding to even if necessary */
|
||||
if (datasize % 2) {
|
||||
fseek(fp, 1, SEEK_CUR);
|
||||
datasize++;
|
||||
}
|
||||
total_read += datasize + CHUNK_HEADER_SIZE;
|
||||
}
|
||||
printf("total read: %d\n", total_read);
|
||||
/*
|
||||
if (imgdata) free(imgdata);
|
||||
if (colors) free(colors);
|
||||
if (bmheader) free(bmheader);*/
|
||||
result->imgdata = imgdata;
|
||||
result->colors = colors;
|
||||
result->bmheader = bmheader;
|
||||
return result;
|
||||
printf("total read: %d\n", total_read);
|
||||
result->imgdata = imgdata;
|
||||
result->data_bytes = imgdata_size;
|
||||
result->colors = colors;
|
||||
result->bmheader = bmheader;
|
||||
return result;
|
||||
}
|
||||
|
||||
IFFData *parse_file(const char *path)
|
||||
ILBMData *parse_file(const char *path)
|
||||
{
|
||||
FILE *fp;
|
||||
char buffer[IFF_HEADER_SIZE];
|
||||
size_t bytes_read;
|
||||
ULONG filesize, total_read = 0;
|
||||
IFFData *result = NULL;
|
||||
ILBMData *result = NULL;
|
||||
|
||||
fp = fopen(path, "rb");
|
||||
|
||||
@ -214,10 +212,11 @@ IFFData *parse_file(const char *path)
|
||||
} else {
|
||||
puts("not an IFF file");
|
||||
}
|
||||
fclose(fp);
|
||||
return result;
|
||||
}
|
||||
|
||||
void free_iffdata(IFFData *data)
|
||||
void free_ilbm_data(ILBMData *data)
|
||||
{
|
||||
if (data) {
|
||||
if (data->colors) free(data->colors);
|
||||
@ -227,15 +226,24 @@ void free_iffdata(IFFData *data)
|
||||
}
|
||||
}
|
||||
|
||||
void print_ilbm_info(ILBMData *data)
|
||||
{
|
||||
printf("width: %d, height: %d, # planes: %d # colors: %d\n",
|
||||
(int) data->bmheader->w,
|
||||
(int) data->bmheader->h,
|
||||
(int) data->bmheader->nPlanes,
|
||||
data->num_colors);
|
||||
}
|
||||
|
||||
#ifdef STANDALONE
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc <= 1) {
|
||||
puts("usage: ilbm <image-file>");
|
||||
puts("usage: ilbm <image-file>");
|
||||
} else {
|
||||
IFFData *data = parse_file(argv[1]);
|
||||
free_iffdata(data);
|
||||
ILBMData *data = parse_file(argv[1]);
|
||||
print_ilbm_info(data);
|
||||
free_ilbm_data(data);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -34,6 +34,9 @@
|
||||
#define LONG int32_t
|
||||
#define WORD int16_t
|
||||
#define BYTE int8_t
|
||||
typedef int BOOL;
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
#define HAM 0x800
|
||||
#define EXTRA_HALFBRITE 0x80
|
||||
@ -77,12 +80,13 @@ typedef struct {
|
||||
UBYTE low, high;
|
||||
} CRange;
|
||||
|
||||
typedef struct _IFFData {
|
||||
typedef struct _ILBMData {
|
||||
BitMapHeader *bmheader;
|
||||
int num_colors, data_bytes;
|
||||
ColorRegister *colors;
|
||||
UBYTE *imgdata;
|
||||
} IFFData;
|
||||
} ILBMData;
|
||||
|
||||
extern IFFData *parse_file(const char *path);
|
||||
extern void free_iffdata(IFFData *data);
|
||||
extern ILBMData *parse_file(const char *path);
|
||||
extern void free_ilbm_data(ILBMData *data);
|
||||
#endif /* __ILBM_H__ */
|
||||
|
||||
Reference in New Issue
Block a user