Jump to content

[TUT]Converting R16 images to TGA


Recommended Posts

This tutorial will cover the basic structure of R16 and TGAs. It draws from my R16 specification here and the TGA specification here


R16s contain a series of images and some related data. They comprise a 29 byte header, followed by the image data.

The image data is 15 bit colour, although stored with 16 bits to make it two nice round bytes. Each two bytes of the image data represents a pixel in the format XRRRRRGG GGGBBBBB, where X is disregarded and each colour channel is allocated 5 bits and therefore 32 combinations each and 32768 possible colours from the RGB channels.

To calculate the length of this image data you simply take the width and height specified in the header, then multiply these by two. (Image data length in bytes = width * height * 2)

The width and height of the R16 image are at an offset of 1 and 5 respectively, they're stored as standard unsigned 32 bit integers. For example, if we wanted to calculate the length of the image data in a tileset, looking at the width and height in offset 1 and 5 would give us a width and height of 32 pixels. Ergo, the image data length is 2048 bytes and starts at 0x1D.


TGAs store a lot of optional data which I won't go into, such as the developer area, extension area, file footer and some other things. All we're interested here is the TGA header and the image data which follows it.

The header is stored as:

1 byte - ID field length

1 byte - Colour map type

1 byte - Image type

5 bytes - Colour map specifictaion

10 bytes - Image specifictaion

The Tutorial

For this tutorial I will be using a tileset (BLOX****.R16), so open it up in your hex editor. Now let's use the first image out of this R16, so check the offsets 1 and 5 for the width and height. These will show a hex value of 0x20 in a little endian format for both. 0x20 is 32 in decimal, so we know the width and height is 32 pixels. Now select the byte at 0x1D. You can calculate the length of the image data by multiplying the width (32) by the height (32) by 2 (so 32 * 32 * 2 = 2048). So select 2048 bytes including current position in your hex editor (in XVI32, you simply select 0x1D, go to Edit->Block <n> chars, and enter the decimal 2048).

Next copy this image data to clipboard, (again in XVI32, this is a simple Ctrl-C or Edit->Clipboard->Copy).

Now let's create a new file (in XVI32 use File->New), now using the TGA header spec as a guideline:

1. Add 00 for the ID field length, as ID fields are optional and we have no use of one.

2. Add 00 for the Colour Map type, as we're not using a colour map

3. Add 02 for the image type, as we are using an uncompressed true colour specification

4. Add 00 00 00 00 00 for the colour map specification, since we're not using one

5. Add 00 00 00 00 for the start of the image specification (this sets the image origin to the corner 0 by 0)

6. Now we have to add the image width and height, this is stored as a Unsigned Int 16 here (unlike the Int 32 in the R16), so add 20 00 20 00

7. As the penultimate part of the image specification add 10 (this is 16 in decimal and indicates 16 bit colour (yes I know it's 15 bit!))

8. As the final byte of the image specification add 01 for the image descriptor byte (I don't know why)

This will give you a header of 00 00 02 00 00 00 00 00 00 00 00 00 20 00 20 00 10 01

Now after this, paste in the image data from clipboard (take care not to overwrite the last byte of the header, you may need to create a byte after the header to paste onto.) Done! Now open this up in whatever TGA viewer you have on your PC, remember that both Photoshop and Mozilla Firefox can open up TGAs, but that Windows probably won't be able to on its own.

I can include XVI32 screenshots as well if people want.

Link to comment
Share on other sites

Cool, thanks for this tutorial. I tried it, but it does not work. I just changed the first lines with hex editor into "00 00 02 00 00 00 00 00 00 00 00 00 20 00 20 00 10 01", but irfanview does not read it (after saving as 123.tga).

Perhaps a screenshot of XVI32?  :)

edit: perhaps I should read the tut better first... where is the 0x20? There is no x in the program at all...?

Link to comment
Share on other sites

0x signifies hex values, 0x20 is equal to 32 in decimal. I highly recommend using XVI32 for hex editing, it's very lightweight, fast and powerful (oh and free.) I'll screenshot the process in XVI32, and upload that sometime today.

Link to comment
Share on other sites

Alright, since that quality was so awful I've uploaded the original video to my permanent section of my site here. It's 25 meg, but is good quality. The audio is still a second or two out of sync with the video unfortunately, but just think of it as me saying what to do before I show it lol

Link to comment
Share on other sites

Quadruple post, my apologies to the staff.

Okay, so I've started on a program which exports all the images in the tileset to tga. I was a little surprised when the program didn't hang at all when I hit export, but it's the start of an R16 editor.

Edit: Have just converted R16 images to BMP too now, BMPs have a longer header but aside from the BMP header being 54 bytes compared to the TGAs 18 byte header, it's the exact same. I'm going to try adding this support to the program I wrote.

Edit 2: BMP support now added to the program. Just exported a tileset to generate 1600 files (800 bmps, 800 tgas), does it in the blink of an eye.

Link to comment
Share on other sites

  • 3 years later...

I have been looking at your tutorial again and it works perfectly for BLOX****.R16, but for all the other r16 is fails.


I even wrote a little python to export all the images (proof that is works for BLOX****):




What I did discover when looking at the other r16 files is that you actually need 00 00 02 00 00 00 00 00 00 00 00 00 20 00 20 00 10 20


The 20 on the end makes sure that the origin is at the left top.


What is very annoying is that it looks so simple (the MOUSE.R16), but I can't figure it out:




See looks simple, but I get this:


Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...