ILBM lib enhancements

convert interleaved to plane-by plane data, display in Intuition
is changed to consider the imaga data width
This commit is contained in:
Wei-ju Wu
2016-01-11 16:14:55 -08:00
parent 3b04b00490
commit 3db8ee02ba
5 changed files with 77 additions and 7 deletions
+3 -1
View File
@@ -11,5 +11,7 @@ iffview: iffview.o ilbm.o filereq.o
$(CC) $(CFLAGS) $^ -lamiga -lauto -o $@
# Mostly for testing
# interestingly, when defining std=c99, LITTLE_ENDIAN disappears as a definition
# in gcc, so we define it explicitly
ilbm: ilbm.c
gcc -o $@ $< -DSTANDALONE -DDEBUG
gcc -o $@ $< -DSTANDALONE -DDEBUG -std=c99 -DLITTLE_ENDIAN
+6
View File
@@ -100,6 +100,12 @@ struct Requester *open_file(struct Window *window)
requester.ReqText = &labels[0];
/* scan current directory */
/*
on AmigaOS versions before 36 (essentially all 1.x versions), the
function GetCurrentDirName() does not exist, but it's obtainable
by calling Cli() and querying the returned CommandLineInterface
structure
*/
puts("scanning directory...");
/*
// on AmigaOS 1.x, this function does not exist !!!
+16 -6
View File
@@ -172,22 +172,32 @@ void setup_menu()
struct Image image = { 0, 0, 0, 0, 0, NULL, 0, 0, NULL};
/* Defined automatically in VBCC */
extern struct Library *DOSBase;
int main(int argc, char **argv)
{
/* version: e.g. 34, revision e.g. 3 for Kickstart 1.3 */
printf("DOS, version: %d, revision: %d\n",
(int) DOSBase->lib_Version, (int) DOSBase->lib_Revision);
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);
int wordwidth = (image.Width + 16) / 16;
int finalsize = wordwidth * image.Height * image.Depth * sizeof(UWORD);
image.ImageData = AllocMem(finalsize, MEMF_CHIP|MEMF_CLEAR);
ilbm_to_image_data((char *) image.ImageData, ilbm_data, wordwidth * 16, image.Height);
image.PlanePick = (1 << image.Depth) - 1;
/*
Note that the image width is now set to the data's image width.
Displayed correctly now.
*/
image.Width = wordwidth * 16;
// Note: rastport is the entire window, including title bars
DrawImage(window->RPort, &image, 5, 10);
handle_events();
+51
View File
@@ -196,8 +196,10 @@ ILBMData *parse_file(const char *path)
if (!strncmp("FORM", buffer, 4)) {
#ifdef LITTLE_ENDIAN
puts("little endian");
filesize = __bswap_32(*((ULONG *) &buffer[4])) + CHUNK_HEADER_SIZE;
#else
puts("big endian");
filesize = *((ULONG *) &buffer[4]) + CHUNK_HEADER_SIZE;
#endif
@@ -235,6 +237,46 @@ void print_ilbm_info(ILBMData *data)
data->num_colors);
}
/*
* ILBM interleaved bit maps -> Intuition Image data
* ILBM is interleaved
* - plane 0/row 0 -> plane 1/row 0 -> ... plane 0/row 1 -> plane 1/row 1 ->...
* - rows are multiples of 8
*
* but Intuition Image expects its data
* - plane-by-plane
* - as a multiple of 16
*/
void ilbm_to_image_data(char *dest, ILBMData *data, int dest_width, int dest_height)
{
if (data->bmheader->w % 8 != 0) {
puts("ERROR: source width must be multiple of 8");
return;
}
if (dest_width % 16 != 0) {
puts("ERROR: destination width must be multiple of 16");
return;
}
if (dest_width < data->bmheader->w || dest_height < data->bmheader->h) {
puts("ERROR: destination dimensions are smaller than source");
return;
}
int src_bytes_per_row = data->bmheader->w / 8;
int dest_bytes_per_row = dest_width / 8;
char *src_ptr = data->imgdata;
int src_offset, img_height = data->bmheader->h, num_planes = data->bmheader->nPlanes;
int row_data_size = num_planes * src_bytes_per_row;
for (int plane = 0; plane < num_planes; plane++) {
// copy row-by-row
for (int row = 0; row < img_height; row++) {
src_offset = (row * row_data_size) + (plane * src_bytes_per_row);
memcpy(dest, src_ptr + src_offset, src_bytes_per_row);
dest += dest_bytes_per_row;
}
}
}
#ifdef STANDALONE
int main(int argc, char **argv)
{
@@ -243,6 +285,15 @@ int main(int argc, char **argv)
} else {
ILBMData *data = parse_file(argv[1]);
print_ilbm_info(data);
int wordwidth = (data->bmheader->w + 16) / 16;
int destWidth = wordwidth * 16;
int destHeight = data->bmheader->h;
int finalsize = wordwidth * data->bmheader->h * data->bmheader->nPlanes * 2;
printf("loaded size: %d, final size: %d\n", data->data_bytes, finalsize);
char *dest = calloc(finalsize, sizeof(char));
ilbm_to_image_data(dest, data, destWidth, destHeight);
free(dest);
free_ilbm_data(data);
}
}
+1
View File
@@ -89,4 +89,5 @@ typedef struct _ILBMData {
extern ILBMData *parse_file(const char *path);
extern void free_ilbm_data(ILBMData *data);
extern void ilbm_to_image_data(char *dest, ILBMData *data, int dest_width, int dest_height);
#endif /* __ILBM_H__ */