Created
January 25, 2020 15:07
-
-
Save Hermann-SW/27fb7cdb7145c233017491d69ddf9052 to your computer and use it in GitHub Desktop.
pipeable "file" command replacement for gif/jpeg/png (https://www.raspberrypi.org/forums/viewtopic.php?f=32&t=262967)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
''' | |
Pipeable "file" command replacement for gif/jpeg/png images. | |
Outputs three lines (type, width, height), followed by copy of input. | |
''' | |
import struct | |
import sys | |
def get_image_type_size(fhandle): | |
'''Determine the image type of fhandle and return its size. | |
from draco / Fred the Fantastic / Dagh Bunnstad; | |
imghdr removed and pipe handling added by HermannSW''' | |
not_ok = False, False, False, False | |
read_sofar = bytearray() | |
head = fhandle.peek(24) | |
if len(head) < 24: | |
return not_ok | |
if head[:4] == b'\x89\x50\x4e\x47': | |
check = struct.unpack('>i', head[4:8])[0] | |
if check != 0x0d0a1a0a: | |
return not_ok | |
width, height = struct.unpack('>ii', head[16:24]) | |
itype = "png" | |
elif head[:4] == b'\x47\x49\x46\x38': | |
width, height = struct.unpack('<HH', head[6:10]) | |
itype = "gif" | |
elif head[:2] == b'\xff\xd8': | |
try: | |
# Because of .peek(24) above, no .seek(0) needed. Read 0xff next | |
size = 2 | |
ftype = 0 | |
while not 0xc0 <= ftype <= 0xcf or ftype in (0xc4, 0xc8, 0xcc): | |
read_sofar += fhandle.read(size+1) | |
while read_sofar[-1] == 0xff: | |
read_sofar += fhandle.read(1) | |
ftype = read_sofar[-1] | |
read_sofar += fhandle.read(2) | |
size = struct.unpack('>H', read_sofar[-2:])[0] - 2 | |
# We are at a SOFn block | |
read_sofar += fhandle.read(1+4) # Skip `precision' byte. | |
height, width = struct.unpack('>HH', read_sofar[-4:]) | |
itype = "jpeg" | |
except Exception: #IGNORE:W0703 | |
return not_ok | |
else: | |
return not_ok | |
return itype, width, height, read_sofar | |
FROM_FILE = len(sys.argv) > 1 and sys.argv[1] != '-' | |
FHANDLE = open(sys.argv[1], 'rb') if FROM_FILE else sys.stdin.buffer | |
RET = get_image_type_size(FHANDLE) | |
if not RET[0]: | |
sys.exit() | |
print(str(RET[0])+'\n'+str(RET[1])+'\n'+str(RET[2])) | |
sys.stdout.flush() | |
# sys.exit() | |
sys.stdout.buffer.write(RET[3]) | |
while True: | |
BUF = FHANDLE.read(1024) | |
if BUF: | |
sys.stdout.buffer.write(BUF) | |
else: | |
break |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment