Skip to content

Commit

Permalink
ファイルに分けてみる
Browse files Browse the repository at this point in the history
  • Loading branch information
pinfort committed Dec 18, 2018
1 parent 5ab55cb commit 7069bd7
Show file tree
Hide file tree
Showing 18 changed files with 648 additions and 0 deletions.
53 changes: 53 additions & 0 deletions analyzeSegment.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
from markers import Markers
from segments.SOI import SOI
from segments.EOI import EOI
from segments.SOF import SOF
from segments.DQT import DQT
from segments.DHT import DHT
from segments.COM import COM
from segments.APP import APP
from segments.SOS import SOS

class segment(object):
def __init__(self):
super(segment, self).__init__()

def analyze(self, marker, body):
if marker == Markers.JUST_FF:
return None
if marker == Markers.SOI:
# SOI (FFD8) has no body
return SOI().analyze(marker, body)
elif marker == Markers.EOI:
# EOI (FFD9) has no body
return EOI().analyze(marker, body)
if marker in Markers.SOF:
# do sof
return SOF().analyze(marker, body)
elif marker == Markers.DQT:
# do dqt
return DQT().analyze(marker, body)
elif marker == Markers.DHT:
# do dht
return DHT().analyze(marker, body)
elif marker == Markers.DRI:
# do dri
pass
elif marker == Markers.COM:
# do com
return COM().analyze(marker, body)
elif marker in Markers.APP:
# do app
return APP().analyze(marker, body)
elif marker == Markers.SOS:
# do sos
return SOS().analyze(marker, body)
elif marker in Markers.RST:
# do rst
pass
else:
raise ValueError(str(b'\xFF') + str(marker.to_bytes(1, 'big')) + " is not supported marker")
return {
"segmentName": "Not Implemented",
"length": 0,
}
52 changes: 52 additions & 0 deletions file.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
from markers import Markers

class File(object):
IS_SCANNING = False
IMAGES = []
IMG_DATA = []

def __init__(self, path):
super(File, self).__init__()
self.f = open(path, 'rb')

def __del__(self):
self.f.close()

def getData(self, count):
bt = list(self.f.read(count))
if self.IS_SCANNING:
self.IMG_DATA.extend(bt)
return bt

def __getSegmentBodyLength(self, length_for_length_data):
length = 0
for i in range(length_for_length_data):
length = length + (self.getData(1)[0] * (0x100 ** (length_for_length_data - i - 1)))
return length - length_for_length_data

def __getSegmentBody(self, length_for_length_data = 2):
body_length = self.__getSegmentBodyLength(length_for_length_data)
return self.getData(body_length)

# return dict
def getSegment(self, marker):
if marker not in Markers.REGISTERED_MARKERS:
raise Exception("unexpected marker found. it's not supported.")
if marker != Markers.JUST_FF:
# データの最後にマーカー(2ビット)がついているので末尾2ビット削除
self.IMG_DATA = self.IMG_DATA[0:len(self.IMG_DATA - 2)]
self.IMAGES.append(self.IMG_DATA)
self.IMG_DATA = []
self.IS_SCANNING = False
if marker in [Markers.JUST_FF, Markers.SOI, Markers.EOI]:
return {
"marker": marker,
"body": None,
}
body = self.__getSegmentBody()
if marker == Markers.SOS:
self.IS_SCANNING = True
return {
"marker": marker,
"body": body,
}
70 changes: 70 additions & 0 deletions markers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
class Markers(object):
SOI = 0xd8
EOI = 0xd9
JUST_FF = 0x00

# cf. https://hp.vector.co.jp/authors/VA032610/JPEGFormat/marker/SOF.htm
SOF = [
0xC0, # ハフマン / ベースライン / 非差分
0xC1, # ハフマン / シーケンシャル / 非差分
0xC2, # ハフマン / プログレッシブ / 非差分
0xC3, # ハフマン / ロスレス / 非差分
0xC5, # ハフマン / シーケンシャル / 差分
0xC6, # ハフマン / プログレッシブ / 差分
0xC7, # ハフマン / ロスレス / 差分
0xC9, # 算術 / シーケンシャル / 非差分
0xCA, # 算術 / プログレッシブ / 非差分
0xCB, # 算術 / ロスレス / 非差分
0xCD, # 算術 / シーケンシャル / 差分
0xCE, # 算術 / プログレッシブ / 差分
0xCF, # 算術 / ロスレス / 差分
]

RST = [
0xD0,
0xD1,
0xD2,
0xD3,
0xD4,
0xD5,
0xD6,
0xD7,
]

# cf. https://hp.vector.co.jp/authors/VA032610/JPEGFormat/JPEGsegment.htm
DQT = 0xDB # 量子化テーブル定義
DHT = 0xC4 # ハフマンテーブル定義
DRI = 0xDD
COM = 0xFE
SOS = 0xDA
APP = [
0xE0,
0xE1,
0xE2,
0xE3,
0xE4,
0xE5,
0xE6,
0xE7,
0xE8,
0xE9,
0xEA,
0xEB,
0xEC,
0xED,
0xEE,
0xEF,
]

REGISTERED_MARKERS = []
REGISTERED_MARKERS.extend(SOF)
REGISTERED_MARKERS.extend(APP)
REGISTERED_MARKERS.extend(RST)
REGISTERED_MARKERS.append(SOI)
REGISTERED_MARKERS.append(DQT)
REGISTERED_MARKERS.append(DHT)
REGISTERED_MARKERS.append(DRI)
REGISTERED_MARKERS.append(COM)
REGISTERED_MARKERS.append(SOS)
REGISTERED_MARKERS.append(EOI)
REGISTERED_MARKERS.append(JUST_FF)
50 changes: 50 additions & 0 deletions segments/APP.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import sys
import os
import warnings
sys.path.append(os.pardir)

from segmentsCommon import SegmentsCommon
from markers import Markers
from APPs.APP0 import APP0

class APP(SegmentsCommon):
def __init__(self):
super(APP, self).__init__()

def analyze(self, marker, body):
if marker == Markers.APP[0]:
return APP0().analyze(marker, body)
elif marker == Markers.APP[1]:
pass
elif marker == Markers.APP[2]:
pass
elif marker == Markers.APP[3]:
pass
elif marker == Markers.APP[4]:
pass
elif marker == Markers.APP[5]:
pass
elif marker == Markers.APP[6]:
pass
elif marker == Markers.APP[7]:
pass
elif marker == Markers.APP[8]:
pass
elif marker == Markers.APP[9]:
pass
elif marker == Markers.APP[10]:
pass
elif marker == Markers.APP[11]:
pass
elif marker == Markers.APP[12]:
pass
elif marker == Markers.APP[13]:
pass
elif marker == Markers.APP[14]:
pass
elif marker == Markers.APP[15]:
pass
else:
raise ValueError("invailed marker. marker " + marker.to_bytes(1, 'big') + " found. class APP is not excepting it.\nAPP expecting marker is below.\n" + str([m.to_bytes(1, 'big') for m in Markers.APP]))
# raise NotImplementedError("this type APP segment not supported. please inform to the author.")
warnings.warn("this type APP segment not supported. please inform to the author.")
27 changes: 27 additions & 0 deletions segments/APPs/APP0.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import sys
import os
sys.path.append(os.pardir)
sys.path.append("../..")

from segmentsCommon import SegmentsCommon
from markers import Markers

class APP0(SegmentsCommon):
def __init__(self):
super(APP0, self).__init__()

def analyze(self, marker, body):
analyzed = {}
analyzed["segmentName"] = "APP0"
assert body[0:5] == [ord('J'), ord('F'), ord('I'), ord('F'), 0x00], 'for APP0, JFIF is only supported. maybe it contains JFXX segment?'
# TODO: support JFXX segent
analyzed["format"] = "JFIF"
analyzed["ver"] = str(body[5]) + '.' + str(body[6])
analyzed["units"] = body[7] # 0 = None, 1 = dpi, 2 = dpcm
analyzed["xdensity"] = body[8] * 0x100 + body[9]
analyzed["ydensity"] = body[10] * 0x100 + body[11]
analyzed["xthumbnail"] = body[12]
analyzed["ythumbnail"] = body[13]
if analyzed["xthumbnail"] * analyzed["ythumbnail"] > 0:
analyzed["RGB"] = body[14:14 + 3 * analyzed["xthumbnail"] * analyzed["ythumbnail"]]
return analyzed
Empty file added segments/APPs/__init__.py
Empty file.
18 changes: 18 additions & 0 deletions segments/COM.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import sys
import os
sys.path.append(os.pardir)

from segmentsCommon import SegmentsCommon
from markers import Markers

class COM(SegmentsCommon):
def __init__(self):
super(COM, self).__init__()

def analyze(self, marker, body):
if marker != Markers.COM:
raise ValueError("invailed marker. class COM excepting marker is " + Markers.COM.to_bytes(1, 'big') + ". but " + marker.to_bytes(1, 'big') + " found.")
analyzed = {}
analyzed["segmentName"] = "COM"
analyzed["comment"] = ''.join([chr(i) for i in body])
return analyzed
Loading

0 comments on commit 7069bd7

Please sign in to comment.