public byte[] getUnpackedData(TaskMonitor monitor) throws IOException {
		if (getSectionKind() != SectionKind.PackedData) {
			throw new IOException("Attempt to unpack a section that is not packed.");
		}
		try (InputStream input = getData()) {
			byte[] data = new byte[getUnpackedLength()];
			int index = 0;
			while (index < data.length) {
				if (monitor.isCancelled()) {
					break;
				}
				int value = input.read();
				if (value == -1) {
					throw new IllegalStateException();
				}
				int count = value & 0x1f;//count is the lower 5 bits...
				if (count == 0) {
					count = unpackNextValue(input);
				}
				PackedDataOpcodes opcode = PackedDataOpcodes.get(value >> 5);
				if (opcode == PackedDataOpcodes.kPEFPkDataZero) {
					index += count;
				}
				else if (opcode == PackedDataOpcodes.kPEFPkDataBlock) {
					byte[] rawData = new byte[count];
					int nRead = input.read(rawData);
					if (nRead != count) {
						throw new IllegalStateException(
							"Unable to read enough bytes for " + opcode);
					}
					System.arraycopy(rawData, 0, data, index, rawData.length);
					index += rawData.length;
				}
				else if (opcode == PackedDataOpcodes.kPEFPkDataRepeat) {
					int repeatCount = unpackNextValue(input);
					byte[] rawData = new byte[count];
					int nRead = input.read(rawData);
					if (nRead != rawData.length) {
						throw new IllegalStateException(
							"Unable to read enough bytes for " + opcode);
					}
					for (int i = 0; i < repeatCount + 1; ++i) {
						System.arraycopy(rawData, 0, data, index, rawData.length);
						index += rawData.length;
					}
				}
				else if (opcode == PackedDataOpcodes.kPEFPkDataRepeatBlock) {
					int commonSize = count;
					int customSize = unpackNextValue(input);
					int repeatCount = unpackNextValue(input);

					byte[] commonData = new byte[commonSize];
					int nCommonRead = input.read(commonData);
					if (nCommonRead != commonData.length) {
						throw new IllegalStateException(
							"Unable to read enough common data bytes for " + opcode);
					}

					for (int i = 0; i < repeatCount; ++i) {
						System.arraycopy(commonData, 0, data, index, commonData.length);
						index += commonData.length;

						byte[] customData = new byte[customSize];
						int nCustomRead = input.read(customData);
						if (nCustomRead != customData.length) {
							throw new IllegalStateException(
								"Unable to read enough custom data bytes for " + opcode);
						}
						System.arraycopy(customData, 0, data, index, customData.length);
						index += customData.length;
					}

					//a final common data pattern is added at end...
					System.arraycopy(commonData, 0, data, index, commonData.length);
					index += commonData.length;
				}
				else if (opcode == PackedDataOpcodes.kPEFPkDataRepeatZero) {
					int commonSize = count;
					int customSize = unpackNextValue(input);
					int repeatCount = unpackNextValue(input);

					for (int i = 0; i < repeatCount; ++i) {
						index += commonSize;//skip common size of zero bytes...

						byte[] customData = new byte[customSize];
						int nCustomRead = input.read(customData);
						if (nCustomRead != customData.length) {
							throw new IllegalStateException(
								"Unable to read enough custom data bytes for " + opcode);
						}
						System.arraycopy(customData, 0, data, index, customData.length);
						index += customData.length;
					}

					index += commonSize;//a final common size of zero bytes...
				}
				else {
					Msg.error(this, "Unrecognized packed data opcode: " + opcode);
				}
			}
			return data;
		}
	}
Unpack the data in a packed section.
Calling this method is only valid on a packed section.
@param monitor the task monitor
@return the unpacked data
@throws IOException if an i/o error occurs or the section is not packed.
Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pef/SectionHeader.java