Пример #1
0
    def render_tile_scanlines():
        feedback_counter = 0
        for ty in range(render_ty, render_ty + render_th):
            skip_rendering = False
            if single_tile_pattern:
                # optimization for simple background patterns
                # e.g. solid color
                if ty != first_row:
                    skip_rendering = True

            for tx_rel in xrange(render_tw):
                # render one tile
                dst = arr[:, tx_rel * N:(tx_rel + 1) * N, :]
                if not skip_rendering:
                    tx = render_tx + tx_rel
                    try:
                        surface.blit_tile_into(dst, alpha, tx, ty, **kwargs)
                    except Exception:
                        logger.exception("Failed to blit tile %r of %r",
                                         (tx, ty), surface)
                        mypaintlib.tile_clear_rgba8(dst)
                if feedback_cb and feedback_counter % TILES_PER_CALLBACK == 0:
                    feedback_cb()
                feedback_counter += 1

            # yield a numpy array of the scanline without padding
            res = arr_xcrop
            if ty == last_row:
                res = res[:y + h - ty * N, :, :]
            if ty == first_row:
                res = res[y - render_ty * N:, :, :]
            yield res
Пример #2
0
    def blit_tile_into(self, dst, dst_has_alpha, tx, ty, mipmap_level=0):
        # used mainly for saving (transparent PNG)

        #assert dst_has_alpha is True

        if self.mipmap_level < mipmap_level:
            return self.mipmap.blit_tile_into(dst, dst_has_alpha, tx, ty,
                                              mipmap_level)

        assert dst.shape[2] == 4
        if dst.dtype not in ('uint16', 'uint8'):
            raise ValueError('Unsupported destination buffer type %r',
                             dst.dtype)
        dst_is_uint16 = (dst.dtype == 'uint16')

        with self.tile_request(tx, ty, readonly=True) as src:
            if src is transparent_tile.rgba:
                #dst[:] = 0 # <-- notably slower than memset()
                if dst_is_uint16:
                    mypaintlib.tile_clear_rgba16(dst)
                else:
                    mypaintlib.tile_clear_rgba8(dst)
            else:
                if dst_is_uint16:
                    # this will do memcpy, not worth to bother skipping the u channel
                    mypaintlib.tile_copy_rgba16_into_rgba16(src, dst)
                else:
                    if dst_has_alpha:
                        mypaintlib.tile_convert_rgba16_to_rgba8(src, dst)
                    else:
                        mypaintlib.tile_convert_rgbu16_to_rgbu8(src, dst)
Пример #3
0
    def blit_tile_into(self, dst, dst_has_alpha, tx, ty, mipmap_level=0):
        # used mainly for saving (transparent PNG)

        #assert dst_has_alpha is True

        if self.mipmap_level < mipmap_level:
            return self.mipmap.blit_tile_into(dst, dst_has_alpha, tx, ty, mipmap_level)

        assert dst.shape[2] == 4
        if dst.dtype not in ('uint16', 'uint8'):
            raise ValueError('Unsupported destination buffer type %r', dst.dtype)
        dst_is_uint16 = (dst.dtype == 'uint16')

        with self.tile_request(tx, ty, readonly=True) as src:
            if src is transparent_tile.rgba:
                #dst[:] = 0 # <-- notably slower than memset()
                if dst_is_uint16:
                    mypaintlib.tile_clear_rgba16(dst)
                else:
                    mypaintlib.tile_clear_rgba8(dst)
            else:
                if dst_is_uint16:
                    # this will do memcpy, not worth to bother skipping the u channel
                    mypaintlib.tile_copy_rgba16_into_rgba16(src, dst)
                else:
                    if dst_has_alpha:
                        mypaintlib.tile_convert_rgba16_to_rgba8(src, dst)
                    else:
                        mypaintlib.tile_convert_rgbu16_to_rgbu8(src, dst)
Пример #4
0
    def render_tile_scanlines():
        feedback_counter = 0
        for ty in range(render_ty, render_ty+render_th):
            skip_rendering = False
            if single_tile_pattern:
                # optimization for simple background patterns
                # e.g. solid color
                if ty != first_row:
                    skip_rendering = True

            for tx_rel in xrange(render_tw):
                # render one tile
                dst = arr[:, tx_rel*N:(tx_rel+1)*N, :]
                if not skip_rendering:
                    tx = render_tx + tx_rel
                    try:
                        surface.blit_tile_into(dst, alpha, tx, ty, **kwargs)
                    except Exception:
                        logger.exception("Failed to blit tile %r of %r",
                                         (tx, ty), surface)
                        mypaintlib.tile_clear_rgba8(dst)
                if feedback_cb and feedback_counter % TILES_PER_CALLBACK == 0:
                    feedback_cb()
                feedback_counter += 1

            # yield a numpy array of the scanline without padding
            res = arr_xcrop
            if ty == last_row:
                res = res[:y+h-ty*N, :, :]
            if ty == first_row:
                res = res[y-render_ty*N:, :, :]
            yield res
Пример #5
0
    def blit_tile_into(self,
                       dst,
                       dst_has_alpha,
                       tx,
                       ty,
                       mipmap_level=0,
                       *args,
                       **kwargs):
        """Copy one tile from this object into a destination array

        See lib.surface.TileBlittable for the parameters. This
        implementation adds an extra param:

        :param int mipmap_level: layer mipmap level to use

        Used mainly for saving (transparent PNG).

        """

        # assert dst_has_alpha is True

        if self.mipmap_level < mipmap_level:
            return self.mipmap.blit_tile_into(dst, dst_has_alpha, tx, ty,
                                              mipmap_level)

        assert dst.shape[2] == 4
        if dst.dtype not in ('uint16', 'uint8'):
            raise ValueError('Unsupported destination buffer type %r',
                             dst.dtype)
        dst_is_uint16 = (dst.dtype == 'uint16')

        with self.tile_request(tx, ty, readonly=True) as src:
            if src is transparent_tile.rgba:
                # dst[:] = 0  # <-- notably slower than memset()
                if dst_is_uint16:
                    mypaintlib.tile_clear_rgba16(dst)
                else:
                    mypaintlib.tile_clear_rgba8(dst)
            else:
                if dst_is_uint16:
                    # this will do memcpy, not worth to bother skipping
                    # the u channel
                    mypaintlib.tile_copy_rgba16_into_rgba16(src, dst)
                else:
                    if dst_has_alpha:
                        mypaintlib.tile_convert_rgba16_to_rgba8(src, dst)
                    else:
                        mypaintlib.tile_convert_rgbu16_to_rgbu8(src, dst)
Пример #6
0
    def blit_tile_into(self, dst, dst_has_alpha, tx, ty, mipmap_level=0,
                       *args, **kwargs):
        """Copy one tile from this object into a destination array

        See lib.surface.TileBlittable for the parameters. This
        implementation adds an extra param:

        :param int mipmap_level: layer mipmap level to use

        """
        # used mainly for saving (transparent PNG)

        #assert dst_has_alpha is True

        if self.mipmap_level < mipmap_level:
            return self.mipmap.blit_tile_into(dst, dst_has_alpha, tx, ty, mipmap_level)

        assert dst.shape[2] == 4
        if dst.dtype not in ('uint16', 'uint8'):
            raise ValueError('Unsupported destination buffer type %r', dst.dtype)
        dst_is_uint16 = (dst.dtype == 'uint16')

        with self.tile_request(tx, ty, readonly=True) as src:
            if src is transparent_tile.rgba:
                #dst[:] = 0 # <-- notably slower than memset()
                if dst_is_uint16:
                    mypaintlib.tile_clear_rgba16(dst)
                else:
                    mypaintlib.tile_clear_rgba8(dst)
            else:
                if dst_is_uint16:
                    # this will do memcpy, not worth to bother skipping the u channel
                    mypaintlib.tile_copy_rgba16_into_rgba16(src, dst)
                else:
                    if dst_has_alpha:
                        mypaintlib.tile_convert_rgba16_to_rgba8(src, dst)
                    else:
                        mypaintlib.tile_convert_rgbu16_to_rgbu8(src, dst)
Пример #7
0
def scanline_strips_iter(surface,
                         rect,
                         alpha=False,
                         single_tile_pattern=False,
                         **kwargs):
    """Generate (render) scanline strips from a tile-blittable object

    :param lib.surface.TileBlittable surface: Surface to iterate over
    :param bool alpha: If true, write a PNG with alpha
    :param bool single_tile_pattern: True if surface is a one tile only.
    :param tuple \*\*kwargs: Passed to blit_tile_into.

    The `alpha` parameter is passed to the surface's `blit_tile_into()`.
    Rendering is skipped for all but the first line of single-tile patterns.

    The scanline strips yielded by this generator are suitable for
    feeding to a mypaintlib.ProgressivePNGWriter.

    """
    # Sizes
    x, y, w, h = rect
    assert w > 0
    assert h > 0

    # calculate bounding box in full tiles
    render_tx = x / N
    render_ty = y / N
    render_tw = (x + w - 1) / N - render_tx + 1
    render_th = (y + h - 1) / N - render_ty + 1

    # buffer for rendering one tile row at a time
    arr = np.empty((N, render_tw * N, 4), 'uint8')  # rgba or rgbu
    # view into arr without the horizontal padding
    arr_xcrop = arr[:, x - render_tx * N:x - render_tx * N + w, :]

    first_row = render_ty
    last_row = render_ty + render_th - 1

    for ty in range(render_ty, render_ty + render_th):
        skip_rendering = False
        if single_tile_pattern:
            # optimization for simple background patterns
            # e.g. solid color
            if ty != first_row:
                skip_rendering = True

        for tx_rel in xrange(render_tw):
            # render one tile
            dst = arr[:, tx_rel * N:(tx_rel + 1) * N, :]
            if not skip_rendering:
                tx = render_tx + tx_rel
                try:
                    surface.blit_tile_into(dst, alpha, tx, ty, **kwargs)
                except Exception:
                    logger.exception("Failed to blit tile %r of %r", (tx, ty),
                                     surface)
                    mypaintlib.tile_clear_rgba8(dst)

        # yield a numpy array of the scanline without padding
        res = arr_xcrop
        if ty == last_row:
            res = res[:y + h - ty * N, :, :]
        if ty == first_row:
            res = res[y - render_ty * N:, :, :]
        yield res
Пример #8
0
def scanline_strips_iter(surface, rect, alpha=False,
                         single_tile_pattern=False, **kwargs):
    """Generate (render) scanline strips from a tile-blittable object

    :param lib.surface.TileBlittable surface: Surface to iterate over
    :param bool alpha: If true, write a PNG with alpha
    :param bool single_tile_pattern: True if surface is a one tile only.
    :param tuple \*\*kwargs: Passed to blit_tile_into.

    The `alpha` parameter is passed to the surface's `blit_tile_into()`.
    Rendering is skipped for all but the first line of single-tile patterns.

    The scanline strips yielded by this generator are suitable for
    feeding to a mypaintlib.ProgressivePNGWriter.

    """
    # Sizes
    x, y, w, h = rect
    assert w > 0
    assert h > 0

    # calculate bounding box in full tiles
    render_tx = x/N
    render_ty = y/N
    render_tw = (x+w-1)/N - render_tx + 1
    render_th = (y+h-1)/N - render_ty + 1

    # buffer for rendering one tile row at a time
    arr = numpy.empty((1*N, render_tw*N, 4), 'uint8')  # rgba or rgbu
    # view into arr without the horizontal padding
    arr_xcrop = arr[:, x-render_tx*N:x-render_tx*N+w, :]

    first_row = render_ty
    last_row = render_ty+render_th-1

    for ty in range(render_ty, render_ty+render_th):
        skip_rendering = False
        if single_tile_pattern:
            # optimization for simple background patterns
            # e.g. solid color
            if ty != first_row:
                skip_rendering = True

        for tx_rel in xrange(render_tw):
            # render one tile
            dst = arr[:, tx_rel*N:(tx_rel+1)*N, :]
            if not skip_rendering:
                tx = render_tx + tx_rel
                try:
                    surface.blit_tile_into(dst, alpha, tx, ty, **kwargs)
                except Exception:
                    logger.exception("Failed to blit tile %r of %r",
                                     (tx, ty), surface)
                    mypaintlib.tile_clear_rgba8(dst)

        # yield a numpy array of the scanline without padding
        res = arr_xcrop
        if ty == last_row:
            res = res[:y+h-ty*N, :, :]
        if ty == first_row:
            res = res[y-render_ty*N:, :, :]
        yield res