<commit_before># img_info.py
from collections import deque
from json import load
from loris.constants import IMG_API_NS, COMPLIANCE, FORMATS_SUPPORTED
import struct
import xml.dom.minidom

class ImgInfo(object):
	"""Info about the image.

	See: <http://www-sul.stanford.edu/iiif/image-api/#info>

	Slots:
		ident (str): The image identifier.
		width (int)
		height (int)
		tile_width (int)
		tile_height (int)
		levels [(int)]
		qualities [(str)]: 'native', 'bitonal', 'color', or 'grey'
		native_quality: 'color' or 'grey'
	"""
	__slots__ = ('scale_factors', 'width', 'tile_height', 'levels', 'height', 
		'native_quality', 'tile_width', 'qualities', 'formats', 'ident')

	def __init__(self, path, img_id=None):
		if path.endswith('.jp2'):
			self._fromJP2(path, img_id)
		elif path.endswith('.json') or path.endswith('.xml'):
			self._unmarshal(path)
		else:
			msg = 'Could not instantiate an image object from ' + path
			ex = TypeError(msg)
			raise ex

	# Other fromXXX methods could be defined
	def _fromJP2(self, path, img_id):
		"""Get info about a JP2. 

		There's enough going on here; make sure the file is available 
		(exists and readable) before passing it.
		
		See <http://library.stanford.edu/iiif/image-api/#info>

		Args:
			path (str): The absolute path to the image.
			img_id: The identifer for the image.

		Returns:
			ImgInfo
		"""
		self.ident = img_id
		self.qualities = ['native', 'bitonal']

		jp2 = open(path, 'rb')
		b = jp2.read(1)

		# Figure out color or greyscale. 
		# Depending color profiles; there's probably a better way (or more than
		# one, anyway.)
		# see: JP2 I.5.3.3 Colour Specification box
		window =  deque([], 4)
		while ''.join(window) != 'colr':
			b = jp2.read(1)
			c = struct.unpack('c', b)[0]
			window.append(c)

		b = jp2.read(1)
		meth = struct.unpack('B', b)[0]
		jp2.read(2) # over PREC and APPROX, 1 byte each
		if meth == 1: # Enumerated Colourspace
			enum_cs = int(struct.unpack(">HH", jp2.read(4))[1])
			# if enum_cs == 16:
			# 	self.native_quality = 'color'
			# 	self.qualities += ['grey', 'color']
			if enum_cs == 17:
				self.native_quality = 'grey'
				self.qualities += ['grey']
			else:
			 	self.native_quality = 'color'
			 	self.qualities += ['grey', 'color']
			 # TODO: we can't assume color just because it's not grey, probably


		# logr.debug('qualities: ' + str(self.qualities))

		b = jp2.read(1)
		while (ord(b) != 0xFF):	b = jp2.read(1)
		b = jp2.read(1) #skip over the SOC, 0x4F 
		
		while (ord(b) != 0xFF):	b = jp2.read(1)
		b = jp2.read(1) # 0x51: The SIZ marker segment
		if (ord(b) == 0x51):
			jp2.read(4) # get through Lsiz, Rsiz (16 bits each)
			self.width = int(struct.unpack(">HH", jp2.read(4))[1]) # Xsiz (32)
			self.height = int(struct.unpack(">HH", jp2.read(4))[1]) # Ysiz (32)
			#logr.debug("width: " + str(self.width))
			#logr.debug("height: " + str(self.height))
			jp2.read(8) # get through XOsiz , YOsiz  (32 bits each)
			self.tile_width = int(struct.unpack(">HH", jp2.read(4))[1]) # XTsiz (32)<commit_msg>still having trouble with info.native_quality<commit_after># img_info.py
from collections import deque
from json import load
from loris.constants import IMG_API_NS, COMPLIANCE, FORMATS_SUPPORTED
import struct
import xml.dom.minidom

class ImgInfo(object):
	"""Info about the image.

	See: <http://www-sul.stanford.edu/iiif/image-api/#info>

	Slots:
		ident (str): The image identifier.
		width (int)
		height (int)
		tile_width (int)
		tile_height (int)
		levels [(int)]
		qualities [(str)]: 'native', 'bitonal', 'color', or 'grey'
		native_quality: 'color' or 'grey'
	"""
	__slots__ = ('scale_factors', 'width', 'tile_height', 'levels', 'height', 
		'native_quality', 'tile_width', 'qualities', 'formats', 'ident')

	def __init__(self, path, img_id=None):
		if path.endswith('.jp2'):
			self._fromJP2(path, img_id)
		elif path.endswith('.json') or path.endswith('.xml'):
			self._unmarshal(path)
		else:
			msg = 'Could not instantiate an image object from ' + path
			ex = TypeError(msg)
			raise ex

	# Other fromXXX methods could be defined
	def _fromJP2(self, path, img_id):
		"""Get info about a JP2. 

		There's enough going on here; make sure the file is available 
		(exists and readable) before passing it.
		
		See <http://library.stanford.edu/iiif/image-api/#info>

		Args:
			path (str): The absolute path to the image.
			img_id: The identifer for the image.

		Returns:
			ImgInfo
		"""
		self.ident = img_id
		self.qualities = ['native', 'bitonal']

		jp2 = open(path, 'rb')
		b = jp2.read(1)

		# Figure out color or greyscale. 
		# Depending color profiles; there's probably a better way (or more than
		# one, anyway.)
		# see: JP2 I.5.3.3 Colour Specification box
		window =  deque([], 4)
		while ''.join(window) != 'colr':
			b = jp2.read(1)
			c = struct.unpack('c', b)[0]
			window.append(c)

		b = jp2.read(1)
		meth = struct.unpack('B', b)[0]
		jp2.read(2) # over PREC and APPROX, 1 byte each

		self.native_quality = 'color' # TODO: HACK, this is an assumption
		if meth == 1: # Enumerated Colourspace
			enum_cs = int(struct.unpack(">HH", jp2.read(4))[1])
			# if enum_cs == 16:
			# 	self.native_quality = 'color'
			# 	self.qualities += ['grey', 'color']
			if enum_cs == 17:
				self.native_quality = 'grey'
				self.qualities += ['grey']
			else:
			 	self.native_quality = 'color'
			 	self.qualities += ['grey', 'color']
			 # TODO: we can't assume color just because it's not grey, probably


		# logr.debug('qualities: ' + str(self.qualities))

		b = jp2.read(1)
		while (ord(b) != 0xFF):	b = jp2.read(1)
		b = jp2.read(1) #skip over the SOC, 0x4F 
		
		while (ord(b) != 0xFF):	b = jp2.read(1)
		b = jp2.read(1) # 0x51: The SIZ marker segment
		if (ord(b) == 0x51):
			jp2.read(4) # get through Lsiz, Rsiz (16 bits each)
			self.width = int(struct.unpack(">HH", jp2.read(4))[1]) # Xsiz (32)
			self.height = int(struct.unpack(">HH", jp2.read(4))[1]) # Ysiz (32)
			#logr.debug("width: " + str(self.width))
			#logr.debug("height: " + str(self.height))
			jp2.read(8) # get through XOsiz , YOsiz  (32 bits each)
			self.tile_width = int(struct.unpack(">HH", jp2.read(4))[1]) # XTsiz (32)
{'fraction_non_alphanumeric': 0.1612115290669272, 'fraction_numerical': 0.02344894968246214, 'mean_word_length': 3.5699404761904763, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 4}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7440834', 'n_tokens_mistral': 2707, 'n_tokens_neox': 2352, 'n_words': 629}