Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect end of file for JPG images

Tags:

jpeg

I am sending many images from my server to clients in sequence, continuously through TCP.

Now at the client, how should I detect efficiently that this is the end of one image so I can save it to the file system and then process the next image and so on?

like image 889
Zai Avatar asked Jan 03 '11 15:01

Zai


People also ask

What type of file ends in JPG?

A JPG file is a raster image saved in the JPEG format, commonly used to store digital photographs and graphics created by image-editing software. JPEG features lossy compression that can significantly reduce the size of an image without much degradation and supports up to 16,777,216 colors.

What is the beginning and ending signature for a JPEG file?

SOI is the start of image marker and always contains the marker code values FFh D8h. APP0 is the Application marker and always contains the marker code values FFh E0h.

Is there metadata in a JPG?

A typical JPEG file contains a lot more information than just the bytes required to store image data. A JPEG file also has a lot of metadata in each file containing auxiliary information about the image. On an average, this kind of metadata occupies 16% of size of the JPEG file.

How do I check if a JPG is valid?

The easiest way is to open it as an image and check it's a JPG type when it's open. However, if it isn't then you will get an exception which may not always be catchable. If these are present, it probably is a JPG. But the only true way to be absolutely sure is to load it as an image!


3 Answers

Well, there's no guarantee that you won't find FFD9 within a jpeg image. The best way you can find the end of a jpeg image is to parse it. Every marker, except for FFD0 to FFD9 and FF01(reserved), is immediately followed by a length specifier that will give you the length of that marker segment, including the length specifier but not the marker. FF00 is not a marker, but for your purposes you can treat it as marker without a length specifier.

The length specifier is two bytes long and it's big endian. So what you'll do is search for FF, and if the following byte is not one of 0x00, 0x01 or 0xD0-0xD8, you read the length specifier and skips forward in the stream as long as the length specifier says minus two bytes.

Also, every marker can be padded in the beginning with any number of FF's.

When you get to FFD9 you're at the end of the stream.

Of course you could read the stream word by word, searching for FF if you want performance but that's left as an exercise for the reader. ;-)

like image 103
onemasse Avatar answered Oct 20 '22 22:10

onemasse


A quick look at Wikipedia's JPEG article would have given you the answer:

  • bytes 0xFF, 0xD8 indicate start of image
  • bytes 0xFF, 0xD9 indicate end of image
like image 30
darioo Avatar answered Oct 20 '22 22:10

darioo


If you're sending the images via a byte array then you can simply add the file size of the image as a pair of bytes before the start of the file.
Client grabs the first two bytes to find specified number of bytes (we'll call that x) and discards them, then pumps the next x number of bytes into a buffer which it can write to file.
Rinse and repeat for all following jpegs.

An alternative is just looking for the FFD9 marker - if I'm not mistaken any compressed value FF will be encoded as FF00 (the 00 byte is discarded and the FF byte is kept).
The problem with this is that you get things like thumbnails with their own FFD9 headers, but those are contained within a segment in the headers. Those segments have a length value in the two bytes after their marker so you can just skip to the end of any segment you encounter to avoid premature eoi detection.

like image 2
TheHitchenator Avatar answered Oct 20 '22 22:10

TheHitchenator