Пример #1
0
    def decode(self, data: bytes, index: int = 0) -> int:
        """Decode a byte buffer.

		Args:
			data (bytes): data buffer to decode
			index (int, optional): index within the buffer to start at. Defaults to 0.

		Returns:
			int: offset
		"""
        ioBuf = IO(data, index)
        self.name = ioBuf.textLine
        secondLine = ioBuf.textLine.split(" ")
        self.params = {}
        numBrushes = int(secondLine[0])
        # everything that's left is a gimp-image-pipe-parameters parasite
        for i in range(1, len(secondLine)):
            param = secondLine[i].split(":", 1)
            self.params[param[0].strip()] = param[1].strip()
        self.brushes = []
        for _ in range(numBrushes):
            brush = GimpGbrBrush()
            ioBuf.index = brush.decode(
                ioBuf.data, ioBuf.index
            )  # TODO: broken.  For some reason there is extra data between brushes!
            self.brushes.append(brush)
        return ioBuf.index
Пример #2
0
	def decode(self, data: bytes, index: int = 0) -> int:
		"""Decode a byte buffer.

		Args:
			data (bytes): data buffer to decode
			index (int, optional): index within the buffer to start at. Defaults to 0.

		Returns:
			int: offset
		"""
		ioBuf = IO(data, index, boolSize=32)
		self.name = ioBuf.sz754
		self.uniqueId = ioBuf.u32
		self.visible = ioBuf.boolean
		self.linked = ioBuf.boolean
		numParasites = ioBuf.u32
		numStrokes = ioBuf.u32
		for _ in range(numParasites):
			parasite = GimpParasite()
			ioBuf.index = parasite.decode(ioBuf.data, ioBuf.index)
			self.parasites.append(parasite)
		for _ in range(numStrokes):
			gimpstroke = GimpStroke(self)
			ioBuf.index = gimpstroke.decode(ioBuf.data, ioBuf.index)
			self.strokes.append(gimpstroke)
		return ioBuf.index
Пример #3
0
    def decode(self, data: bytes, index: int = 0) -> int:
        """Decode a byte buffer.

		Args:
			data (bytes): data buffer to decode
			index (int, optional): index within the buffer to start at. Defaults to 0.

		Raises:
			RuntimeError: "unknown brush version"
			RuntimeError: "File format error.  Magic value mismatch"

		Returns:
			int: offset]
		"""
        ioBuf = IO(data, index)
        headerSize = ioBuf.u32
        self.version = ioBuf.u32
        if self.version != 2:
            raise RuntimeError(f"ERR: unknown brush version {self.version}")
        self.width = ioBuf.u32
        self.height = ioBuf.u32
        self.bpp = ioBuf.u32  # only allows grayscale or RGB
        self.mode = self.COLOR_MODES[self.bpp]
        magic = ioBuf.getBytes(4)
        if magic.decode("ascii") != "GIMP":
            raise RuntimeError('"' + magic.decode("ascii") + '" ' +
                               str(index) +
                               " File format error.  Magic value mismatch.")
        self.spacing = ioBuf.u32
        nameLen = headerSize - ioBuf.index
        self.name = ioBuf.getBytes(nameLen).decode("UTF-8")
        self.rawImage = ioBuf.getBytes(self.width * self.height * self.bpp)
        return ioBuf.index
Пример #4
0
	def _propertiesEncode(self):
		"""Encode a list of properties."""
		ioBuf = IO()
		for propertyType in range(1, self.PROP_NUM_PROPS):
			moData = self._propertyEncode(propertyType)
			if moData:
				ioBuf.addBytes(moData)
		return ioBuf.data
Пример #5
0
	def decode(self, data: bytes, index: int = 0) -> int:
		"""Decode a byte buffer

		:param data: data buffer to decode
		:param index: index within the buffer to start at
		"""
		ioBuf = IO(data, index)
		self.name = ioBuf.sz754
		self.flags = ioBuf.u32
		dataLength = ioBuf.u32
		self.data = ioBuf.getBytes(dataLength)
		return ioBuf.index
Пример #6
0
	def encode(self, gimpVersion: int, ioBuf: IO):
		"""Encode this to the file.

		NOTE: will not mess with development versions 5 or 6
		"""
		if gimpVersion < 4:
			if self.bits != 8 or not (self.gamma) or self.numberFormat != int:
				raise RuntimeError(
					f"Illegal precision ({self}" + f") for gimp version {gimpVersion}"
				)
		else:
			if gimpVersion == 4:
				if self.bits == 64:
					raise RuntimeError(
						f"Illegal precision ({self}" + f") for gimp version {gimpVersion}"
					)
				if self.numberFormat == int:
					code = (8, 16, 32).index(self.bits)
				else:
					code = (16, 32).index(self.bits) + 2
				code = code * 100
				if self.gamma:
					code += 50
			elif gimpVersion in (5, 6):
				raise NotImplementedError(f"Cannot save to gimp developer version {gimpVersion}")
			else:  # version 7 or above
				if self.numberFormat == int:
					code = (8, 16, 32).index(self.bits)
				else:
					code = (16, 32, 64).index(self.bits) + 2
				code = code * 100
				if self.gamma:
					code += 50
			ioBuf.u32 = code
Пример #7
0
    def decode(self, data: bytes, index: int = 0) -> int:
        """Decode a byte buffer.

		Steps:
		Create a new IO buffer (array of binary values)
		Grab attributes as outlined in the spec
		List of properties
		Get the image hierarchy and mask pointers
		Return the offset

		Args:
			data (bytes): data buffer to decode
			index (int, optional): index within the buffer to start at]. Defaults to 0.

		Returns:
			int: offset
		"""
        # Create a new IO buffer (array of binary values)
        ioBuf = IO(data, index)
        # Grab attributes as outlined in the spec
        self.width = ioBuf.u32
        self.height = ioBuf.u32
        self.colorMode = ioBuf.u32  # one of self.COLOR_MODES
        self.name = ioBuf.sz754
        # List of properties
        self._propertiesDecode(ioBuf)
        # Get the image hierarchy and mask pointers
        self._imageHierarchyPtr = self._pointerDecode(ioBuf)
        self._maskPtr = self._pointerDecode(ioBuf)
        self._mask = None
        self._data = data
        # Return the offset
        return ioBuf.index
Пример #8
0
	def decode(self, data: bytes, index: int = 0, numFloatsPerPoint: int = 0):
		"""Decode a byte buffer.

		Args:
			data (bytes): data buffer to decode
			index (int, optional): index within the buffer to start at. Defaults to 0.
			numFloatsPerPoint (int, optional): required so we know
			how many different brush dynamic measurements are
			inside each point. Defaults to 0.

		Returns:
			int: offset
		"""
		ioBuf = IO(data, index, boolSize=32)
		self.pressure = 1.0
		self.xTilt = 0.5
		self.yTilt = 0.5
		self.wheel = 0.5
		self.pointType = ioBuf.u32
		if numFloatsPerPoint < 1:
			numFloatsPerPoint = int((len(ioBuf.data) - ioBuf.index) / 4)
		self.x = ioBuf.float32
		self.y = ioBuf.float32
		if numFloatsPerPoint > 2:
			self.pressure = ioBuf.float32
			if numFloatsPerPoint > 3:
				self.xTilt = ioBuf.float32
				if numFloatsPerPoint > 4:
					self.yTilt = ioBuf.float32
					if numFloatsPerPoint > 5:
						self.wheel = ioBuf.float32
		return ioBuf.index
Пример #9
0
	def _pointerEncode(self, ptr: int, ioBuf: IO | None = None) -> bytearray:
		if ioBuf is None:
			ioBuf = IO()
		if self.pointerSize == 64:
			ioBuf.u64 = ptr
		else:
			ioBuf.u32 = ptr
		return ioBuf.data
Пример #10
0
	def encode(self) -> bytearray:
		"""Encode this object to a byte buffer."""
		ioBuf = IO()
		ioBuf.u32 = self.width
		ioBuf.u32 = self.height
		ioBuf.sz754 = self.name
		ioBuf.addBytes(self._propertiesEncode())
		imgH = self._imageHierarchyPtr
		if imgH is None:
			imgH = 0
		ioBuf.addBytes(self._pointerEncode(imgH))
		return ioBuf.data
Пример #11
0
	def decode(self, data: bytes, index: int = 0) -> int:
		"""Decode a byte buffer.

		Args:
			data (bytes): data buffer to decode
			index (int, optional): index within the buffer to start at. Defaults to 0.

		Returns:
			int: offset
		"""
		ioBuf = IO(data, index, boolSize=32)
		self.strokeType = ioBuf.u32
		self.closedShape = ioBuf.boolean
		numFloatsPerPoint = ioBuf.u32
		numPoints = ioBuf.u32
		for _ in range(numPoints):
			gimpPoint = GimpPoint(self)
			ioBuf.index = gimpPoint.decode(ioBuf.data, ioBuf.index, numFloatsPerPoint)
			self.points.append(gimpPoint)
		return ioBuf.index
Пример #12
0
	def _propertiesDecode(self, ioBuf: IO):
		"""Decode a list of properties."""
		while True:
			try:
				propertyType = ioBuf.u32
				dataLength = ioBuf.u32
			except struct.error:  # end of data, so that's that.
				break
			if propertyType == 0:
				break
			self._propertyDecode(propertyType, ioBuf.getBytes(dataLength))
		return ioBuf.index
Пример #13
0
	def encode(self):
		"""Convert this object to raw bytes."""
		ioBuf = IO()
		ioBuf.float32 = self.factor
		ioBuf.u32 = self.numDigits
		ioBuf.sz754 = self.id
		ioBuf.sz754 = self.symbol
		ioBuf.sz754 = self.abbrev
		ioBuf.sz754 = self.sname
		ioBuf.sz754 = self.pname
		return ioBuf.data
Пример #14
0
	def encode(self):
		"""Encode to binary data."""
		ioBuf = IO(boolSize=32)
		ioBuf.u32 = self.pointType
		ioBuf.float32 = self.x
		ioBuf.float32 = self.y
		if self.pressure is not None:
			ioBuf.float32 = self.pressure
			if self.xTilt is not None:
				ioBuf.float32 = self.xTilt
				if self.yTilt is not None:
					ioBuf.float32 = self.yTilt
					if self.wheel is not None:
						ioBuf.float32 = self.wheel
		return ioBuf.data
Пример #15
0
	def encode(self):
		"""Encode a byte buffer

		:param data: data buffer to encode
		:param index: index within the buffer to start at
		"""
		ioBuf = IO()
		ioBuf.sz754 = self.name
		ioBuf.u32 = self.flags
		ioBuf.u32 = len(self.data)
		ioBuf.addBytes(self.data)
		return ioBuf.data
Пример #16
0
	def encode(self):
		"""Encode to binary data."""
		ioBuf = IO(boolSize=32)
		ioBuf.u32 = self.strokeType
		ioBuf.boolean = self.closedShape
		# ioBuf.u32 = numFloatsPerPoint
		# ioBuf.u32 = numPoints
		for gimpPoint in self.points:
			ioBuf.addBytes(gimpPoint.encode())
		return ioBuf.data
Пример #17
0
 def encode(self):
     """Encode this object to a byte array."""
     ioBuf = IO()
     ioBuf.textLine = self.name
     # add the second line of data
     secondLine = [str(len(self.brushes))]
     for key, value in self.params.items():
         secondLine.append(f"{key}:{value}")
     ioBuf.textLine = " ".join(secondLine)
     # add the brushes
     for brush in self.brushes:
         ioBuf.addBytes(brush.encode())
     return ioBuf.data
Пример #18
0
	def decode(self, data: bytes, index: int = 0) -> int:
		"""Decode a byte buffer.

		Args:
			data (bytes): data buffer to decode
			index (int, optional): index within the buffer to start at]. Defaults to 0.

		Returns:
			int: offset
		"""
		ioBuf = IO(data, index)
		self.factor = ioBuf.float32
		self.numDigits = ioBuf.u32
		self.id = ioBuf.sz754
		self.symbol = ioBuf.sz754
		self.abbrev = ioBuf.sz754
		self.sname = ioBuf.sz754
		self.pname = ioBuf.sz754
		return ioBuf.index
Пример #19
0
	def decode(self, data: bytes, index: int = 0) -> int:
		"""Decode a byte buffer.

		Args:
			data (bytes): data to decode
			index (int, optional): index to start from. Defaults to 0.

		Returns:
			int: pointer
		"""
		ioBuf = IO(data, index)
		# print 'Decoding channel at',index
		self.width = ioBuf.u32
		self.height = ioBuf.u32
		self.name = ioBuf.sz754
		self._propertiesDecode(ioBuf)
		self._imageHierarchyPtr = self._pointerDecode(ioBuf)
		self._data = ioBuf.data
		return ioBuf.index
Пример #20
0
	def _propertyDecode(self, propertyType, data):
		"""Decode a single property.

		Many properties are in the form
		propertyType: one of PROP_
		lengthOfData: 4
		data: varies but is often ioBuf.32 or ioBuf.boolean
		"""
		ioBuf = IO(data, boolSize=32)
		# print('DECODING PROPERTY',propertyType,len(data))
		if propertyType == self.PROP_COLORMAP:
			self._colormapDecode(ioBuf)
		elif propertyType == self.PROP_ACTIVE_LAYER:
			self.selected = True
		elif propertyType == self.PROP_ACTIVE_CHANNEL:
			self.selected = True
		elif propertyType == self.PROP_SELECTION:
			self.isSelection = True
		elif propertyType == self.PROP_FLOATING_SELECTION:
			self.selectionAttachedTo = ioBuf.u32
		elif propertyType == self.PROP_OPACITY:
			self.opacity = ioBuf.u32
		elif propertyType == self.PROP_MODE:
			self.blendMode = ioBuf.u32
		elif propertyType == self.PROP_VISIBLE:
			self.visible = ioBuf.boolean
		elif propertyType == self.PROP_LINKED:
			self.isLinked = ioBuf.boolean
		elif propertyType == self.PROP_LOCK_ALPHA:
			self.lockAlpha = ioBuf.boolean
		elif propertyType == self.PROP_APPLY_MASK:
			self.applyMask = ioBuf.boolean
		elif propertyType == self.PROP_EDIT_MASK:
			self.editingMask = ioBuf.boolean
		elif propertyType == self.PROP_SHOW_MASK:
			self.showMask = ioBuf.boolean
		elif propertyType == self.PROP_SHOW_MASKED:
			self.showMasked = ioBuf.boolean
		elif propertyType == self.PROP_OFFSETS:
			self.xOffset = ioBuf.i32
			self.yOffset = ioBuf.i32
		elif propertyType == self.PROP_COLOR:
			red = ioBuf.byte
			green = ioBuf.byte
			blue = ioBuf.byte
			self.color = [red, green, blue]
		elif propertyType == self.PROP_COMPRESSION:
			self.compression = ioBuf.byte
		elif propertyType == self.PROP_GUIDES:
			self._guidelinesDecode(data)
		elif propertyType == self.PROP_RESOLUTION:
			self.horizontalResolution = ioBuf.float32
			self.verticalResolution = ioBuf.float32
		elif propertyType == self.PROP_TATTOO:
			self.uniqueId = data.hex()
		elif propertyType == self.PROP_PARASITES:
			self._parasitesDecode(data)
		elif propertyType == self.PROP_UNIT:
			self.units = ioBuf.u32
		elif propertyType == self.PROP_PATHS:
			_numPaths = ioBuf.u32
			"""
			for _ in range(numPaths):
				nRead, path = self._pathDecode_(data[index:])
				self.paths.append(path)
				index += nRead
			"""
		elif propertyType == self.PROP_USER_UNIT:
			self._userUnitsDecode(data)
		elif propertyType == self.PROP_VECTORS:
			pass
			# self._vectorsDecode_(data)
		elif propertyType == self.PROP_TEXT_LAYER_FLAGS:
			if isinstance(data, bytes):
				self.textLayerFlags = int.from_bytes(data, byteorder="big")
			else:
				self.textLayerFlags = int(data)
		elif propertyType == self.PROP_OLD_SAMPLE_POINTS:
			raise RuntimeError("ERR: old sample points structure not supported")
		elif propertyType == self.PROP_LOCK_CONTENT:
			self.locked = ioBuf.boolean
		elif propertyType == self.PROP_GROUP_ITEM:
			self.isGroup = True
		elif propertyType == self.PROP_ITEM_PATH:
			self._itemPathDecode(data)
		elif propertyType == self.PROP_GROUP_ITEM_FLAGS:
			self.groupItemFlags = ioBuf.u32
		elif propertyType == self.PROP_LOCK_POSITION:
			self.positionLocked = ioBuf.boolean
		elif propertyType == self.PROP_FLOAT_OPACITY:
			self.opacity = ioBuf.float32
		elif propertyType == self.PROP_COLOR_TAG:
			self.colorTag = ioBuf.u32
		elif propertyType == self.PROP_COMPOSITE_MODE:
			self.compositeMode = ioBuf.i32
		elif propertyType == self.PROP_COMPOSITE_SPACE:
			self.compositeSpace = ioBuf.i32
		elif propertyType == self.PROP_BLEND_SPACE:
			self.blendSpace = ioBuf.u32
		elif propertyType == self.PROP_FLOAT_COLOR:
			red = ioBuf.float32
			green = ioBuf.float32
			blue = ioBuf.float32
			self.color = [red, green, blue]
		elif propertyType == self.PROP_SAMPLE_POINTS:
			self._samplePointsDecode(data)
		else:
			raise RuntimeError(f"Unknown property id {propertyType}")
		return ioBuf.index
Пример #21
0
	def _propertyEncode(self, propertyType):
		"""Encode a single property.

		Many properties are in the form
		propertyType: one of PROP_
		lengthOfData: 4
		data: varies but is often ioBuf.32 or ioBuf.boolean

		If the property is the same as the default, or not specified, returns empty array
		"""
		ioBuf = IO(boolSize=32)
		if propertyType == self.PROP_COLORMAP:
			if self.colorMap is not None and self.colorMap:
				ioBuf.u32 = self.PROP_COLORMAP
				# ioBuf.addBytes(self._colormapEncode_())
		elif propertyType == self.PROP_ACTIVE_LAYER:
			if self.selected is not None and self.selected:
				ioBuf.u32 = self.PROP_ACTIVE_LAYER
		elif propertyType == self.PROP_ACTIVE_CHANNEL:
			if self.selected is not None and self.selected:
				ioBuf.u32 = self.PROP_ACTIVE_LAYER
		elif propertyType == self.PROP_SELECTION:
			if self.isSelection is not None and self.isSelection:
				ioBuf.u32 = self.PROP_SELECTION
		elif propertyType == self.PROP_FLOATING_SELECTION:
			if self.selectionAttachedTo is not None:
				ioBuf.u32 = self.PROP_FLOATING_SELECTION
				ioBuf.u32 = self.selectionAttachedTo
		elif propertyType == self.PROP_OPACITY:
			if self.opacity is not None and not isinstance(self.opacity, float):
				ioBuf.u32 = self.PROP_OPACITY
				ioBuf.u32 = self.opacity
		elif propertyType == self.PROP_MODE:
			if self.blendMode is not None:
				ioBuf.u32 = self.PROP_MODE
				ioBuf.u32 = self.blendMode
		elif propertyType == self.PROP_VISIBLE:
			if self.visible is not None:
				ioBuf.u32 = self.PROP_VISIBLE
				ioBuf.boolean = self.visible
		elif propertyType == self.PROP_LINKED:
			if self.isLinked is not None and self.isLinked:
				ioBuf.u32 = self.PROP_LINKED
				ioBuf.boolean = self.isLinked
		elif propertyType == self.PROP_LOCK_ALPHA:
			if self.lockAlpha is not None and self.lockAlpha:
				ioBuf.u32 = self.PROP_LOCK_ALPHA
				ioBuf.boolean = self.lockAlpha
		elif propertyType == self.PROP_APPLY_MASK:
			if self.applyMask is not None:
				ioBuf.u32 = self.PROP_APPLY_MASK
				ioBuf.boolean = self.applyMask
		elif propertyType == self.PROP_EDIT_MASK:
			if self.editingMask is not None and self.editingMask:
				ioBuf.u32 = self.PROP_EDIT_MASK
				ioBuf.boolean = self.editingMask
		elif propertyType == self.PROP_SHOW_MASK:
			if self.showMask is not None and self.showMask:
				ioBuf.u32 = self.PROP_SHOW_MASK
				ioBuf.boolean = self.showMask
		elif propertyType == self.PROP_SHOW_MASKED:
			if self.showMasked is not None:
				ioBuf.u32 = self.PROP_SHOW_MASKED
				ioBuf.boolean = self.showMasked
		elif propertyType == self.PROP_OFFSETS:
			if self.xOffset is not None and self.yOffset is not None:
				ioBuf.u32 = self.PROP_OFFSETS
				ioBuf.i32 = self.xOffset
				ioBuf.i32 = self.yOffset
		elif propertyType == self.PROP_COLOR:
			if (
				self.color is not None
				and not isinstance(self.color[0], float)
				and not isinstance(self.color[1], float)
				and not isinstance(self.color[2], float)
			):
				ioBuf.u32 = self.PROP_COLOR
				ioBuf.byte = self.color[0]
				ioBuf.byte = self.color[1]
				ioBuf.byte = self.color[2]
		elif propertyType == self.PROP_COMPRESSION:
			if self.compression is not None:
				ioBuf.u32 = self.PROP_COMPRESSION
				ioBuf.u32 = self.compression
		elif propertyType == self.PROP_GUIDES:
			if self.guidelines is not None and self.guidelines:
				pass
				# ioBuf.u32 = self.PROP_GUIDES
				# ioBuf.addBytes(self._guidelinesEncode_())
		elif propertyType == self.PROP_RESOLUTION:
			if self.horizontalResolution is not None and self.verticalResolution is not None:
				ioBuf.u32 = self.PROP_RESOLUTION
				ioBuf.u32 = int(self.horizontalResolution)
				ioBuf.i32 = int(self.verticalResolution)
		elif propertyType == self.PROP_TATTOO:
			if self.uniqueId is not None:
				ioBuf.u32 = int(self.uniqueId, 16)
		elif propertyType == self.PROP_PARASITES:
			if self.parasites is not None and self.parasites:
				ioBuf.u32 = self.PROP_PARASITES
				ioBuf.addBytes(self._parasitesEncode())
		elif propertyType == self.PROP_UNIT:
			if self.units is not None:
				ioBuf.u32 = self.PROP_UNIT
				ioBuf.u32 = self.units
		elif propertyType == self.PROP_PATHS:
			if self.paths is not None and self.paths:
				# ioBuf.u32 = self.PROP_PATHS
				# ioBuf.u32 = len(self.paths)
				"""
				for path in self.paths:
					ioBuf.append(self._pathEncode_(path))
				"""
		elif propertyType == self.PROP_USER_UNIT:
			if self.userUnits is not None:
				pass
				# ioBuf.u32 = self.PROP_USER_UNIT
				# ioBuf.addBytes(self._userUnitsEncode_())
		elif propertyType == self.PROP_VECTORS:
			if self.vectors is not None and self.vectors:
				pass
				# ioBuf.u32 = self.PROP_VECTORS
				# ioBuf.addBytes(self._vectorsEncode_())
		elif propertyType == self.PROP_TEXT_LAYER_FLAGS:
			if self.textLayerFlags is not None:
				ioBuf.u32 = self.PROP_TEXT_LAYER_FLAGS
				ioBuf.u32 = self.textLayerFlags
		elif propertyType == self.PROP_OLD_SAMPLE_POINTS:
			pass
		elif propertyType == self.PROP_LOCK_CONTENT:
			if self.locked is not None and self.locked:
				ioBuf.u32 = self.PROP_LOCK_CONTENT
				ioBuf.boolean = self.locked
		elif propertyType == self.PROP_GROUP_ITEM:
			if self.isGroup is not None and self.isGroup:
				ioBuf.u32 = self.PROP_GROUP_ITEM
		elif propertyType == self.PROP_ITEM_PATH:
			if self.itemPath is not None:
				pass
				# ioBuf.u32 = self.PROP_ITEM_PATH
				# ioBuf.addBytes(self._itemPathEncode_())
		elif propertyType == self.PROP_GROUP_ITEM_FLAGS:
			if self.groupItemFlags is not None:
				ioBuf.u32 = self.PROP_GROUP_ITEM_FLAGS
				ioBuf.u32 = self.groupItemFlags
		elif propertyType == self.PROP_LOCK_POSITION:
			if self.positionLocked is not None and self.positionLocked:
				ioBuf.u32 = self.PROP_LOCK_POSITION
				ioBuf.boolean = self.positionLocked
		elif propertyType == self.PROP_FLOAT_OPACITY:
			if self.opacity is not None and isinstance(self.opacity, float):
				ioBuf.u32 = self.PROP_FLOAT_OPACITY
				ioBuf.float32 = self.opacity
		elif propertyType == self.PROP_COLOR_TAG:
			if self.colorTag is not None:
				ioBuf.u32 = self.PROP_COLOR_TAG
				ioBuf.u32 = self.colorTag
		elif propertyType == self.PROP_COMPOSITE_MODE:
			if self.compositeMode is not None:
				ioBuf.u32 = self.PROP_COMPOSITE_MODE
				ioBuf.i32 = self.compositeMode
		elif propertyType == self.PROP_COMPOSITE_SPACE:
			if self.compositeSpace is not None:
				ioBuf.u32 = self.PROP_COMPOSITE_SPACE
				ioBuf.i32 = self.compositeSpace
		elif propertyType == self.PROP_BLEND_SPACE:
			if self.blendSpace is not None:
				ioBuf.u32 = self.PROP_BLEND_SPACE
				ioBuf.u32 = self.blendSpace
		elif propertyType == self.PROP_FLOAT_COLOR:
			if (
				self.color is not None
				and isinstance(self.color[0], float)
				and isinstance(self.color[1], float)
				and isinstance(self.color[2], float)
			):
				ioBuf.u32 = self.PROP_FLOAT_COLOR
				ioBuf.float32 = self.color[0]
				ioBuf.float32 = self.color[1]
				ioBuf.float32 = self.color[2]
		elif propertyType == self.PROP_SAMPLE_POINTS:
			if self.samplePoints is not None and self.samplePoints:
				pass
				# ioBuf.u32 = self.PROP_SAMPLE_POINTS
				# self.addBytes(self._samplePointsEncode_())
		else:
			raise RuntimeError(f"Unknown property id {propertyType}")
		return ioBuf.data
Пример #22
0
	def encode(self):
		"""Encode to binary data."""
		ioBuf = IO(boolSize=32)
		ioBuf.sz754 = self.name
		ioBuf.u32 = self.uniqueId
		ioBuf.boolean = self.visible
		ioBuf.boolean = self.linked
		ioBuf.u32 = len(self.parasites)
		ioBuf.u32 = len(self.strokes)
		for parasite in self.parasites:
			ioBuf.addBytes(parasite.encode())
		for gimpstroke in self.strokes:
			ioBuf.addBytes(gimpstroke.encode())
		return ioBuf.data
Пример #23
0
 def encode(self):
     """Encode this object to a byte array."""
     ioBuf = IO()
     ioBuf.addBytes(self.brush.encode())
     ioBuf.addBytes(self.pattern.encode())
     return ioBuf.data
Пример #24
0
    def encode(self):
        """Encode to byte array.

		Steps:
		Create a new IO buffer (array of binary values)
		Set attributes as outlined in the spec
		List of properties
		Set the image hierarchy and mask pointers
		Return the data

		"""
        # Create a new IO buffer (array of binary values)
        dataAreaIO = IO()
        ioBuf = IO()
        # Set attributes as outlined in the spec
        ioBuf.u32 = self.width
        ioBuf.u32 = self.height
        ioBuf.u32 = self.colorMode
        ioBuf.sz754 = self.name
        # Layer properties
        ioBuf.addBytes(self._propertiesEncode())
        # Pointer to the image heirachy structure
        dataAreaIndex = ioBuf.index + self.pointerSize * 2
        ioBuf.addBytes(self._pointerEncode(dataAreaIndex))
        dataAreaIO.addBytes(self.imageHierarchy.encode())
        # ioBuf.addBytes(self._pointerEncode_(dataAreaIndex))
        # Pointer to the layer mask
        if self.mask is not None:
            dataAreaIO.addBytes(self.mask.encode())
        ioBuf.addBytes(self._pointerEncode(dataAreaIndex + dataAreaIO.index))
        ioBuf.addBytes(dataAreaIO)
        # Return the data
        return ioBuf.data
Пример #25
0
    def decode(self, data: bytes, index: int = 0) -> int:
        """Decode a byte buffer.

		Steps:
		Create a new IO buffer (array of binary values)
		Check that the file is a valid gimp xcf
		Grab the file version
		Grab other attributes as outlined in the spec
		Get precision data using the class and ioBuf buffer
		List of properties
		Get the layers and add the pointers to them
		Get the channels and add the pointers to them
		Return the offset

		Args:
			data (bytes): data buffer to decode
			index (int, optional): index within the buffer to start at]. Defaults to 0.

		Raises:
			RuntimeError: "Not a valid GIMP file"

		Returns:
			int: offset
		"""
        # Create a new IO buffer (array of binary values)
        ioBuf = IO(data, index)
        # Check that the file is a valid gimp xcf
        if ioBuf.getBytes(9) != b"gimp xcf ":
            raise RuntimeError("Not a valid GIMP file")
        # Grab the file version
        version = ioBuf.cString
        if version == "file":
            self.version = 0
        else:
            self.version = int(version[1:])
        # Grab other attributes as outlined in the spec
        self.width = ioBuf.u32
        self.height = ioBuf.u32
        self.baseColorMode = ioBuf.u32
        # Get precision data using the class and ioBuf buffer
        self.precision = Precision()
        self.precision.decode(self.version, ioBuf)
        # List of properties
        self._propertiesDecode(ioBuf)
        self._layerPtr = []
        self._layers = []
        # Get the layers and add the pointers to them
        while True:
            ptr = self._pointerDecode(ioBuf)
            if ptr == 0:
                break
            self._layerPtr.append(ptr)
            layer = GimpLayer(self)
            layer.decode(ioBuf.data, ptr)
            self._layers.append(layer)
        # Get the channels and add the pointers to them
        self._channelPtr = []
        self._channels = []
        while True:
            ptr = self._pointerDecode(ioBuf)
            if ptr == 0:
                break
            self._channelPtr.append(ptr)
            chnl = GimpChannel(self)
            chnl.decode(ioBuf.data, ptr)
            self._channels.append(chnl)
        # Return the offset
        return ioBuf.index
Пример #26
0
	def _parasitesEncode(self):
		"""Encode list of parasites."""
		ioBuf = IO()
		for parasite in self.parasites:
			ioBuf.addBytes(parasite.encode())
		return ioBuf.data
Пример #27
0
 def encode(self) -> bytearray:
     """Encode this object to byte array."""
     ioBuf = IO()
     ioBuf.u32 = 28 + len(self.name)
     ioBuf.u32 = self.version
     ioBuf.u32 = self.width
     ioBuf.u32 = self.height
     ioBuf.u32 = self.bpp
     ioBuf.addBytes("GIMP")
     ioBuf.u32 = self.spacing
     ioBuf.addBytes(self.name)
     ioBuf.addBytes(self.rawImage)
     return ioBuf.data
Пример #28
0
    def encode(self):
        """Encode to a byte array.

		Steps:
		Create a new IO buffer (array of binary values)
		The file is a valid gimp xcf
		Set the file version
		Set other attributes as outlined in the spec
		Set precision data using the class and ioBuf buffer
		List of properties
		Set the layers and add the pointers to them
		Set the channels and add the pointers to them
		Return the data

		"""
        # Create a new IO buffer (array of binary values)
        ioBuf = IO()
        # The file is a valid gimp xcf
        ioBuf.addBytes("gimp xcf ")
        # Set the file version
        ioBuf.addBytes(f"v{self.version:03d}\0")
        # Set other attributes as outlined in the spec
        ioBuf.u32 = self.width
        ioBuf.u32 = self.height
        ioBuf.u32 = self.baseColorMode
        # Set precision data using the class and ioBuf buffer
        if self.precision is None:
            self.precision = Precision()
        self.precision.encode(self.version, ioBuf)
        # List of properties
        ioBuf.addBytes(self._propertiesEncode())
        dataAreaIdx = ioBuf.index + self.pointerSize * (len(self.layers) +
                                                        len(self._channels))
        dataAreaIO = IO()
        # Set the layers and add the pointers to them
        for layer in self.layers:
            ioBuf.index = dataAreaIdx + dataAreaIO.index
            dataAreaIO.addBytes(layer.encode())
        # Set the channels and add the pointers to them
        for channel in self._channels:
            ioBuf.index = dataAreaIdx + dataAreaIO.index
            dataAreaIO.addBytes(channel.encode())
        ioBuf.addBytes(dataAreaIO)
        # Return the data
        return ioBuf.data