That code does accomplish 2 things:
Getting the image dimension
Find the real EOF of a jpg file
Well when googling I was more interest in the later one. The task was to cut out a jpg file from a datastream. Since I I didn't find any way to use Pythons 'image' to a way to get the EOF of so jpg-File I made up this.
Interesting things /changes/notes in this sample:
extending the normal Python file class with the method uInt16 making source code better readable and maintainable. Messing around with struct.unpack() quickly makes code to look ugly
Replaced read over'uninteresting' areas/chunk with seek
Incase you just like to get the dimensions you may remove the line:
hasChunk = ord(byte) not in range( 0xD0, 0xDA) + [0x00]
->since that only get's important when reading over the image data chunk and comment in
#break
to stop reading as soon as the dimension were found. ...but smile what I'm telling - you're the Coder ;)
import struct
import io,os
class myFile(file):
def byte( self ):
return file.read( self, 1);
def uInt16( self ):
tmp = file.read( self, 2)
return struct.unpack( ">H", tmp )[0];
jpeg = myFile('grafx_ui.s00_\\08521678_Unknown.jpg', 'rb')
try:
height = -1
width = -1
EOI = -1
type_check = jpeg.read(2)
if type_check != b'\xff\xd8':
print("Not a JPG")
else:
byte = jpeg.byte()
while byte != b"":
while byte != b'\xff': byte = jpeg.byte()
while byte == b'\xff': byte = jpeg.byte()
# FF D8 SOI Start of Image
# FF D0..7 RST DRI Define Restart Interval inside CompressedData
# FF 00 Masked FF inside CompressedData
# FF D9 EOI End of Image
# http://en.wikipedia.org/wiki/JPEG#Syntax_and_structure
hasChunk = ord(byte) not in range( 0xD0, 0xDA) + [0x00]
if hasChunk:
ChunkSize = jpeg.uInt16() - 2
ChunkOffset = jpeg.tell()
Next_ChunkOffset = ChunkOffset + ChunkSize
# Find bytes \xFF \xC0..C3 That marks the Start of Frame
if (byte >= b'\xC0' and byte <= b'\xC3'):
# Found SOF1..3 data chunk - Read it and quit
jpeg.seek(1, os.SEEK_CUR)
h = jpeg.uInt16()
w = jpeg.uInt16()
#break
elif (byte == b'\xD9'):
# Found End of Image
EOI = jpeg.tell()
break
else:
# Seek to next data chunk
print "Pos: %.4x %x" % (jpeg.tell(), ChunkSize)
if hasChunk:
jpeg.seek(Next_ChunkOffset)
byte = jpeg.byte()
width = int(w)
height = int(h)
print("Width: %s, Height: %s JpgFileDataSize: %x" % (width, height, EOI))
finally:
jpeg.close()