Reverse Engineering the .IRG infrared thermal imaging format - help needed
I always find it depressing when I reach the limits of my abilities.
I have a new Thermal Imaging camera. It automatically saves photos in two formats. The first is a standard JPEG with false colours and metadata superimposed.
The second is a .irg
file which can only be opened by the Windows-only software which comes with the camera.
Judging from what that software shows, the .irg
contains a raw thermal image and separate metadata. That makes it more useful for analysis.
What I know (not much!)
Here's what I can find out about this undocumented file format.
Every .irg
file is exactly 131,080 bytes. I presume that means the image is stored as an uncompressed array of pixels - the thermal sensor is only 256x192. And I also guess that it has fixed length fields for metadata?
Each file has a different MD5 hash - so these are unique.
I couldn't identify the images with the standard Linux tools of identify
, strings
, file
, or exiftool
. Thermal Imaging tools like ThermImageJ weren't able to read them.
Running binwalk
showed that there was a JPEG at 0x1FAC0
until the end of the file. Each .irg
had exactly the same JPEG attached:
An unexciting, 180x240, 1,352 byte, lump of green. There's no exif in it.
A hexdump
shows that all the .irg
files start with the same header:
0000000 0bb0 0080 a8c0 0000 00f0 00b4 c000 00a8
0000010 f000 b400 0000 a8c0 0000 00f0 00b4 251c
0000020 0000 7e7c 002d 7e7c 002d 1388 0000 0fa0
0000030 0000 2710 0000 0000 0000 2710 0000 0000
0000040 0000 0000 0000 0004 0000 0002 0000 0000
0000050 0000 0000 0000 0000 0000 0000 0000 0000
That doesn't look like any file signature I recognise.
The metadata on the software's PDF manual showed it was written by Infiray. They don't have any details on their site and haven't responded to my emails.
My knowledge of comparing hexdumps and trying to interpret them is lacking. It looks to me like there is a bunch of regular data in there, but I wasn't able to make head nor tale of it.
There are some articles about decoding these sorts of files but I wasn't able to apply that knowledge.
Your turn
Well gang, I'm stumped! Here is a zip with 5 JPEGs and their corresponding 5 .irg
files.
If you can decipher how they work, or get me any closer to an open source viewer, please let me know!
Progress
James has a quick scrap of Python to extract the black and white image.
I think that's just from the visual sensor, rather than the thermal sensor - but it's a start!
Further Update!
Phil has completely reverse engineered it.
Julia said on mathstodon.xyz:
@Edent Dang, I was hoping you’d figured it out!
Andy Mabbett says:
This forum discussion:
https://autelpilots.com/threads/evo2-enterprise-dual-640t-rtk-maps-and-models-of-ir-and-rgb-jpegs-ntrip-data.9058/page-2
includes a post saying "I checked out the Autel IR_PCTool utility and it works so long as you have the JPEG and IRG files."
Elsewhere in the discussion it is stated that "IRG is a converted RJPEG".
I don't pretend to understand the rest of the discusison, but hope this is useful.
RJPEG is further discussed here:
https://av3aerovisual.com/en/differences-between-images-in-tiff-jpg-and-rjpeg-formats/
James Seward said on mastodon.jamesoff.net:
@Edent the pattern of data starting from that offset looked like it repeated in a way which would just be rows (or columns) of 8-bit values straight off the sensor so it was worth a shot. I guess the metadata elsewhere in the file will contain the temps, coords for the points to mark, and the timestamp, but I've not looked at that.
James Seward said on mastodon.jamesoff.net:
@Edent guessing the timestamp will be epoch-like, so looking for values in the file which are around whatever that converts to will probably help locate the metadata bits. No idea what that green JPEG is doing there near the end! Maybe some kind of overlay you can specify?Oh, and hexdump on macOS shows the first two bytes as "b0 0b" 🙄
nicopap says:
Starting work with Jame's script, I find a second array, of size 180x240, each pixel occupy 2 bytes. It's located just after the first one, so replacing in the script 0x7E by 0x7E+(180*240) I get an actual image. See this script:
https://gist.github.com/nicopap/dcd57bbc195cb7ceed6ed3fed9ffe652
nicopap says:
I'm done. Using value = datum[1] + 2**8 * datum[0] (little endian), I get some white zones in very cold (but not TOO cold) areas. The mysterious second array is possibly a 16 bits float, or a 16 bits signed integer in 2's complement. If a number is negative in two's complement, it will be translated into a large value in my little script, so it will be white.
Doesn't answer the most important question: What do those numbers represent? Is the first 8bits array meant to be used in combination with the second 16bits array? 24 bits? Hmm reminds you of something?
I've other things to do today so I'll let everyone else figure it out.
Sam Sharpe says:
I think the second image is still an 8bit value, just it's using two bytes for each pixel for some reason. If you look, the second byte in the pair is always 0x0b (well, at least I haven't found any where it isn't 0x0b - if you ignore that second byte it makes sense as an image again.
Sam J Sharpe said on mastodon.social:
@Edent I think you have two images, the first is 1 byte per pixel, the second is using 2 bytes per pixel, then finally you have some actual data right at the end.Have a look at it with Binocle https://github.com/sharkdp/binocleUse the settings in the screenshot and you can basically see the second image (and two copies of the first). Switch stride from 2 to 1 and you'll see the first image and a stretched second image. I think your second image has the crosshair points. GitHub - sharkdp/binocle: a graphical tool to visualize binary data
Sam J Sharpe said on mastodon.social:
@Edent I build on nicopaps script in the replies to your post at https://shkspr.mobi/blog/2023/02/reverse-engineering-the-irg-infrared-thermal-imaging-format-help-needed/- fixed a bug in the initial offset and made is discard the interleaved values (always 0x0b) in the second image. https://gist.github.com/samjsharpe/4f8d2eda8c5b874d4b548848779da871It's weird - the images are not exactly the same, as otherwise the diff would be black. I suspect nicopap is correct and the two images represent slightly different things, but I don't know what. Reverse Engineering the .IRG infrared thermal imaging format - help needed
Phil Ashby: :marmite:, NHS 💙 said on mastodon.me.uk:
@Edent I did some digging and found this post about IRG files:https://autelpilots.com/threads/evo2-enterprise-dual-640t-rtk-maps-and-models-of-ir-and-rgb-jpegs-ntrip-data.9058/page-3..which mentioned an IRPCTool, more digging gets..https://www.reddit.com/r/Autel/comments/xu6duh/does_anyone_know_where_i_might_find_the_evo_ii/..and finally a download page for an SDK:https://www.autelrobotics.com/download/139.htmlthe SDK has functions for reading IRG parameters and data - reversing that ATM...
Yo says:
I have added some color rendering of the images using different palettes I found: https://github.com/YoannHub/infrared
Craig says:
I did a little bit more work here, mainly documenting some of the stuff that was already discovered on this thread by all the contributors. So hopefully consolidating things into one place. You can see what I did here: https://github.com/crroush/heatseeker
I have a TC004, and there seems to be some different flavors of the IRG format that I have not seen. Most notable is the two different offsets from where the first image starts (0x80/0x100).
More comments on Mastodon.