def _get_bit(self, coords): x, y = coords if x < 0: x += self.info.size if y < 0: y += self.info.size return self._get_pixel(tuples.add(self.info.canvas[:2], tuples.multiply((x, y), self.info.block_size)))
def _get_bit(self, coords): x, y = coords if x < 0: x += self.info.size if y < 0: y += self.info.size color = self.image.getpixel(tuples.add(self.info.canvas[:2], tuples.multiply((x, y), self.info.block_size))) return 1 if color < 128 else 0
def get_block_size(self, img_start): """ Returns the size in pixels of a single block. Right now only supports square blocks :return: A tuple of width, height in pixels of a block :rtype: tuple[int] """ for i in range(1, 20): if self.image.getpixel(tuples.add(img_start, i)) > 128: return i, i
def _get_bit(self, coords): # print('ImageScanner._get_bit: {}'.format(self._was_read)) x, y = coords if x < 0: x += self.info.size if y < 0: y += self.info.size return self._get_pixel( tuples.add(self.info.canvas[:2], tuples.multiply((x, y), self.info.block_size)))
def _get_straight_bits(self, start, length, direction, skip=()): """ Reads several bits from the specified coordinates :param tuple[int] start: The x, y of the start position :param int length: the amount of bits to read :param str direction: d(own) or l(eft) :param tuple skip: the indexes to skip. they will still be counted on for the length :return: The bits read as an integer :rtype: int """ result = 0 counted = 0 step = (0, 1) if direction == 'd' else (-1, 0) for i in range(length): if i in skip: start = tuples.add(start, step) continue result += self._get_bit(start) << counted counted += 1 start = tuples.add(start, step) return result
def _get_straight_bits(self, start, length, direction, skip=()): """ Reads several bits from the specified coordinates :param tuple[int] start: The x, y of the start position :param int length: the amount of bits to read :param str direction: r(ight), d(own), l(eft), u(p) :param tuple skip: the indexes to skip. they will still be counted on for the length :return: The bits read as an integer :rtype: int """ result = 0 counted = 0 step = (1, 0) if direction == 'r' else (0, 1) if direction == 'd' else (-1, 0) if direction == 'l' else (0, -1) for i in range(length): if i in skip: start = tuples.add(start, step) continue result += self._get_bit(start) << counted counted += 1 start = tuples.add(start, step) return result
def _get_next_pos(self, current): pos = current while pos[0] >= 0 and (pos == current or self.mask[pos] is None): step = (-1, 0) # We advance a line if we're in an odd column, but if we have the col_modified flag on, we switch it around advance_line = ((self.info.size - pos[0]) % 2 == 0) ^ self._odd_col_modifier if advance_line: step = (1, -1 if self._scan_direction == 'u' else 1) # if we're trying to advance a line but we've reached the edge, we probably shouldn't do that if (pos[1] == 0 and self._scan_direction == 'u') or (pos[1] == self.info.size - 1 and self._scan_direction == 'd'): # swap scan direction self._scan_direction = 'd' if self._scan_direction == 'u' else 'u' # go one step left step = (-1, 0) # make sure we're not tripping over the timing array if pos[0] > 0 and all(self.mask[pos[0] - 1, y] is None for y in range(self.info.size)): step = (-2, 0) self._odd_col_modifier = not self._odd_col_modifier pos = tuples.add(pos, step) return pos
def _advance_pos(self): pos = self._current while pos[0] >= 0 and (pos == self._current or pos in self.ignored_pos): step = (-1, 0) # We advance a line if we're in an odd column, but if we have the col_modified flag on, we switch it around advance_line = ((self.size - pos[0]) % 2 == 0) ^ self._odd_col_modifier if advance_line: step = (1, -1 if self._scan_direction == 'u' else 1) # if we're trying to advance a line but we've reached the edge, we should change directions if (pos[1] == 0 and self._scan_direction == 'u') or \ (pos[1] == self.size - 1 and self._scan_direction == 'd'): # swap scan direction self._scan_direction = 'd' if self._scan_direction == 'u' else 'u' # go one step left step = (-1, 0) # make sure we're not tripping over the timing array if pos[0] > 0 and all((pos[0] - 1, y) in self.ignored_pos for y in range(self.size)): step = (-2, 0) self._odd_col_modifier = not self._odd_col_modifier pos = tuples.add(pos, step) self._current = pos
def test_scalar(self): t = (-1, 0, 1, 2.5, 3) self.assertEqual((-2, -1, 0, 1.5, 2), tuples.add(t, -1)) self.assertEqual((0, 1, 2, 3.5, 4), tuples.add(t, 1)) self.assertEqual((.5, 1.5, 2.5, 4, 4.5), tuples.add(t, 1.5)) self.assertEqual(t, tuples.add(t, 0))
def test_too_short_tuple(self): t = (-1, 0, 1, 2.5, 3) self.assertRaises(IndexError, lambda: tuples.add(t, ()))
def test_weird_addition(self): t = (-1, 0, 1, 2.5, 3) self.assertRaises(TypeError, lambda: tuples.add(t, 'hello')) self.assertRaises(TypeError, lambda: tuples.add(t, None))
def test_tuple(self): t = (-1, 0, 1, 2.5, 3) self.assertEqual((-2, 0, 2, 5, 6), tuples.add(t, (-1, 0, 1, 2.5, 3))) self.assertEqual((0,) * 5, tuples.add(t, (1, 0, -1, -2.5, -3))) self.assertEqual(t, tuples.add(t, (0,) * 5))
def test_tuple(self): t = (-1, 0, 1, 2.5, 3) self.assertEqual((-2, 0, 2, 5, 6), tuples.add(t, (-1, 0, 1, 2.5, 3))) self.assertEqual((0, ) * 5, tuples.add(t, (1, 0, -1, -2.5, -3))) self.assertEqual(t, tuples.add(t, (0, ) * 5))