Users browsing this thread: 1 Guest(s)
Basics?
#1
Could someone help me to understand the basics on how to analyze an image format?
Reply
Thanked by:
#2
First thing's first, you need to be familiar with bits and bytes, their hexadecimal representations (as well as hexadecimal representations of colour, and hence how bytes represent colour), and looking at files in a hex editor. Knowing things like endianess and how bytes are read as numbers (shorts, longs, etc) is helpful too. I've PMed you before and you seem to know a fair bit about this stuff but it also applies to anyone else who might be reading this.

Now, you need to understand that the majority of the time a digital image is little more than a collection of pixels (unless we're talking about vector images but let's not go there). Each pixel is assigned a colour, and so when you arrange them in the right order they give you the image.

There are two popular ways of doing this; with a palette or without one. The latter represents each pixel by its full colour value. So for a 32-bit colour image, each pixel would be 4 bytes (i.e. 32 bits).
The palette method is a bit different. Each pixel is just a number that points to a place in a palette, which contains that pixel's colour. This palette can either be in the same file or in a separate file. Depending on the size of the palette the pixel can take up a different number of bytes, but typically it doesn't go beyond 1 byte (since 256 colours is often more than enough for a single image). It can vary though. In any case, the advantage of this method is that you can save space by not having the same colour being repeated in the image; two pixels of the same colour can simply reference the same index in the palette with a single byte (assuming it's 256 colours).

In either case, the pixels are often stored in a linear fashion, one after the other. Files usually have additional information in them telling you how these should be arranged. The simplest way is simply giving a width and height, and then you just place the pixels from left to right in rows. Sometimes a height isn't even given, and you just assume that the height is whatever the image is when the pixels run out (i.e. pixel number divided by width).

That's a really really simple explanation of "the basics", this is the most simple format of the many, many formats that exist. There's no specific steps to follow really, it's more or less practice and experience. Looking into popular formats like BMP and PNG is helpful, and if you're a coder then looking at source code for programs that convert game image formats can help too.

EDIT: By the way, I haven't even mentioned compression. I suppose using palettes is a form of compression, but there are much more complex forms that aren't nearly as friendly.
You may have a fresh start any moment you choose, for this thing that we call "failure" is not the falling down, but the staying down. -Mary Pickford
Reply
#3
That helps out a bunch, thanks Smile
Reply
Thanked by: puggsoy
#4
I'm sorry for bumping this thread (very old thread) but I need a bit more help understanding it :/
Reply
Thanked by:
#5
Is there anything in particular that you need help with?
[Image: ndsMEF0.gif][Image: sig.gif]
Reply
Thanked by:
#6
Mainly on Palettes. I thought I understood palettes but I don't Tongue
Reply
Thanked by:
#7
OK so, basically a palette is a collection of colours. These colours are read just like any colour, which I'm assuming you know how to.
In the actual pixel data, each pixel is just a number pointing to an index within the palette. For example, if the first colour in the palette is 0xFFFF0000 (in ARGB32 that's opaque red) and you wanted a particular pixel to be red, the byte(s) representing that pixel would have a value of 0 (palettes are almost always zero-indexed). A program decoding this format would read the pixel number, go to the palette, grab the colour, then make the pixel in the image that colour.

I hope that clears things up? If you'd like I can maybe find some simple formats (or make a fake one) so that I can explain it more specifically without being so general.
You may have a fresh start any moment you choose, for this thing that we call "failure" is not the falling down, but the staying down. -Mary Pickford
Reply
#8
So let me see if I have this right.
[Image: DwTq41v.png]
Each of these is a pointer to a pixel value, so I would just read from it and place it left from left?
Reply
Thanked by:
#9
Well, in this particular case the image doesn't actually look like it uses a palette; rather just a plain 32-bit colouring, or maybe something different altogether. But yeah, if it was using a palette, the first pixel would be the colour at index 0x80 = 128 in the palette, the second would be at 0x1B = 27, etc.

Let's work with an example file. This is a file from Patapon 2 for the PSP. The first 0xC bytes are just a magic ID, and there are some other things in the header, but for now I'll just focus on the pixel and palette data.

At 0x80 starts the pixel data, which is 0x1FE00 bytes long. At 0x1FEC0 is the palette data, which is 0x400 bytes long. The palette has 0x100 (256) colours in it, each 4 bytes long, and they're in RGBA format.
In the pixel data, each byte represents a pixel, and the value of each one points to a specific place in the palette. Let's look at the first one at 0x80, which is 0xD3. In decimal that's 211, so you go to the 211th colour in the palette, which is 0x739FD3FF.

You can use this process to create an array of all the pixels, each element being a colour value grabbed from the palette. After that, you can create the image using the width and height. In this specific file they're found at 0x20360 as little-endian 32-bit integers, first width then height.
You may have a fresh start any moment you choose, for this thing that we call "failure" is not the falling down, but the staying down. -Mary Pickford
Reply
Thanked by: Struggleton!
#10
Someone ought to fix code formatting, lol.
C# code example:
Code:
public static Bitmap Create(Color[] palette, byte[] indices, int width, int height)
{
    Bitmap bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
    for (int y = 0; y < height; y++)
    {
           // we traverse through the image from top to bottom
        for (int x = 0; x < width; x++)
        {
                        // ..and from left to right
                        // x + (y * width)] means we get the current column and
                        // add the amount of traversed rows * the amount of traversed columns
                        // in a 2-dimensional array, this would be equal to indices[x][y]
            bitmap.SetPixel(x, y, palette[indices[x + (y * width)]]);
                        // SetPixel() takes in the x and y coordinate and an ARGB Color value
        }
    }
    return bitmap;
}
Reply
Thanked by: Struggleton!


Forum Jump: