JPEG
The mysterious world of the jpeg file format explained
Benjamin Kenwright
Well those of you who are about to set out on the journey of discovering the jpeg file format better be prepared, I believe that the principles behind it are easy to grasp than the actual coding of it.
The jpeg file format is all around you... probably one of the most widely used... its platform independent... one of its biggest uses is for the internet.
Why use the jpeg file format? ts biggest selling point is the fact that you can take a 3meg bitmap file (coolimage.bmp) and convert it to a jpg of only a few hundred kilobytes instead (e.g. coolimage.jpg).
Of course it does have its downside, it's a lossy image format, so the original image looses some of its original details... but usually these are not noticeable to the human eye.
| Inside | |
Give me a jpeg, and lets rip it to pieces!
How its layed out, and how the information is stored isn't to hard to grasp. Simply put the jpeg file format is arrange with a description section of size 2 bytes which has an value which we can look up, e.g. 0xffda for example, then it has a further 2 bytes following that desciption section header which tells us how many bytes make up that section.
One exception!!... There are a few uni-markers as they say! A uni marker is just a 2 byte id, which has some meaning.
SO A UNI-MARKER DOES NOT HAVE 2 BYTES FOLLOWING IT TO GIVE ITS SIZE.
I've empasised the one exception in bold as it can make decoding corrupted jpgs very challenging if the end marking identifier is missed (as it'll go passed the end of the data block). But more on that later..
Hmmm...markers...hmm....yup it all seems simple and if you take it one step at a time it will eventually make sense! The secret to understanding the jpeg file format is to break it up into pieces and understand fully how each section of the marker works, and its use in the overall picture.
Now, to start with... all jpegs should start with an SOI marker, which is a uni-marker and has the value 'xffda'. But the jpeg file format is arrange in little endian format...What does that mean? Well the bytes are arranged so that the least significant bits are first ... so if we read in the first two bytes we would get '0xda' first followed by '0xff'. Again it only matters if we read more than one byte at a time. So if we read more than one byte at a time we'll have to shift it around.
One thing I found when writing a simple jpeg decoder/reader, was that you have to be prepared to look at your data right down to the binary level! Its not enough to look at your data as bytes....you'll have to actually decode 1's and 0's and compare them etc... and shift them... to get your image back.
Let write a little code to see how the jpeg file format works... give you a taster.
All markers (e.g. 2 byte identification chunks) always start with 0xff it may not be so easy to follow as the bytes are read in the opposite way so what where really getting is 0xdaff ....But I think you get the point. There is one exception, a marker followed by '00' is a ignore marker, these only appear in our encoded data (e.g. in the SOS Start of Scan part).. but well get to that in time.
Note: Sometimes I use the word chunk to represent the actual section ID of the part of the file for example I say Im reading in the chunk ID, which for example could be APP0 (e.g. 0xffe0) which will be followed by a chunk size of 2 bytes, then we go through the chunk. Alternatively you can refer to then as sections, or markers..just make sure you know what Im going on about, and how its organized.
Our file would start like this:
[0xd8] [0xff] [0xe0] [0xff] [0x00][0x10] ..
So what would this tell us??? Any ideas?
Well its goes like this:
[0xd8] [0xff] first 2 bytes are a uni-marker representing SOI (Start Of Image).
[0xe0] [0xff] - further 2 bytes we have the marker APP0 (Application Marker)
[0x00] [0x10] This is the further 2 bytes following our APP0 marker telling us how long this marker is! Which is 0x1000 remember the bytes are the other way around. So the next 16 bytes (0x10) including the 2 bytes for the length, represent how long our APP0 marker is.
Now a good idea for a newby to the jpeg file format is to write a small program which just goes though the file and sees what markers are in there! As we can read in the markers type, and we know how long that marker is, so we can just jump to the next marker and read in what it isget its size and skip to the next one.
Note: All the markers contain the total size of how much information is in them EXCEPT the SOS marker which is the marker that contains the compressed image information and is usually located at the end of the filewell almost, the last marker is always EOI (End Of Image) and has the value 0xffd9.
And here we are a nice little program which lists the markers in the jpg file:
If you run the above code you'll get the following:
Now belive it or not, we've got a whole lot of juicy information there....it tells us the size of each chunk, the order that they are in.... and which chunks are in our image.
|