NEW: custom j3g binary parsing of jpg files!!! =)
This commit is contained in:
parent
d039f2a9e6
commit
5bc89da407
|
@ -0,0 +1,189 @@
|
|||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
# 0xFF,0xD8 - Start of Image (0xFFD8FF to be used as JPG file marker)
|
||||
# 0xFF,0xEn - App Exif data
|
||||
# 0xFF,0xDB - DQT - Define Quantization Table
|
||||
# 0xFF,0xDD - DRI - Define Restart Interval
|
||||
# 0xFF,0xFE - Comments
|
||||
# 0xFF,0xC0 - SOF0 - Start of Frame
|
||||
# 0xFF,0xC2 - SOF2 - Start of Frame
|
||||
# 0xFF,0xC4 - DHT - Define Huffman Tables
|
||||
# 0xFF,0xDA - SOS - Start of Scan
|
||||
# 0xFF,0xDn - RST - Restart (n=0..7)
|
||||
# 0xFF,0xD9 - EOI - End of Image
|
||||
#
|
||||
# high,low - length
|
||||
#
|
||||
# https://en.wikipedia.org/wiki/JPEG
|
||||
import re
|
||||
import struct
|
||||
import logging
|
||||
|
||||
#
|
||||
class JpgBin:
|
||||
|
||||
BUF_CHUNK_SIZE = 2048
|
||||
data_buf = None
|
||||
data_idx = 0
|
||||
data_len = 0
|
||||
fh = None
|
||||
|
||||
continue_process = True
|
||||
|
||||
metadata_h = {}
|
||||
img_bin_h = {}
|
||||
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
#
|
||||
def __isJPG(self):
|
||||
(m1, m2) = struct.unpack('>HB', self.data_buf[0:3])
|
||||
if (0xffd8 == m1 and 0xff == m2):
|
||||
self.data_idx = 2
|
||||
return True
|
||||
return False
|
||||
|
||||
#
|
||||
def processFile(self, fhandle):
|
||||
self.fh = fhandle
|
||||
self.getMoreBytes(True)
|
||||
if (self.data_buf):
|
||||
if (not self.__isJPG()):
|
||||
return False
|
||||
|
||||
while(self.continue_process):
|
||||
self.findMarker()
|
||||
self.getMoreBytes()
|
||||
|
||||
return True
|
||||
return False
|
||||
|
||||
#
|
||||
def getMoreBytes(self, force_bytes=False):
|
||||
if (self.data_idx >= (self.data_len-1) or force_bytes):
|
||||
self.data_buf = self.fh.read(self.BUF_CHUNK_SIZE)
|
||||
self.data_idx = 0
|
||||
self.data_len = len(self.data_buf)
|
||||
if (0 == self.data_len):
|
||||
self.continue_process = False
|
||||
logging.debug("DATA: len=={}".format(self.data_len))
|
||||
|
||||
#
|
||||
def calcSeekBytes(self):
|
||||
self.data_idx += 2
|
||||
(rec_len,) = struct.unpack('>H', self.data_buf[self.data_idx:self.data_idx+2])
|
||||
remain_bytes = self.data_len - self.data_idx
|
||||
if (rec_len >= remain_bytes):
|
||||
rec_diff = rec_len - remain_bytes
|
||||
self.seekBytes(rec_diff)
|
||||
else:
|
||||
self.data_idx += rec_len
|
||||
|
||||
#
|
||||
def seekBytes(self, num_bytes):
|
||||
pos = self.fh.seek(num_bytes, 1)
|
||||
logging.debug("SEEK: seek=={}, cur_loc=={}".format(num_bytes, pos))
|
||||
self.getMoreBytes(True)
|
||||
return pos
|
||||
|
||||
#
|
||||
def findMarker(self):
|
||||
(word_b,) = struct.unpack('>H', self.data_buf[self.data_idx:self.data_idx+2])
|
||||
hex_str = word_b.to_bytes(2, 'big').hex()
|
||||
# RST 0xD(n) (n==0..7)
|
||||
if (0xffd0 == word_b or 0xffd1 == word_b or 0xffd2 == word_b or 0xffd3 == word_b or 0xffd4 == word_b or 0xffd5 == word_b or 0xffd6 == word_b or 0xffd7 == word_b):
|
||||
logging.info("[ {} : RST ]".format(hex_str))
|
||||
self.markerRST()
|
||||
# Comments section
|
||||
elif (0xfffe == word_b):
|
||||
logging.info("[ {} : Comment ]".format(hex_str))
|
||||
self.markerComment()
|
||||
# DQT
|
||||
elif (0xffdb == word_b):
|
||||
logging.info("[ {} : DQT ]".format(hex_str))
|
||||
self.markerDQT()
|
||||
# DRI
|
||||
elif (0xffdd == word_b):
|
||||
logging.info("[ {} : DRI ]".format(hex_str))
|
||||
self.markerDRI()
|
||||
# SOF0 - Start of Frame 0
|
||||
elif (0xffc0 == word_b):
|
||||
logging.info("[ {} : SOF0 ]".format(hex_str))
|
||||
self.markerSOF0()
|
||||
# SOF2 - Start of Frame 2
|
||||
elif (0xffc2 == word_b):
|
||||
logging.info("[ {} : SOF2 ]".format(hex_str))
|
||||
self.markerSOF2()
|
||||
# DHT
|
||||
elif (0xffC4 == word_b):
|
||||
logging.info("[ {} : DHT ]".format(hex_str))
|
||||
self.markerDHT()
|
||||
# SOS
|
||||
elif (0xffda == word_b):
|
||||
logging.info("[ {} : SOS ]".format(hex_str))
|
||||
self.markerSOS()
|
||||
# EOI
|
||||
elif (0xffd9 == word_b):
|
||||
logging.info("[ {} : EOI ]".format(hex_str))
|
||||
self.markerEOI()
|
||||
# APP 0xE(n) - App Exif Data
|
||||
# struct.pack(">H", intt).hex()
|
||||
elif ( re.search(r'ffe.', hex_str ) ):
|
||||
logging.info("[ {} : App Data ]".format(hex_str))
|
||||
self.markerAppData()
|
||||
else:
|
||||
self.data_idx += 1
|
||||
|
||||
#
|
||||
def markerComment(self):
|
||||
self.calcSeekBytes()
|
||||
|
||||
#
|
||||
def markerDQT(self):
|
||||
self.calcSeekBytes()
|
||||
|
||||
#
|
||||
def markerDRI(self):
|
||||
self.data_idx += 4
|
||||
|
||||
#
|
||||
def markerSOF0(self):
|
||||
self.calcSeekBytes()
|
||||
|
||||
#
|
||||
def markerSOF2(self):
|
||||
self.calcSeekBytes()
|
||||
|
||||
def markerDHT(self):
|
||||
self.calcSeekBytes()
|
||||
|
||||
def markerSOS(self):
|
||||
self.calcSeekBytes()
|
||||
|
||||
def markerRST(self):
|
||||
self.data_idx += 2
|
||||
|
||||
def markerEOI(self):
|
||||
self.data_idx += 2
|
||||
# self.continue_process = False
|
||||
|
||||
def markerAppData(self):
|
||||
self.calcSeekBytes()
|
||||
|
||||
def __repr__(self):
|
||||
pass
|
||||
|
||||
|
||||
def findMarkers222(self):
|
||||
last_idx = len(self.data_buf)
|
||||
|
||||
while ord(self.data_buf[self.data_idx]) != 0xFF:
|
||||
self.data_idx = self.data_idx+1
|
||||
|
||||
for idx in range(last_idx):
|
||||
pass
|
||||
|
|
@ -2,79 +2,35 @@
|
|||
#
|
||||
#
|
||||
from PIL import Image
|
||||
from libs.jpg_bin import JpgBin
|
||||
|
||||
#
|
||||
# 0xFF,0xD8 - Start of Image
|
||||
# 0xFF,0xEn - App Exif data
|
||||
# 0xFF,0xD8 - DQT - Define Quantization Table
|
||||
# 0xFF,0xDD - DRI - Define Restart Interval
|
||||
# 0xFF,0xFE - Comments
|
||||
# 0xFF,0xC0 - SOF0 - Start of Frame
|
||||
# 0xFF,0xC2 - SOF2 - Start of Frame
|
||||
# 0xFF,0xC4 - DHT - Define Huffman Tables
|
||||
# 0xFF,0xDA - SOS - Start of Scan
|
||||
# 0xFF,0xDn - RST - Restart (n=0..7)
|
||||
# 0xFF,0xEn - Application
|
||||
# 0xFF,0xD9
|
||||
#
|
||||
#
|
||||
# https://en.wikipedia.org/wiki/JPEG
|
||||
|
||||
class JpgTools:
|
||||
|
||||
BUF_CHUNK_SIZE = 2048
|
||||
data_buf = None
|
||||
data_idx = None
|
||||
fh = None
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def getJpgBin(self, fname):
|
||||
self.processFile(fname)
|
||||
|
||||
#
|
||||
def jpgHash(self):
|
||||
|
||||
|
||||
def findMarkers(self):
|
||||
last_idx = len(self.data_buf)
|
||||
while
|
||||
|
||||
|
||||
while ord(self.data_buf[self.data_idx]) != 0xFF:
|
||||
self.data_idx = self.data_idx+1
|
||||
|
||||
for idx in range(last_idx):
|
||||
|
||||
|
||||
while self.data_buf:
|
||||
|
||||
self.getBytes
|
||||
pass
|
||||
|
||||
|
||||
def processFile(self, fname):
|
||||
self.data_buf = self.fh.read(self.BUF_CHUNK_SIZE)
|
||||
while self.data_buf:
|
||||
(ret, fin) = self.findMarkers()
|
||||
|
||||
|
||||
|
||||
#
|
||||
def getBytes(self, fname):
|
||||
if (not self.fh):
|
||||
self.fh = open(fname, "rb")
|
||||
self.data_buf = self.fh.read(self.BUF_CHUNK_SIZE)
|
||||
|
||||
|
||||
#
|
||||
def processFile(self, fname):
|
||||
self.fh = open(fname, "rb")
|
||||
self.data_buf = self.fh.read(self.BUF_CHUNK_SIZE)
|
||||
if (self.data_buf):
|
||||
self.data_idx = 0
|
||||
findMarkers()
|
||||
|
||||
|
||||
|
||||
|
||||
self.jpg = JpgBin()
|
||||
retval = self.jpg.processFile(self.fh)
|
||||
print("processFile()=={}".format(retval))
|
||||
|
||||
#
|
||||
def process_OLD(self, fname):
|
||||
|
@ -85,8 +41,7 @@ class JpgTools:
|
|||
im.tostring()
|
||||
|
||||
#
|
||||
def getJpgBin_OLD(self, fname):
|
||||
img_h = Image.open(fname)
|
||||
img_bin = list(img_h.getdata())
|
||||
return img_bin
|
||||
# def getJpgBin_OLD(self, fname):
|
||||
# img_h = Image.open(fname)
|
||||
# img_h.???
|
||||
|
||||
|
|
13
picseal.py
13
picseal.py
|
@ -22,13 +22,14 @@ def main():
|
|||
def processImage(image_fn):
|
||||
jpg = JpgTools()
|
||||
img_bin = jpg.getJpgBin(image_fn)
|
||||
sig = Signature()
|
||||
sig.genSig(img_bin)
|
||||
|
||||
(pub_fn, priv_fn) = copyImage(image_fn)
|
||||
|
||||
writePubImg(pub_fn, sig)
|
||||
writePrivImg(priv_fn, sig)
|
||||
# sig = Signature()
|
||||
# sig.genSig(img_bin)
|
||||
|
||||
# (pub_fn, priv_fn) = copyImage(image_fn)
|
||||
|
||||
# writePubImg(pub_fn, sig)
|
||||
# writePrivImg(priv_fn, sig)
|
||||
|
||||
|
||||
# add a digital signature to the metadata
|
||||
|
|
Loading…
Reference in New Issue