public static function encode($content, $eccPercent = self::DEFAULT_EC_PERCENT, $dataEncoder = null) { if (strlen($content) == 0) { throw new \InvalidArgumentException('No content provided'); } if (null === $dataEncoder) { $dataEncoder = new DynamicDataEncoder(); } elseif (!$dataEncoder instanceof DataEncoderInterface) { throw new \InvalidArgumentException('dataEncoder has to implement DataEncoderInterface'); } $bits = $dataEncoder->encode($content); $eccBits = intval($bits->getLength() * $eccPercent / 100 + 11); $totalSizeBits = $bits->getLength() + $eccBits; $layers = 0; $wordSize = 0; $totalSymbolBits = 0; $stuffedBits = null; for ($layers = 1; $layers < self::LAYERS_COMPACT; $layers++) { if (self::getBitsPerLayer($layers, false) >= $totalSizeBits) { if ($wordSize != self::$wordSize[$layers]) { $wordSize = self::$wordSize[$layers]; $stuffedBits = self::stuffBits($bits, $wordSize); } $totalSymbolBits = self::getBitsPerLayer($layers, false); if ($stuffedBits->getLength() + $eccBits <= $totalSymbolBits) { break; } } } $compact = true; if ($layers == self::LAYERS_COMPACT) { $compact = false; for ($layers = 1; $layers < self::LAYERS_FULL; $layers++) { if (self::getBitsPerLayer($layers, true) >= $totalSizeBits) { if ($wordSize != self::$wordSize[$layers]) { $wordSize = self::$wordSize[$layers]; $stuffedBits = self::stuffBits($bits, $wordSize); } $totalSymbolBits = self::getBitsPerLayer($layers, true); if ($stuffedBits->getLength() + $eccBits <= $totalSymbolBits) { break; } } } } if ($layers == self::LAYERS_FULL) { throw new \InvalidArgumentException('Data too large'); } $messageSizeInWords = intval(($stuffedBits->getLength() + $wordSize - 1) / $wordSize); for ($i = $messageSizeInWords * $wordSize - $stuffedBits->getLength(); $i > 0; $i--) { $stuffedBits->append(1); } // generate check words $rs = new ReedSolomonEncoder(self::getGF($wordSize)); $totalSizeInFullWords = intval($totalSymbolBits / $wordSize); $messageWords = self::bitsToWords($stuffedBits, $wordSize, $totalSizeInFullWords); $messageWords = $rs->encodePadded($messageWords, $totalSizeInFullWords - $messageSizeInWords); // convert to bit array and pad in the beginning $startPad = $totalSymbolBits % $wordSize; $messageBits = new BitArray(); $messageBits->append(0, $startPad); foreach ($messageWords as $messageWord) { $messageBits->append($messageWord, $wordSize); } // generate mode message $modeMessage = self::generateModeMessage($compact, $layers, $messageSizeInWords); // allocate symbol if ($compact) { $matrixSize = $baseMatrixSize = 11 + $layers * 4; $alignmentMap = array(); for ($i = 0; $i < $matrixSize; $i++) { $alignmentMap[] = $i; } } else { $baseMatrixSize = 14 + $layers * 4; $matrixSize = $baseMatrixSize + 1 + 2 * intval((intval($baseMatrixSize / 2) - 1) / 15); $alignmentMap = array_fill(0, $baseMatrixSize, 0); $origCenter = intval($baseMatrixSize / 2); $center = intval($matrixSize / 2); for ($i = 0; $i < $origCenter; $i++) { $newOffset = $i + intval($i / 15); $alignmentMap[$origCenter - $i - 1] = $center - $newOffset - 1; $alignmentMap[$origCenter + $i] = $center + $newOffset + 1; } } $matrix = new BitMatrix($matrixSize); // draw mode and data bits for ($i = 0, $rowOffset = 0; $i < $layers; $i++) { if ($compact) { $rowSize = ($layers - $i) * 4 + 9; } else { $rowSize = ($layers - $i) * 4 + 12; } for ($j = 0; $j < $rowSize; $j++) { $columnOffset = $j * 2; for ($k = 0; $k < 2; $k++) { if ($messageBits->get($rowOffset + $columnOffset + $k)) { $matrix->set($alignmentMap[$i * 2 + $k], $alignmentMap[$i * 2 + $j]); } if ($messageBits->get($rowOffset + $rowSize * 2 + $columnOffset + $k)) { $matrix->set($alignmentMap[$i * 2 + $j], $alignmentMap[$baseMatrixSize - 1 - $i * 2 - $k]); } if ($messageBits->get($rowOffset + $rowSize * 4 + $columnOffset + $k)) { $matrix->set($alignmentMap[$baseMatrixSize - 1 - $i * 2 - $k], $alignmentMap[$baseMatrixSize - 1 - $i * 2 - $j]); } if ($messageBits->get($rowOffset + $rowSize * 6 + $columnOffset + $k)) { $matrix->set($alignmentMap[$baseMatrixSize - 1 - $i * 2 - $j], $alignmentMap[$i * 2 + $k]); } } } $rowOffset += $rowSize * 8; } $matrix = self::drawModeMessage($matrix, $compact, $matrixSize, $modeMessage); // draw alignment marks if ($compact) { $matrix = self::drawBullsEye($matrix, intval($matrixSize / 2), 5); } else { $matrix = self::drawBullsEye($matrix, intval($matrixSize / 2), 7); for ($i = 0, $j = 0; $i < intval($baseMatrixSize / 2) - 1; $i += 15, $j += 16) { for ($k = intval($matrixSize / 2) & 1; $k < $matrixSize; $k += 2) { $matrix->set(intval($matrixSize / 2) - $j, $k); $matrix->set(intval($matrixSize / 2) + $j, $k); $matrix->set($k, intval($matrixSize / 2) - $j); $matrix->set($k, intval($matrixSize / 2) + $j); } } } $code = new AztecCode(); $code->setCompact($compact); $code->setSize($matrixSize); $code->setLayers($layers); $code->setCodeWords($messageSizeInWords); $code->setMatrix($matrix); return $code; }