Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get the width/height of jpeg file without using library?

Firstly I want to say I tried many times to find the answer by using google search, and I found many results but I did not understand, because I don't know the idea of reading a binary file, and convert the value that Obtained to readable value.

What I tried doing it.

unsigned char fbuff[16];
FILE *file;
file = fopen("C:\\loser.jpg", "rb");
if(file != NULL){
   fseek(file, 0, SEEK_SET);
   fread(fbuff, 1, 16, file);
   printf("%d\n", fbuff[1]);
   fclose(file);
}else{
   printf("File does not exists.");
}

I want a simple explanation with example shows, how to get width/height of jpeg file from its header, and then convert that value to readable value.

like image 495
Lion King Avatar asked Aug 16 '13 01:08

Lion King


People also ask

How do you find the height and width of a JPEG?

Find the image file in your Finder, right click the image and select Get Info. A pop-up window will open with the dimensions of your image displaying in the More Info section. The dimensions show the pixel height and width of your photo.

Is JPEG file size big or small?

A JPEG file can display 16.8 million colors while staying relatively small in size. That's what makes it the go-to file for photographers and web publishers alike.

Why is JPEG file smaller?

JPEGs use a lossy compression process — meaning some data from the image is permanently deleted when it's made smaller. This could compromise the quality of your file in the long term because each time you edit and save it, you lose more data.

Why is JPEG file so large?

If your scanner is creating 100-kilobyte files, then your scanner is probably producing images in an uncompressed or slightly compressed JPEG format. Using a program like Paint Shop Pro, you can open the image and re-save it at a different compression ratio to shrink the file size significantly.


2 Answers

Unfortunately, it doesn't seem to be simple for JPEG. You should look at the source to the jhead command line tool. It provides this information. When going through the source, you will see the function ReadJpegSections. This function scans through all the segments contained within the JPEG file to extract the desired information. The image width and height is obtained when processing the frames that have an SOFn marker.

I see the source is in the public domain, so I'll show the snippet that gets the image info:

static int Get16m(const void * Short)
{
    return (((uchar *)Short)[0] << 8) | ((uchar *)Short)[1];
}

static void process_SOFn (const uchar * Data, int marker)
{
    int data_precision, num_components;

    data_precision = Data[2];
    ImageInfo.Height = Get16m(Data+3);
    ImageInfo.Width = Get16m(Data+5);

From the source code, it is clear to me there is no single "header" with this information. You have to scan through the JPEG file, parsing each segment, until you find the segment with the information in it that you want. This is described in the wikipedia article:

A JPEG image consists of a sequence of segments, each beginning with a marker, each of which begins with a 0xFF byte followed by a byte indicating what kind of marker it is. Some markers consist of just those two bytes; others are followed by two bytes indicating the length of marker-specific payload data that follows.


A JPEG file consists of a sequence of segments:

SEGMENT_0
SEGMENT_1
SEGMENT_2
...

Each segment begins with a 2-byte marker. The first byte is 0xFF, the second byte determines the type of the segment. This is followed by an encoding of the length of the segment. Within the segment is data specific to that segment type.

The image width and height is found in a segment of type SOFn, or "Start of frame [n]", where "n" is some number that means something special to a JPEG decoder. It should be good enough to look only for a SOF0, and its byte designation is 0xC0. Once you find this frame, you can decode it to find the image height and width.

So the structure of a program to do what you want would look like:

file_data = the data in the file
data = &file_data[0]
while (data not at end of file_data)
    segment_type = decoded JPEG segment type at data
    if (type != SOF0)
        data += byte length for segment_type
        continue
    else
        get image height and width from segment
        return

This is essentially the structure found in Michael Petrov's get_jpeg_size() implementation.

like image 169
jxh Avatar answered Oct 17 '22 14:10

jxh


then you have to find hight and width marker of jpeg that is [ffc0].

after finding ffc0 in binary formate, the the four,five bytes are hight and six and seven bytes are width.

eg: [ff c0] d8 c3 c2 [ff da] [00 ff]
                      |         |
                      |         |
                      ->height  ->width

int position;
unsigned char len_con[2];
/*Extract start of frame marker(FFC0) of width and hight and get the position*/
for(i=0;i<FILE_SIZE;i++)
{
    if((image_buffer[i]==FF) && (image_buffer[i+1]==c0) )
    {
        position=i;
    }
}
/*Moving to the particular byte position and assign byte value to pointer variable*/
position=position+5;
*height=buffer_src[position]<<8|buffer_src[position+1];
*width=buffer_src[position+2]<<8|buffer_src[position+3];

printf("height %d",*height);
printf("width %d",*width);
like image 39
user3614789 Avatar answered Oct 17 '22 14:10

user3614789