Reading JPG width and height from Binary data

Visuals, audio, animation. Blended, not stirred. If LiveCode is part of your rich media production toolbox, this is the forum for you.

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

Post Reply
capellan
Posts: 654
Joined: Wed Aug 15, 2007 11:09 pm

Reading JPG width and height from Binary data

Post by capellan » Mon Dec 24, 2018 5:11 am

Hi All,

In the mail list there is a thread about reading JPG width and height
and just for future reference I want to include this script in the forum.

Please test and improve this script:

Code: Select all

on mouseUp
local temp
answer file "Select JPEG image"
put it into temp
open file temp for binary read
read from file temp for 100000
put it into temp1
close file temp

put numtobyte(255) & numtobyte(192) into tBaselineJPGFrame0
-- in Hexadecimal: FFC0 =  JPEG Start-Of-Frame (SOF) marker FFC0
put numtobyte(255) & numtobyte(194) into tProgressiveJPGFrame0
-- in Hexadecimal: FFC2 =  JPEG Start-Of-Frame (SOF) marker FFC2

set the casesensitive to true

put offset(tBaselineJPGFrame0,temp1) into tStartOFrame
if tStartOFrame is 0 then put offset(tProgressiveJPGFrame0,temp1) into tStartOFrame

if tStartOFrame is not empty
then
put byte (tStartOFrame + 5) of temp1 & byte (tStartOFrame + 6) of temp1 into tJPGHeight
put byte (tStartOFrame + 7) of temp1 & byte (tStartOFrame + 8) of temp1 into tJPGWidth

-- put baseConvert(baseConvert(bytetonum(byte 1 of tJPGHeight),10,16) & baseConvert(bytetonum(byte 2 of tJPGHeight),10,16),16,10) into tJPGHeight

put bytetonum(byte 1 of tJPGHeight) into q
put bytetonum(byte 2 of tJPGHeight) into w
put baseConvert(q,10,16) into r
if the number of bytes of r = 1 then put "0" & r into r
put baseConvert(w,10,16) into t
if the number of bytes of t = 1 then put "0" & t into t
put r & t into y
put baseConvert(y,16,10) into tJPGHeight

-- put baseConvert(baseConvert(bytetonum(byte 1 of tJPGWidth),10,16) & baseConvert(bytetonum(byte 2 of tJPGWidth),10,16),16,10) into tJPGWidth

put bytetonum(byte 1 of tJPGWidth) into q
put bytetonum(byte 2 of tJPGWidth) into w
put baseConvert(q,10,16) into r
if the number of bytes of r = 1 then put "0" & r into r
put baseConvert(w,10,16) into t
if the number of bytes of t = 1 then put "0" & t into t
put r & t into y
put baseConvert(y,16,10) into tJPGWidth

answer "JPG Width" && tJPGWidth & cr & "JPG Height" && tJPGHeight & cr & temp

else
answer "Could not find Start of Frame information in this JPEG image" & cr & temp
end if

end mouseUp

 /*
Information from
https://stackoverflow.com/questions/35427283/get-width-and-height-from-jpeg-without-0xff-0xc0

The JPEG Start-Of-Frame (SOF) marker has 4 possible values:

    FFC0 (baseline) - This is the usual mode chosen for photos and encodes
fully specified DCT blocks in groupings depending on the color/subsample
options chosen
    FFC1 (extended) - This is similar to baseline, but has more than 8-bits
per color stimulus
    FFC2 (progressive) - This mode is often found on web pages to allow the
image to load progressively as the data is received. Each "scan" of the
image progressively defines more coefficients of the DCT blocks until
they're fully defined. This effectively provides more and more detail as
more scans are decoded
    FFC3 (lossless) - This mode uses a simple Huffman encoding to
losslessly encode the image. The only place I've seen this used is on
16-bit grayscale DICOM medical images

 */
Al

bogs
Posts: 5435
Joined: Sat Feb 25, 2017 10:45 pm

Re: Reading JPG width and height from Binary data

Post by bogs » Mon Dec 24, 2018 11:39 am

Interesting stuff Al. Thanks!
Image

capellan
Posts: 654
Joined: Wed Aug 15, 2007 11:09 pm

Re: Reading JPG width and height from Binary data

Post by capellan » Mon Dec 24, 2018 2:22 pm

Thanks Bogs! :-)

Take notice of this part of the script:

Code: Select all

put baseConvert(baseConvert(bytetonum(byte 1 of tJPGHeight),10,16) & baseConvert(bytetonum(byte 2 of tJPGHeight),10,16),16,10) into tJPGHeight
This code fails to produce correct results if the hexadecimal conversion
produces a single hexadecimal digit like any of these:
0 1 2 3 4 5 6 7 8 9 a b c d e f

For this reason, I had to change this single line of code
to many lines just to add a zero "0" before
the single hexadecimal number, in this way:
00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f

Code: Select all

put bytetonum(byte 1 of tJPGHeight) into q
put bytetonum(byte 2 of tJPGHeight) into w
put baseConvert(q,10,16) into r
if the number of bytes of r = 1 then put "0" & r into r
put baseConvert(w,10,16) into t
if the number of bytes of t = 1 then put "0" & t into t
put r & t into y
put baseConvert(y,16,10) into tJPGHeight
Bogs, Do you know another way to add a zero (0) before
the hexadecimal number if it is a single digit?

I tried and failed to use the format command for this purpose.

Thanks in advance!

Al

bogs
Posts: 5435
Joined: Sat Feb 25, 2017 10:45 pm

Re: Reading JPG width and height from Binary data

Post by bogs » Mon Dec 24, 2018 3:19 pm

Well, not off the top of my head, sorry. The only thing I can think of is checking the value the way you did in the 2nd example. I haven't really dived into the code yet though, currently working on (hopefully) a nice surprise for Sphere :D
Image

Klaus
Posts: 13824
Joined: Sat Apr 08, 2006 8:41 am
Location: Germany
Contact:

Re: Reading JPG width and height from Binary data

Post by Klaus » Mon Dec 24, 2018 6:10 pm

Or we just use the build-in means of LC! :D
This took 3 millisecs on my MacMini for a 3888*2592 px image:

Code: Select all

...
put the millisecs into tMS
put "/Volumes/1TB/Dokumente2/RRMC etc Hilfe/Andernfalls/Bilder Norbert HI-RES/Konzertfotos/20091115.JPG" into tFile
set the filename of the templateimage to tFile
put the formattedwidth of the templateimage & "," & the formattedheight of the templateimage & CR & the millisecs - tMS
reset the templateimage
...
3888,2592
3

Not too bad :-)
OK, Al's way is a millisecond faster, took me 2 ms for the same image file.

capellan
Posts: 654
Joined: Wed Aug 15, 2007 11:09 pm

Re: Reading JPG width and height from Binary data

Post by capellan » Tue Dec 25, 2018 12:21 am

Now I found a shorter way to get the same result:

Code: Select all

constant tBaselineJPGFrame0="ˇ¿",tProgressiveJPGFrame0="ˇ¬"
on mouseUp
   answer file "Select JPEG image";put it into temp
   open file temp for binary read;read from file temp for 100000
   put it into temp1;close file temp;set the casesensitive to true
   if offset(tBaselineJPGFrame0,temp1) is not 0 then put offset(tBaselineJPGFrame0,temp1) into tStartOFrame else put offset(tProgressiveJPGFrame0,temp1) into tStartOFrame
   if tStartOFrame is not empty then
      answer "JPG Width" && baseConvert(char 2 to 3 of format("%03s",baseConvert(bytetonum(byte (tStartOFrame + 7) of temp1),10,16)) & char 2 to 3 of format("%03s",baseConvert(bytetonum(byte (tStartOFrame + 8) of temp1),10,16)),16,10) & cr & "JPG Height" && baseConvert(char 2 to 3 of format("%03s",baseConvert(bytetonum(byte (tStartOFrame + 5) of temp1),10,16)) &  char 2 to 3 of format("%03s",baseConvert(bytetonum(byte (tStartOFrame + 6) of temp1),10,16)),16,10) & cr & temp
   else
      answer "Could not find Start of Frame information in this JPEG image" & cr & temp
   end if
end mouseUp
-- Reference: https://stackoverflow.com/questions/35427283/get-width-and-height-from-jpeg-without-0xff-0xc0

Post Reply

Return to “Multimedia”