decodeMacroBlock static method
Implementation
static int decodeMacroBlock(
List<int> codewords,
int codeIndex,
PDF417ResultMetadata resultMetadata,
) {
if (codeIndex + _NUMBER_OF_SEQUENCE_CODEWORDS > codewords[0]) {
// we must have at least two bytes left for the segment index
throw FormatsException.instance;
}
final segmentIndexArray = List.generate(
_NUMBER_OF_SEQUENCE_CODEWORDS,
(_) => codewords[codeIndex++],
);
//List<int> segmentIndexArray = List.filled(_NUMBER_OF_SEQUENCE_CODEWORDS, 0);
//for (int i = 0; i < _NUMBER_OF_SEQUENCE_CODEWORDS; i++, codeIndex++) {
// segmentIndexArray[i] = codewords[codeIndex];
//}
final segmentIndexString = _decodeBase900toBase10(
segmentIndexArray,
_NUMBER_OF_SEQUENCE_CODEWORDS,
);
if (segmentIndexString.isEmpty) {
resultMetadata.segmentIndex = 0;
} else {
try {
resultMetadata.segmentIndex = int.parse(segmentIndexString);
} on FormatException catch (_) {
throw FormatsException.instance;
}
}
// Decoding the fileId codewords as 0-899 numbers, each 0-filled to width 3. This follows the spec
// (See ISO/IEC 15438:2015 Annex H.6) and preserves all info, but some generators (e.g. TEC-IT) write
// the fileId using text compaction, so in those cases the fileId will appear mangled.
final fileId = StringBuffer();
while (codeIndex < codewords[0] &&
codeIndex < codewords.length &&
codewords[codeIndex] != _MACRO_PDF417_TERMINATOR &&
codewords[codeIndex] != _BEGIN_MACRO_PDF417_OPTIONAL_FIELD) {
fileId.write(codewords[codeIndex].toString().padLeft(3, '0'));
codeIndex++;
}
if (fileId.isEmpty) {
// at least one fileId codeword is required (Annex H.2)
throw FormatsException.instance;
}
resultMetadata.fileId = fileId.toString();
int optionalFieldsStart = -1;
if (codewords[codeIndex] == _BEGIN_MACRO_PDF417_OPTIONAL_FIELD) {
optionalFieldsStart = codeIndex + 1;
}
while (codeIndex < codewords[0]) {
switch (codewords[codeIndex]) {
case _BEGIN_MACRO_PDF417_OPTIONAL_FIELD:
codeIndex++;
switch (codewords[codeIndex]) {
case _MACRO_PDF417_OPTIONAL_FIELD_FILE_NAME:
final fileName = ECIStringBuilder();
codeIndex = _textCompaction(codewords, codeIndex + 1, fileName);
resultMetadata.fileName = fileName.toString();
break;
case _MACRO_PDF417_OPTIONAL_FIELD_SENDER:
final sender = ECIStringBuilder();
codeIndex = _textCompaction(codewords, codeIndex + 1, sender);
resultMetadata.sender = sender.toString();
break;
case _MACRO_PDF417_OPTIONAL_FIELD_ADDRESSEE:
final addressee = ECIStringBuilder();
codeIndex = _textCompaction(codewords, codeIndex + 1, addressee);
resultMetadata.addressee = addressee.toString();
break;
case _MACRO_PDF417_OPTIONAL_FIELD_SEGMENT_COUNT:
final segmentCount = ECIStringBuilder();
codeIndex =
_numericCompaction(codewords, codeIndex + 1, segmentCount);
try {
resultMetadata.segmentCount =
int.parse(segmentCount.toString());
} on FormatException catch (_) {
throw FormatsException.instance;
}
break;
case _MACRO_PDF417_OPTIONAL_FIELD_TIME_STAMP:
final timestamp = ECIStringBuilder();
codeIndex =
_numericCompaction(codewords, codeIndex + 1, timestamp);
try {
resultMetadata.timestamp = int.parse(timestamp.toString());
} on FormatException catch (_) {
throw FormatsException.instance;
}
break;
case _MACRO_PDF417_OPTIONAL_FIELD_CHECKSUM:
final checksum = ECIStringBuilder();
codeIndex =
_numericCompaction(codewords, codeIndex + 1, checksum);
try {
resultMetadata.checksum = int.parse(checksum.toString());
} on FormatException catch (_) {
throw FormatsException.instance;
}
break;
case _MACRO_PDF417_OPTIONAL_FIELD_FILE_SIZE:
final fileSize = ECIStringBuilder();
codeIndex =
_numericCompaction(codewords, codeIndex + 1, fileSize);
try {
resultMetadata.fileSize = int.parse(fileSize.toString());
} on FormatException catch (_) {
throw FormatsException.instance;
}
break;
default:
throw FormatsException.instance;
}
break;
case _MACRO_PDF417_TERMINATOR:
codeIndex++;
resultMetadata.isLastSegment = true;
break;
default:
throw FormatsException.instance;
}
}
// copy optional fields to additional options
if (optionalFieldsStart != -1) {
int optionalFieldsLength = codeIndex - optionalFieldsStart;
if (resultMetadata.isLastSegment) {
// do not include terminator
optionalFieldsLength--;
}
if (optionalFieldsLength > 0) {
// ignore: deprecated_consistency, deprecated_member_use_from_same_package
resultMetadata.optionalData = codewords.sublist(
optionalFieldsStart,
optionalFieldsStart + optionalFieldsLength,
);
}
}
return codeIndex;
}