public ResultList encode(Version version) { if (version == null) { // compute minimal encoding trying the three version sizes. Version[] versions = { getVersion(VersionSize.SMALL), getVersion(VersionSize.MEDIUM), getVersion(VersionSize.LARGE) }; ResultList[] results = { encodeSpecificVersion(versions[0]), encodeSpecificVersion(versions[1]), encodeSpecificVersion(versions[2]) }; int smallestSize = Int32.MaxValue; int smallestResult = -1; for (int i = 0; i < 3; i++) { int size = results[i].Size; if (Encoder.willFit(size, versions[i], ecLevel) && size < smallestSize) { smallestSize = size; smallestResult = i; } } if (smallestResult < 0) { throw new WriterException("Data too big for any version"); } return(results[smallestResult]); } else { // compute minimal encoding for a given version ResultList result = encodeSpecificVersion(version); if (!Encoder.willFit(result.Size, getVersion(getVersionSize(result.getVersion())), ecLevel)) { throw new WriterException("Data too big for version" + version); } return(result); } }
public ResultList(Version version, Edge solution, MinimalEncoder encoder) { this.encoder = encoder; this.version = version; var length = 0; var current = solution; var containsECI = false; while (current != null) { length += current.characterLength; Edge previous = current.previous; bool needECI = current.mode == Mode.BYTE && (previous == null && current.charsetEncoderIndex != 0) || // at the beginning and charset is not ISO-8859-1 (previous != null && current.charsetEncoderIndex != previous.charsetEncoderIndex); if (needECI) { containsECI = true; } if (previous == null || previous.mode != current.mode || needECI) { list.Insert(0, new ResultNode(current.mode, current.fromPosition, current.charsetEncoderIndex, length, encoder, this)); length = 0; } if (needECI) { list.Insert(0, new ResultNode(Mode.ECI, current.fromPosition, current.charsetEncoderIndex, 0, encoder, this)); } current = previous; } // prepend FNC1 if needed. If the bits contain an ECI then the FNC1 must be preceeded by an ECI. // If there is no ECI at the beginning then we put an ECI to the default charset (ISO-8859-1) if (encoder.isGS1) { var first = list[0]; if (first != null && first.mode != Mode.ECI && containsECI) { // prepend a default character set ECI list.Insert(0, new ResultNode(Mode.ECI, 0, 0, 0, encoder, this)); } first = list[0]; // prepend or insert a FNC1_FIRST_POSITION after the ECI (if any) var node = new ResultNode(Mode.FNC1_FIRST_POSITION, 0, 0, 0, encoder, this); if (first == null || first.mode != Mode.ECI) { list.Insert(0, node); } else { list.Insert(1, node); } } // set version to smallest version into which the bits fit. int versionNumber = version.VersionNumber; int lowerLimit; int upperLimit; switch (getVersionSize(version)) { case VersionSize.SMALL: lowerLimit = 1; upperLimit = 9; break; case VersionSize.MEDIUM: lowerLimit = 10; upperLimit = 26; break; case VersionSize.LARGE: default: lowerLimit = 27; upperLimit = 40; break; } int size = getSize(version); // increase version if needed while (versionNumber < upperLimit && !Encoder.willFit(size, Version.getVersionForNumber(versionNumber), encoder.ecLevel)) { versionNumber++; } // shrink version if possible while (versionNumber > lowerLimit && Encoder.willFit(size, Version.getVersionForNumber(versionNumber - 1), encoder.ecLevel)) { versionNumber--; } this.version = Version.getVersionForNumber(versionNumber); }