コード例 #1
0
 /**
  * <p>When QR Codes use multiple data blocks, they are actually interleaved.
  * That is, the first byte of data block 1 to n is written, then the second bytes, and so on. This
  * method will separate the data into original blocks.</p>
  *
  * @param rawCodewords bytes as read directly from the QR Code
  * @param version version of the QR Code
  * @param ecLevel error-correction level of the QR Code
  * @return DataBlocks containing original bytes, "de-interleaved" from representation in the
  *         QR Code
  */
 static function getDataBlocks($rawCodewords, $version, $ecLevel)
 {
     if (count($rawCodewords) != $version->getTotalCodewords()) {
         throw new \InvalidArgumentException();
     }
     // Figure out the number and size of data blocks used by this version and
     // error correction level
     $ecBlocks = $version->getECBlocksForLevel($ecLevel);
     // First count the total number of data blocks
     $totalBlocks = 0;
     $ecBlockArray = $ecBlocks->getECBlocks();
     foreach ($ecBlockArray as $ecBlock) {
         $totalBlocks += $ecBlock->getCount();
     }
     // Now establish DataBlocks of the appropriate size and number of data codewords
     $result = array();
     //new DataBlock[$totalBlocks];
     $numResultBlocks = 0;
     foreach ($ecBlockArray as $ecBlock) {
         for ($i = 0; $i < $ecBlock->getCount(); $i++) {
             $numDataCodewords = $ecBlock->getDataCodewords();
             $numBlockCodewords = $ecBlocks->getECCodewordsPerBlock() + $numDataCodewords;
             $result[$numResultBlocks++] = new DataBlock($numDataCodewords, fill_array(0, $numBlockCodewords, 0));
         }
     }
     // All blocks have the same amount of data, except that the last n
     // (where n may be 0) have 1 more byte. Figure out where these start.
     $shorterBlocksTotalCodewords = count($result[0]->codewords);
     $longerBlocksStartAt = count($result) - 1;
     while ($longerBlocksStartAt >= 0) {
         $numCodewords = count($result[$longerBlocksStartAt]->codewords);
         if ($numCodewords == $shorterBlocksTotalCodewords) {
             break;
         }
         $longerBlocksStartAt--;
     }
     $longerBlocksStartAt++;
     $shorterBlocksNumDataCodewords = $shorterBlocksTotalCodewords - $ecBlocks->getECCodewordsPerBlock();
     // The last elements of result may be 1 element longer;
     // first fill out as many elements as all of them have
     $rawCodewordsOffset = 0;
     for ($i = 0; $i < $shorterBlocksNumDataCodewords; $i++) {
         for ($j = 0; $j < $numResultBlocks; $j++) {
             $result[$j]->codewords[$i] = $rawCodewords[$rawCodewordsOffset++];
         }
     }
     // Fill out the last data block in the longer ones
     for ($j = $longerBlocksStartAt; $j < $numResultBlocks; $j++) {
         $result[$j]->codewords[$shorterBlocksNumDataCodewords] = $rawCodewords[$rawCodewordsOffset++];
     }
     // Now add in error correction blocks
     $max = count($result[0]->codewords);
     for ($i = $shorterBlocksNumDataCodewords; $i < $max; $i++) {
         for ($j = 0; $j < $numResultBlocks; $j++) {
             $iOffset = $j < $longerBlocksStartAt ? $i : $i + 1;
             $result[$j]->codewords[$iOffset] = $rawCodewords[$rawCodewordsOffset++];
         }
     }
     return $result;
 }
コード例 #2
0
 /**
  * <p>Creates a finder that will search the image for three finder patterns.</p>
  *
  * @param image image to search
  */
 public function __construct($image, $resultPointCallback = null)
 {
     $this->image = $image;
     $this->possibleCenters = array();
     //new ArrayList<>();
     $this->crossCheckStateCount = fill_array(0, 5, 0);
     $this->resultPointCallback = $resultPointCallback;
 }
コード例 #3
0
 public function __construct($source)
 {
     self::$LUMINANCE_SHIFT = 8 - self::$LUMINANCE_BITS;
     self::$LUMINANCE_BUCKETS = 1 << self::$LUMINANCE_BITS;
     parent::__construct($source);
     $this->luminances = self::$EMPTY;
     $this->buckets = fill_array(0, self::$LUMINANCE_BUCKETS, 0);
     $this->source = $source;
 }
コード例 #4
0
 public function __construct($width, $height = false, $rowSize = false, $bits = false)
 {
     if (!$height) {
         $height = $width;
     }
     if (!$rowSize) {
         $rowSize = intval(($width + 31) / 32);
     }
     if (!$bits) {
         $bits = fill_array(0, $rowSize * $height, 0);
         array();
         //new int[rowSize * height];
     }
     $this->width = $width;
     $this->height = $height;
     $this->rowSize = $rowSize;
     $this->bits = $bits;
 }
コード例 #5
0
ファイル: cron.php プロジェクト: msehalic/zamger
function cron_fill_array($niz, $opseg)
{
    $rezultat = $niz;
    if (strstr($opseg, ",")) {
        foreach (explode(",", $opseg) as $element) {
            $rezultat = fill_array($rezultat, $element);
        }
    } else {
        if (strstr($opseg, "-")) {
            list($a, $b) = explode("-", $opseg);
            for ($i = $a; $i <= $b; $i++) {
                $rezultat[] = $i;
            }
        } else {
            $rezultat[] = $opseg;
        }
    }
    return $rezultat;
}
コード例 #6
0
 public function sampleGrid_($image, $dimensionX, $dimensionY, $transform)
 {
     if ($dimensionX <= 0 || $dimensionY <= 0) {
         throw NotFoundException::getNotFoundInstance();
     }
     $bits = new BitMatrix($dimensionX, $dimensionY);
     $points = fill_array(0, 2 * $dimensionX, 0.0);
     for ($y = 0; $y < $dimensionY; $y++) {
         $max = count($points);
         $iValue = (double) $y + 0.5;
         for ($x = 0; $x < $max; $x += 2) {
             $points[$x] = (double) ($x / 2) + 0.5;
             $points[$x + 1] = $iValue;
         }
         $transform->transformPoints($points);
         // Quick check to see if points transformed to something inside the image;
         // sufficient to check the endpoints
         $this->checkAndNudgePoints($image, $points);
         try {
             for ($x = 0; $x < $max; $x += 2) {
                 if ($image->get((int) $points[$x], (int) $points[$x + 1])) {
                     // Black(-ish) pixel
                     $bits->set($x / 2, $y);
                 }
             }
         } catch (\Exception $aioobe) {
             //ArrayIndexOutOfBoundsException
             // This feels wrong, but, sometimes if the finder patterns are misidentified, the resulting
             // transform gets "twisted" such that it maps a straight line of points to a set of points
             // whose endpoints are in bounds, but others are not. There is probably some mathematical
             // way to detect this about the transformation that I don't know yet.
             // This results in an ugly runtime exception despite our clever checks above -- can't have
             // that. We could check each point's coordinates but that feels duplicative. We settle for
             // catching and wrapping ArrayIndexOutOfBoundsException.
             throw NotFoundException::getNotFoundInstance();
         }
     }
     return $bits;
 }
コード例 #7
0
 private static function decodeByteSegment($bits, &$result, $count, $currentCharacterSetECI, &$byteSegments, $hints)
 {
     // Don't crash trying to read more bits than we have available.
     if (8 * $count > $bits->available()) {
         throw FormatException::getFormatInstance();
     }
     $readBytes = fill_array(0, $count, 0);
     for ($i = 0; $i < $count; $i++) {
         $readBytes[$i] = $bits->readBits(8);
         //(byte)
     }
     $text = implode(array_map('chr', $readBytes));
     $encoding = '';
     if ($currentCharacterSetECI == null) {
         // The spec isn't clear on this mode; see
         // section 6.4.5: t does not say which encoding to assuming
         // upon decoding. I have seen ISO-8859-1 used as well as
         // Shift_JIS -- without anything like an ECI designator to
         // give a hint.
         $encoding = mb_detect_encoding($text, $hints);
     } else {
         $encoding = $currentCharacterSetECI->name();
     }
     try {
         //  $result.= mb_convert_encoding($text ,$encoding);//(new String(readBytes, encoding));
         $result .= $text;
         //(new String(readBytes, encoding));
     } catch (UnsupportedEncodingException $ignored) {
         throw FormatException::getFormatInstance();
     }
     $byteSegments = array_merge($byteSegments, $readBytes);
 }
コード例 #8
0
 /**
  * Calculates a single black point for each block of pixels and saves it away.
  * See the following thread for a discussion of this algorithm:
  *  http://groups.google.com/group/zxing/browse_thread/thread/d06efa2c35a7ddc0
  */
 private static function calculateBlackPoints($luminances, $subWidth, $subHeight, $width, $height)
 {
     $blackPoints = fill_array(0, $subHeight, 0);
     foreach ($blackPoints as $key => $point) {
         $blackPoints[$key] = fill_array(0, $subWidth, 0);
     }
     for ($y = 0; $y < $subHeight; $y++) {
         $yoffset = intval32bits($y << self::$BLOCK_SIZE_POWER);
         $maxYOffset = $height - self::$BLOCK_SIZE;
         if ($yoffset > $maxYOffset) {
             $yoffset = $maxYOffset;
         }
         for ($x = 0; $x < $subWidth; $x++) {
             $xoffset = intval32bits($x << self::$BLOCK_SIZE_POWER);
             $maxXOffset = $width - self::$BLOCK_SIZE;
             if ($xoffset > $maxXOffset) {
                 $xoffset = $maxXOffset;
             }
             $sum = 0;
             $min = 0xff;
             $max = 0;
             for ($yy = 0, $offset = $yoffset * $width + $xoffset; $yy < self::$BLOCK_SIZE; $yy++, $offset += $width) {
                 for ($xx = 0; $xx < self::$BLOCK_SIZE; $xx++) {
                     $pixel = intval32bits(intval($luminances[intval($offset + $xx)]) & 0xff);
                     $sum += $pixel;
                     // still looking for good contrast
                     if ($pixel < $min) {
                         $min = $pixel;
                     }
                     if ($pixel > $max) {
                         $max = $pixel;
                     }
                 }
                 // short-circuit min/max tests once dynamic range is met
                 if ($max - $min > self::$MIN_DYNAMIC_RANGE) {
                     // finish the rest of the rows quickly
                     for ($yy++, $offset += $width; $yy < self::$BLOCK_SIZE; $yy++, $offset += $width) {
                         for ($xx = 0; $xx < self::$BLOCK_SIZE; $xx++) {
                             $sum += intval32bits($luminances[$offset + $xx] & 0xff);
                         }
                     }
                 }
             }
             // The default estimate is the average of the values in the block.
             $average = intval32bits($sum >> self::$BLOCK_SIZE_POWER * 2);
             if ($max - $min <= self::$MIN_DYNAMIC_RANGE) {
                 // If variation within the block is low, assume this is a block with only light or only
                 // dark pixels. In that case we do not want to use the average, as it would divide this
                 // low contrast area into black and white pixels, essentially creating data out of noise.
                 //
                 // The default assumption is that the block is light/background. Since no estimate for
                 // the level of dark pixels exists locally, use half the min for the block.
                 $average = intval($min / 2);
                 if ($y > 0 && $x > 0) {
                     // Correct the "white background" assumption for blocks that have neighbors by comparing
                     // the pixels in this block to the previously calculated black points. This is based on
                     // the fact that dark barcode symbology is always surrounded by some amount of light
                     // background for which reasonable black point estimates were made. The bp estimated at
                     // the boundaries is used for the interior.
                     // The (min < bp) is arbitrary but works better than other heuristics that were tried.
                     $averageNeighborBlackPoint = intval(($blackPoints[$y - 1][$x] + 2 * $blackPoints[$y][$x - 1] + $blackPoints[$y - 1][$x - 1]) / 4);
                     if ($min < $averageNeighborBlackPoint) {
                         $average = $averageNeighborBlackPoint;
                     }
                 }
             }
             $blackPoints[$y][$x] = intval($average);
         }
     }
     return $blackPoints;
 }
コード例 #9
0
 function grayScaleToBitmap($grayScale)
 {
     $middle = $this->getMiddleBrightnessPerArea($grayScale);
     $sqrtNumArea = count($middle);
     $areaWidth = floor($this->dataWidth / $sqrtNumArea);
     $areaHeight = floor($this->dataHeight / $sqrtNumArea);
     $bitmap = fill_array(0, $this->dataWidth * $this->dataHeight, 0);
     for ($ay = 0; $ay < $sqrtNumArea; $ay++) {
         for ($ax = 0; $ax < $sqrtNumArea; $ax++) {
             for ($dy = 0; $dy < $areaHeight; $dy++) {
                 for ($dx = 0; $dx < $areaWidth; $dx++) {
                     $bitmap[intval($areaWidth * $ax + $dx + ($areaHeight * $ay + $dy) * $this->dataWidth)] = $grayScale[intval($areaWidth * $ax + $dx + ($areaHeight * $ay + $dy) * $this->dataWidth)] < $middle[$ax][$ay] ? 0 : 255;
                 }
             }
         }
     }
     return $bitmap;
 }
コード例 #10
0
 public function addResultPoints($newPoints)
 {
     $oldPoints = $this->resultPoints;
     if ($oldPoints == null) {
         $this->resultPoints = $newPoints;
     } else {
         if ($newPoints != null && count($newPoints) > 0) {
             $allPoints = fill_array(0, count($oldPoints) + count($newPoints), 0);
             $allPoints = arraycopy($oldPoints, 0, $allPoints, 0, count($oldPoints));
             $allPoints = arraycopy($newPoints, 0, $allPoints, count($oldPoints), count($newPoints));
             $this->resultPoints = $allPoints;
         }
     }
 }
コード例 #11
0
 /**
  * @return the monomial representing coefficient * x^degree
  */
 function buildMonomial($degree, $coefficient)
 {
     if ($degree < 0) {
         throw new InvalidArgumentException();
     }
     if ($coefficient == 0) {
         return $this->zero;
     }
     $coefficients = fill_array(0, $degree + 1, 0);
     //new int[degree + 1];
     $coefficients[0] = $coefficient;
     return new GenericGFPoly($this, $coefficients);
 }
コード例 #12
0
 /**
  * <p>Reads the bits in the {@link BitMatrix} representing the finder pattern in the
  * correct order in order to reconstruct the codewords bytes contained within the
  * QR Code.</p>
  *
  * @return bytes encoded within the QR Code
  * @throws FormatException if the exact number of bytes expected is not read
  */
 function readCodewords()
 {
     $formatInfo = $this->readFormatInformation();
     $version = $this->readVersion();
     // Get the data mask for the format used in this QR Code. This will exclude
     // some bits from reading as we wind through the bit matrix.
     $dataMask = DataMask::forReference($formatInfo->getDataMask());
     $dimension = $this->bitMatrix->getHeight();
     $dataMask->unmaskBitMatrix($this->bitMatrix, $dimension);
     $functionPattern = $version->buildFunctionPattern();
     $readingUp = true;
     if ($version->getTotalCodewords()) {
         $result = fill_array(0, $version->getTotalCodewords(), 0);
     } else {
         $result = array();
     }
     $resultOffset = 0;
     $currentByte = 0;
     $bitsRead = 0;
     // Read columns in pairs, from right to left
     for ($j = $dimension - 1; $j > 0; $j -= 2) {
         if ($j == 6) {
             // Skip whole column with vertical alignment pattern;
             // saves time and makes the other code proceed more cleanly
             $j--;
         }
         // Read alternatingly from bottom to top then top to bottom
         for ($count = 0; $count < $dimension; $count++) {
             $i = $readingUp ? $dimension - 1 - $count : $count;
             for ($col = 0; $col < 2; $col++) {
                 // Ignore bits covered by the function pattern
                 if (!$functionPattern->get($j - $col, $i)) {
                     // Read a bit
                     $bitsRead++;
                     $currentByte <<= 1;
                     if ($this->bitMatrix->get($j - $col, $i)) {
                         $currentByte |= 1;
                     }
                     // If we've made a whole byte, save it off
                     if ($bitsRead == 8) {
                         $result[$resultOffset++] = $currentByte;
                         //(byte)
                         $bitsRead = 0;
                         $currentByte = 0;
                     }
                 }
             }
         }
         $readingUp ^= true;
         // readingUp = !readingUp; // switch directions
     }
     if ($resultOffset != $version->getTotalCodewords()) {
         throw FormatException::getFormatInstance();
     }
     return $result;
 }
コード例 #13
0
 private function findErrorMagnitudes($errorEvaluator, $errorLocations)
 {
     // This is directly applying Forney's Formula
     $s = count($errorLocations);
     $result = fill_array(0, $s, 0);
     for ($i = 0; $i < $s; $i++) {
         $xiInverse = $this->field->inverse($errorLocations[$i]);
         $denominator = 1;
         for ($j = 0; $j < $s; $j++) {
             if ($i != $j) {
                 //denominator = field.multiply(denominator,
                 //    GenericGF.addOrSubtract(1, field.multiply(errorLocations[j], xiInverse)));
                 // Above should work but fails on some Apple and Linux JDKs due to a Hotspot bug.
                 // Below is a funny-looking workaround from Steven Parkes
                 $term = $this->field->multiply($errorLocations[$j], $xiInverse);
                 $termPlus1 = ($term & 0x1) == 0 ? $term | 1 : $term & ~1;
                 $denominator = $this->field->multiply($denominator, $termPlus1);
             }
         }
         $result[$i] = $this->field->multiply($errorEvaluator->evaluateAt($xiInverse), $this->field->inverse($denominator));
         if ($this->field->getGeneratorBase() != 0) {
             $result[$i] = $this->field->multiply($result[$i], $xiInverse);
         }
     }
     return $result;
 }
コード例 #14
0
 /**
  * <p>Given data and error-correction codewords received, possibly corrupted by errors, attempts to
  * correct the errors in-place using Reed-Solomon error correction.</p>
  *
  * @param codewordBytes data and error correction codewords
  * @param numDataCodewords number of codewords that are data bytes
  * @throws ChecksumException if error correction fails
  */
 private function correctErrors(&$codewordBytes, $numDataCodewords)
 {
     $numCodewords = count($codewordBytes);
     // First read into an array of ints
     $codewordsInts = fill_array(0, $numCodewords, 0);
     for ($i = 0; $i < $numCodewords; $i++) {
         $codewordsInts[$i] = $codewordBytes[$i] & 0xff;
     }
     $numECCodewords = count($codewordBytes) - $numDataCodewords;
     try {
         $this->rsDecoder->decode($codewordsInts, $numECCodewords);
     } catch (ReedSolomonException $ignored) {
         throw ChecksumException::getChecksumInstance();
     }
     // Copy back into array of bytes -- only need to worry about the bytes that were data
     // We don't care about errors in the error-correction codewords
     for ($i = 0; $i < $numDataCodewords; $i++) {
         $codewordBytes[$i] = $codewordsInts[$i];
     }
 }