orientation help

Started by Blaumeise00, March 17, 2023, 03:14:03 PM

Previous topic - Next topic

Blaumeise00

Hello forum (and Phil),

I am new here and i have the tool but i am seeking help with exif metadata not related to this tool by Phil. I am an amateur php developer and i am building a website. I wanted to scan jpeg images for code injection when allowing file uploads. I discovered exif data and reading images and now i am trying to read jpeg markers. I have been successful reading the markers but i have trouble excluding thumbnails (thumbnails have the same markers which makes it difficult to separete the main image 0xff 0xc0 from the thumbnail data.) Anyway, i started reading the ifd of the exif app1 segment. I have been successful with this process. However, my Wife has a portrait photo. I have read c0 and i unpack the width and height. But it is reversed. The image is portrait but it shows horizontal dimensions (height should be greater than the width.) I googled "jpeg exif portrait landscape" and i only ever find orientation information. I only see numbers 1-8 documented yet the data that my php script prints out from my fread is not the same (one number). I cannot see how to determine that a photo is portrait from this data. I tried unpacking the two bytes that always have a number as unsigned short 16 bit but i end up with a long number (such as 32877).

My code prints the following info, which appears to be the correct tag number:

12 01 03 00 01 00 00 00 08 00 00

the byte order is MM Big endian. I see an 8 in this tag, so i assumed that it is 8 (270cw, thus portrait). However, this theory breaks whenever i view sample photos from a github page with all of the codes in landscape and portrait. I am struggling to figure out how to use this data to determine if a photo is portrait or landscape. Is anyone able to offer tips? i cannot find data about how to read this tag properly. By the way, i always see a 3 after the tag: 12 01 03 00. I cannot understand what the 3 represents either.

I hope that someone can help.

also, the questions about the Example Output during registration can be avoided by not passing session id in the uri and using cryptographically secure csrf tokens.

Best Wishes to you.

StarGeek

I can't really help with PHP but exiftool's source code is available from the main page or from github.  There are a lot of comments documenting the code.  You might check Exif.pm and jpeg.pm under /lib/image/exiftool.
"It didn't work" isn't helpful. What was the exact command used and the output.
Read FAQ #3 and use that cmd
Please use the Code button for exiftool output

Please include your OS/Exiftool version/filetype

Blaumeise00

Thank you very much for making time to reply. I really appreciate you, StarGeek.

I tried echo ord(fread()) on this single byte and i get the number displayed on the screen. yay!
however, whenever i assign the ord(fread()) to a variable, the number comes out incorrect.
i am stumped. I assume that 0x5 is a hex number but i have yet to figure out how to get 5 from 0x5 into a variable.
i am currently using a switch until i can figure out how to read this character correctly.
i thought that the orientation is a int16u but i cannot unpack it as that type. I get an incorrect number.

i will look at the code that you link to. I was unaware that the source code was available.
i still do not see how this number determines a difference between landscape and portrait
i think that maybe someother tag is responsible for this information
or the image width and height needs to be read from the exif data and not marker 0xC0

i will try the width and height tags and still try to figure out the encoding of 0x5
if you have ever coded in php, then you should appreciate the strange irony of this echo situation
how can i echo the ord and see the number but not be able to store it in a variable?
i think that i have to seek out some php experts that could explain this phenomenon.

greybeard

Tag blocks are 12 bytes - so you are missing one byte in your example - I'm assuming it has 00 at the end:

12 01 03 00 01 00 00 00 08 00 00 00

Your example is little endian.

The tag code is in the first two bytes (reversed) 0x0112

The type is in the second two bytes (reversed) 0x0003 (or 3 in decimal which is 16 bit int)

The number of values is stored in the next four bytes (reversed) 0x000001 (or 1 in decimal)

The last four bytes hold the tag value (or an offset iof there isn't room for the tag value in 4 bytes).

In your example there is only one 16 bit value so it would be stored in the first 2 of the 4 bytes (reversed) 0x0008 (or 8 in decimal which decodes to "270 degrees: mirrored: and on its far side")

=================================================================================================
Here is a big endian example:

01 12 00 03 00 00 00 01 00 01 00 00

Tag code 0x0112

Type 0x0003

Number of values 0x00000001

Orientation value 0x0001 ("0 degrees: correct orientation")

Blaumeise00

Dear greybeard,

you are an angel! I thank you very much for the lucid explanation. I added the two missing bytes (which i assumed was byte stuffing, yikes!) and everything is working well. Now i can use unpack according to the byte order. If i could comb your grey beard for you, i will be happy to do so :-) I am indebted to you.

So now my testing exif code is as follows:
switch ($SID_JPEGmarkers[dechex(ord($SID_nextMarkerID))]['byteorder']) {
    case 'little endian': $SID_char1e = "\x12"; $SID_char1xe = "\x01"; $SID_int16u = 'v2'; break;
    case 'big endian': $SID_char1e = "\x01"; $SID_char1xe = "\x12"; $SID_int16u = 'n2'; break;
}
$sid_testo = unpack($SID_int16u, fread($SID_filePointer, 4));

Also, i am testing various files and i accidentally typed big endian in my example. My apologies for the error. Thank you for correcting this mistake. Yes, the photo from my Wife is little endian (49492a). I was looking at a Motorola byte order at the time of my post.

Best wishes to you, greybeard and thanks again StarGeek.
This forum has some very lovely members. Very nice community here!

Blaumeise00

i am coming back to this subject because i still cannot find an e1 exif entry that specifies portrait or landscape.

consider the following images:
orientation does not separate landscape from portrait as the sample photos have the same values in both perspectives.

the photo that i mentioned in this post is physically horizontal == the width is greater than the height in all of the image dimension fileds (exif 1a 1b and FF CO SOF0, for example). Windows renders the photo in photo viewer correctly but how is determined? are they reading that the image is from a smart phone, thus in portrait mode?

where is data related to portrait in exif metadata? i cannot see a way to determine it whenever the physical dimensions are horizontal.

Blaumeise00

forgot to post the link to the landscape and portrait samples with the same values:
https://github.com/ianare/exif-samples/tree/master/jpg/orientation

Phil Harvey

...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

StarGeek

If I'm understanding you correctly, there isn't a explicit tag that says an image is landscape or portrait.

You would rotate the image to the proper orientation as given in the Orientation tag and then compare the adjusted dimensions to see which is longer.  The config file in Phil's link does this.

AFAIK, all images coming from digital cameras are technically landscape by default and it's up to the sensor in the camera to determinate the orientation, which is then written into the Orientation tag. At least I've never heard of a camera that would write the image otherwise. It's then up to the viewing program to properly rotate the image.

You can find the EXIF standard docs here and this link goes into some details on image orientation.

Side note, Sad to see that the latter link to the JpegSnoop site has to be found through archive.org now, as the original link is just a blank page.  The site had a lot of good information.

By "exif 1a 1b" I'm guessing you mean 0x011a/0x011b, XResolution/YResolution?  Though I'm not sure how that would apply to the orientation of the image.
"It didn't work" isn't helpful. What was the exact command used and the output.
Read FAQ #3 and use that cmd
Please use the Code button for exiftool output

Please include your OS/Exiftool version/filetype

Blaumeise00

Hello Phil and StarGeek,

i now see that i have misunderstood the github samples and my own images versus images directly from cameras. I now understand that if a physical dimension is horizontal but it has an orientation, then rotate it. Regardless. Thus, the 'landscape' photos of the Github page are meant to be rotated. I misunderstood this concept. I thought that landscape can have a rotation orientation number but it is still a landscape photo. Now i know to rotate it. The image width > height and orientation is set, then rotate according to orientation and change the dimensions. So the photo from my Wife's phone should be rotated and the dimensions need to be swapped. Problem solved.

I am sorry for this misunderstanding. I have no idea why i missed the mark here, other than being mentally tired lately.

Thank you for the help. Like i said before, i am not a programmer (hobby). I sometimes struggle to grasp concepts.

Blaumeise00

i added two videos to imgur:

1. http://imgur.com/a/J0dspUY
2. http://imgur.com/a/6gmhbaA

1. my first script that reads the e1 IFD0 to the IFD1 Thumbnail.
2. my new script which isn't complete. I only fully parse data that interests me. The other tags will be scanned for code injection/stenography but not documented.

i am almost finished with processing IFD0. I had to add code that only reads IFD0 when the address offset is matched anywhere in E1 or the file. The 'or the file' part required a rewrite of the IFD0 handler and the address tracking variable. I need to process the IFD0 data segment next, then the SubIFD etc. Then i will extract the thumbnail and show it on the results page (after scanning it, of course.)

StarGeek

One thing to take note on those github images is that each number in the filename indicates what the Orientation tag is set to.  This isn't immediately obvious, as modern browser will automatically correct it.

For example, in the older browser I use, I see this for Landscape 2 (Mirror horizontal)
"It didn't work" isn't helpful. What was the exact command used and the output.
Read FAQ #3 and use that cmd
Please use the Code button for exiftool output

Please include your OS/Exiftool version/filetype

Blaumeise00

StarGeek, thanks for that last post! I am using modern browsers, which apparently rotate the image correctly. No wonder i was struggling to understand the orientation. I need to open my virtualbox with xp and look at those images in older browsers. Unbelievable.

Thank you for sharing this info :-) you've made my day.

I am certainly not trying to make a tool like Phil's tool. I began this project because of those nasty code injected images and security bypass techniques. I decided to code my own jpeg reader because php libraries are almost more like hacker tools than security tools. I am successful with detecting known code injection techniques. I figured that once i am reading the jpeg, then why not grab the data that is most useful to me. I suppose that i could add forensically useful data as well but i don't want to take my project too far into the exif reader territory. I am focused on image security scanning, so a jpeg scanner versus an exif reader.

anyway, i am going to write some more code now, then call it a day. I'd like to finish this script and move on to a different project (probably my own character encoder/decoder to prevent sql injections).