SSJX.CO.UK
Content

Converting Iff2Bmp to D

This is a summary of porting the Amiga IFF ILBM converter to the D Programming Language.

This program went through several different languages, each had different strengths and weaknesses:

I was happy with the Pascal version but thought porting it to D would be interesting. The D version may be a little quicker (not checked), is fairly memory safe and there were more modern programming techniques/methods that could be applied.

This guide does not repeat the items mentioned in the previous Converting Avi2Cvc from C to D guide.

Simple Stuff

In no particular order:

Malloc to Dynamic Arrays

Replaced dynamic memory allocations such as:

char *frame;
...
frame=(unsigned char *)malloc(framesize);

with

ubyte[] frame;
...
frame.length=framesize;

The main advantage of doing this is that the compiler/runtime is aware of the allocations. I did not have to track every path in the program to make sure I deallocated the memory before the program exited. Also, thanks to the bounds checking I can be sure I will not be trashing memory and if I do overshoot the bounds, I will be notified!

In fairness, both Pascal's and Rust's dynamic arrays were not terrible...

Easy Array Clearing

A minor thing but, from this:

// These could have been a memset()
for(int p=0;p<sizeof(pix);p++){pix[p]=0;}
for(int p=0;p<sizeof(green);p++){green[p]=0;}
for(int p=0;p<sizeof(blue);p++){blue[p]=0;}

to

// Set all values in the arrays to zero
pix[]=0;
green[]=0;
blue[]=0;

Advantages to this include:

Immutable Variables

These are variables that can be set at runtime but then not changed. They are useful as another defense against accidently changing a value that should not be changed. Good for the compiler too.

// Find out byte width (including padding) needed
immutable uint bmp_row_width=byte_width(bmp_info[0].width);
immutable uint bmp_size=(bmp_row_width*bmp_info[0].height);

Trying to change bmp_size would give an error. Pascal, Go and C do not (to my knowledge) have immutable variables, in Rust everything is immutable by default.

Garbage Collection

I mentioned the GC profiling before but it is worth mentioning again! To get a GC profile log, compile with -profile=gc and when you run the program you get an easy to read profilegc.log file.

Running the profile enabled version gave this:

bytes allocated, allocations, type, function, file:line
          65536	              1	ubyte[] D main iff2bmp.d:437
          65536	              1	ubyte[] D main iff2bmp.d:523
          32768	              1	ubyte[] D main iff2bmp.d:409
            128	              1	ubyte[] D main iff2bmp.d:391
             16	              1	immutable(char)[] D main iff2bmp.d:528
             16	              1	ubyte[] D main iff2bmp.d:420

All good and as expected. The 'immutable(char)' is the output file name, the others allocations are data chunks and buffers.

Last Updated 20/05/2024
Created 15/02/2020