Okay, let's talk about the 02 token. As you know, this is of the format 02XXXXXX, where the XXXXXX is a number that describes how many BYTES of data follow.
Now hang on, because at the moment I don't have access to a resource fork (cringe) and I can't remember off the top of my head whether the XXXXXX means the number of bytes or the number of pixels. In any case for 8 bit it's the same, so I'l just assume we're in 8 bit for the following example. I'll follow up this post tomorrow when I have access to a resource fork (I'm using my girlfriend's PC at the moment).
So, on to the example. We have the data:
01000014 0300000A 02000009 FFAAFFAA FFAAFFAA FF000000 010000AA......
Once again the first token is a new line long, the 14 means that there are 20 (14 = 16+4 = 20) bytes of data to follow for this line.
Advance your pointer by 4 bytes if you're in C.
The next token, 0300000A, just means skip the next 10 pixels. Read the last post for details. Advance your pointer by 4 bytes if in C, and advance your pixel pointer by 10 pixels (10 bytes in 8 bit colour). You have to do the pixel advance EVEN IN RB. There are serious (read=ultra, ultra serious, probably fatal) problems with using RB to stuff around with RLE's. When you try and encode one, you'll understand why. Decoding, however, is no problem. If you don't want to encode, you can skip the next para.
What is the encoding problem? Well, the beauty of RLE data is that it allows you to simply SKIP pixels - your shape doesn't need to be rectangular. This means you can have total transparency where you need it, without a mask. That's where the mask went! But to encode an RLE, you need a mask, because you need to know which pixels to skip. The easiest way to do this is to fill all the parts of an RLE that you DON'T want with a single colour, a MASKING COLOUR. It usually can't be black because most RLE shapes will have some black in them. Pick a wierd colour. Now, in RB, you MUST FILL your pixel MemoryBlock with this colour BEFORE you start decoding the RLE. Every byte. You see why? Because when you finish decoding, the MemoryBlock will STILL HAVE the masking colour in all the places you skipped, and encoding is no problem - you just have to skip all the masked pixels. If you don't do the mask first, you will be in trouble - when you go to encode, you won't know which pixels are masked!! So if the mask colour is indexed as 1A, your MemoryBlock data would look like 1A1A1A1A1A1A1A1A1A1A1A1A1A1A1A1A1A1A.... before you started decoding, and afterwards it might look like 1A1A1AFFFF1AFF1A1AFFFFFF1A. The mask remains. Good stuff. Moving on...
Just so you don't have to scroll back up, the rest of the data in our example is 02000009 FFAAFFAA FFAAFFAA FF000000 010000AA.
The first token of this data is 02000009, and here the fun starts again. This token means that the next 9 pixels (or bytes, I'll clarify in another post, but for now 1 pixel = 1 byte so it doesn't matter) are to be filled with the pixel data that follows.
How do you deal with this? Well first advance your data pointer by a long, if in C. Now you're reading bytes, not longs. Read a byte. Copy this value to the pixel MemoryBlock. Advance the data pointer one byte, and ALSO advance the pixel pointer one byte. Read a byte. Copy this value to the pixel MemoryBlock... and so on. Remember to advance the pixel pointer by one byte each time as well as the data pointer. You do this 9 times. Why? Because the 02000009 token said to.
Now, what do we do? We might mistakenly think, 'right, time for the next token!' and read a long. What do we get if we do that? 00000001. Is that a token? YES - it's an end of shape token, and if you made that mistake the image would have ended right there. For some reason the Shuttle rle8 resource can't be stuffed up like this, so I never picked up this mistake until I loaded the Enterprise shape, which was clipped to only 20 lines, and something was obviously wrong.
The mistake was that tokens ONLY start on long-even offsets. What this means is that if you look above at the example data, I've grouped it in sets of 8 hex characters = 4 bytes. This is how you MUST read the data. This is what I mean by keeping the data pointer aligned. Because 9 (bytes) isn't a multiple of 4, the data pointer ISN'T IN LINE WITH THE TOKEN! Therefore, you have serious problem. To fix it, you NEED a pointer alignment routine. In BlitPixie there is a lovely little macro that does this in C, but it doesn't work in ProjectBuilder properly. The simple pseudocode for my alignment routine is:
Find the remainder of the division N/4, where N is the number of bytes you just advanced.
If remainder = 0, don't worry.
If remainder = 1, advance the DATA pointer 3 more bytes.
If remainder = 2, advance the DATA pointer 2 more bytes.
If remainder = 3, advance the DATA pointer 1 more byte.
This can be written much more efficiently in C. Note that this has nothing to do with the pixel pointer. SO, now the data pointer is aligned, and you can read the last token, which is just a new line token.
So that's what I'm talking about when I go on about pointer alignment. Tokens only occur on long-even intervals. It's a problem even in RB, so deal with it when it occurs - every time the 02 token appears.
Like I said at the beginning, the NNNNNN in 02NNNNNN might be the number of pixels, in which case the number of bytes is NNNNNN*2 for 16 bit, or it could be the number of bytes. I'm fairly sure it's bytes, not pixels, but I'll check. I can't remember off the top of my head. In 8 bit, none of that matters. It only matters in 16 bits.
My advice is just to use 8 bit until you're comfortable because the 1-1 correspondence between bytes and pixels makes life easy.
Enjoy coding!
------------------
Kane O'Donnell