docs: def table_lookup(image, table, border_value, iterations = None):
      '''Perform a morphological transform on an image, directed by its neighbors
      
      image - a binary image
      table - a 512-element table giving the transform of each pixel given
              the values of that pixel and its 8-connected neighbors.
      border_value - the value of pixels beyond the border of the image.
                     This should test as True or False.
      
      The pixels are numbered like this:
      
      0 1 2
      3 4 5
      6 7 8
      The index at a pixel is the sum of 2**<pixel-number> for pixels
      that evaluate to true. 
      '''
      #
      # Test for a table that never transforms a zero into a one:
      #
      center_is_zero = np.array([(x & 2**4) == 0 for x in range(2**9)])
      use_index_trick = False
      if (not np.any(table[center_is_zero]) and
          (np.issubdtype(image.dtype, bool) or np.issubdtype(image.dtype, int))):
          # Use the index trick
          use_index_trick = True
          invert = False
      elif (np.all(table[~center_is_zero]) and np.issubdtype(image.dtype, bool)):
          # All ones stay ones, invert the table and the image and do the trick
          use_index_trick = True
          invert = True
          image = ~ image
          # table index 0 -> 511 and the output is reversed
          table = ~ table[511-np.arange(512)]
          border_value = not border_value
      if use_index_trick:
          orig_image = image
          index_i, index_j, image = prepare_for_index_lookup(image, border_value)
          index_i, index_j = index_lookup(index_i, index_j, 
                                          image, table, iterations)
          image = extract_from_image_lookup(orig_image, index_i, index_j)
          if invert:
              image = ~ image
          return image
      
      counter = 0
      while counter != iterations:
          counter += 1
          #
          # We accumulate into the indexer to get the index into the table
          # at each point in the image
          #
          if image.shape[0] < 3 or image.shape[1] < 3:
              image = image.astype(bool)
              indexer = np.zeros(image.shape,int)
              indexer[1:,1:]   += image[:-1,:-1] * 2**0
              indexer[1:,:]    += image[:-1,:] * 2**1
              indexer[1:,:-1]  += image[:-1,1:] * 2**2
              
              indexer[:,1:]    += image[:,:-1] * 2**3
              indexer[:,:]     += image[:,:] * 2**4
              indexer[:,:-1]   += image[:,1:] * 2**5
          
              indexer[:-1,1:]  += image[1:,:-1] * 2**6
              indexer[:-1,:]   += image[1:,:] * 2**7
              indexer[:-1,:-1] += image[1:,1:] * 2**8
          else:
              indexer = table_lookup_index(np.ascontiguousarray(image,np.uint8))
          if border_value:
              indexer[0,:]   |= 2**0 + 2**1 + 2**2
              indexer[-1,:]  |= 2**6 + 2**7 + 2**8
              indexer[:,0]   |= 2**0 + 2**3 + 2**6
              indexer[:,-1]  |= 2**2 + 2**5 + 2**8
          new_image = table[indexer]
          if np.all(new_image == image):
              break
          image = new_image
      return image