Scan pixels in a grid pattern along the x-coordinate then y-coordinate

    :param xi: Initial x-coordinate
    :type xi: int
    :param yi: Initial y-coordinate
    :type yi: int
    :param xf: Final x-coordinate
    :type xf: int
    :param yf: Final y-coordinate
    :type yf: int
    :param stepx: Step size in x-coordinate
    :type stepx: int
    :param stepy: Step size in y-coordinate
    :type stepy: int
    :returns: Coordinate generator
    :rtype: function

def gridscan(xi, yi, xf, yf, stepx=1, stepy=1):
    """Scan pixels in a grid pattern along the x-coordinate then y-coordinate

    :param xi: Initial x-coordinate
    :type xi: int
    :param yi: Initial y-coordinate
    :type yi: int
    :param xf: Final x-coordinate
    :type xf: int
    :param yf: Final y-coordinate
    :type yf: int
    :param stepx: Step size in x-coordinate
    :type stepx: int
    :param stepy: Step size in y-coordinate
    :type stepy: int
    :returns: Coordinate generator
    :rtype: function
    """

    if stepx <= 0: raise ValueError("X-step must be positive")
    if stepy <= 0: raise ValueError("Y-step must be positive")

    # Determine direction to move
    dx = stepx if xf >= xi else -stepx
    dy = stepy if yf >= yi else -stepy

    for y in range(yi, yf + dy, dy):
        for x in range(xi, xf + dx, dx):
            yield x, y