in infrastructure/pillow-layer/python/PIL/Jpeg2KImagePlugin.py [0:0]
def _parse_jp2_header(fp):
"""Parse the JP2 header box to extract size, component count and
color space information, returning a (size, mode, mimetype) tuple."""
# Find the JP2 header box
header = None
mimetype = None
while True:
lbox, tbox = struct.unpack(">I4s", fp.read(8))
if lbox == 1:
lbox = struct.unpack(">Q", fp.read(8))[0]
hlen = 16
else:
hlen = 8
if lbox < hlen:
raise SyntaxError("Invalid JP2 header length")
if tbox == b"jp2h":
header = fp.read(lbox - hlen)
break
elif tbox == b"ftyp":
if fp.read(4) == b"jpx ":
mimetype = "image/jpx"
fp.seek(lbox - hlen - 4, os.SEEK_CUR)
else:
fp.seek(lbox - hlen, os.SEEK_CUR)
if header is None:
raise SyntaxError("could not find JP2 header")
size = None
mode = None
bpc = None
nc = None
hio = io.BytesIO(header)
while True:
lbox, tbox = struct.unpack(">I4s", hio.read(8))
if lbox == 1:
lbox = struct.unpack(">Q", hio.read(8))[0]
hlen = 16
else:
hlen = 8
content = hio.read(lbox - hlen)
if tbox == b"ihdr":
height, width, nc, bpc, c, unkc, ipr = struct.unpack(">IIHBBBB", content)
size = (width, height)
if unkc:
if nc == 1 and (bpc & 0x7F) > 8:
mode = "I;16"
elif nc == 1:
mode = "L"
elif nc == 2:
mode = "LA"
elif nc == 3:
mode = "RGB"
elif nc == 4:
mode = "RGBA"
break
elif tbox == b"colr":
meth, prec, approx = struct.unpack_from(">BBB", content)
if meth == 1:
cs = struct.unpack_from(">I", content, 3)[0]
if cs == 16: # sRGB
if nc == 1 and (bpc & 0x7F) > 8:
mode = "I;16"
elif nc == 1:
mode = "L"
elif nc == 3:
mode = "RGB"
elif nc == 4:
mode = "RGBA"
break
elif cs == 17: # grayscale
if nc == 1 and (bpc & 0x7F) > 8:
mode = "I;16"
elif nc == 1:
mode = "L"
elif nc == 2:
mode = "LA"
break
elif cs == 18: # sYCC
if nc == 3:
mode = "RGB"
elif nc == 4:
mode = "RGBA"
break
if size is None or mode is None:
raise SyntaxError("Malformed jp2 header")
return (size, mode, mimetype)