tsixel

package
v0.0.0-...-bb82d89 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 22, 2021 License: ISC Imports: 11 Imported by: 0

Documentation

Overview

Package tsixel provides abstractions to work with SIXEL images in tcell.

Index

Constants

View Source
const MaxResizeTime = 500 * time.Millisecond

MaxResizeTime is the duration to wait since the last resize to try resizing images again. It is only useful for images with resizing enabled.

View Source
const SIXELBufferSize = 40960 // 40KB

SIXELBufferSize is the size of the pre-allocated SIXEL buffer.

View Source
const SIXELHeight = 6 // px

SIXELHeight is the height of a single SIXEL strip.

According to Wikipedia, the free encyclopedia:

Sixel encodes images by breaking up the bitmap into a series of 6-pixel
high horizontal strips.

This suggests that a SIXEL image's height can only be in multiples of 6. We must account this fact into consideration when resizing an image to not overflow a line when a cell's height is not in multiples of 6.

Variables

View Source
var (
	ErrNoDrawInterceptor = errors.New("screen does not support draw interceptors")
	ErrNoPixelDimensions = errors.New("screen does not support pixel dimensions")
	ErrNoDirectDrawer    = errors.New("screen does not support direct drawer")

	// ErrNoExplicitSync is returned if a screen does not implement sync.Locker.
	// This is needed to explicitly sync our own internal state with the screen.
	ErrNoExplicitSync = errors.New("screen does not allow explicit syncing")
)

Errors returned if the tcell screen does not have the capabilities for SIXEL.

Functions

func CharPt

func CharPt(cols, rows int) image.Point

CharPt returns a new point with twice the given columns. It's a convenient function to properly scale images by making the assumption that 2 cells make a square.

Types

type Animation

type Animation struct {
	// contains filtered or unexported fields
}

func NewAnimation

func NewAnimation(gif *gif.GIF, opts ImageOpts) *Animation

func (*Animation) Bounds

func (img *Animation) Bounds() image.Rectangle

Bounds returns the bounds of the image relative to the top-left corner of the screen in units of cells. It is capped to the dimensions of the screen and may not be the actual bounds set. The function will return a zero-sized rectangle if the image is not yet initialized.

func (*Animation) BoundsPx

func (img *Animation) BoundsPx() image.Rectangle

BoundsPx returns the Bounds but in pixels instead of cells.

func (*Animation) RequestedBounds

func (img *Animation) RequestedBounds() image.Rectangle

RequestedBounds calculates the bounds similarly to Bounds(), except the returned size is the one requested, not the one that's rescaled. This is useful for calculations relative to the corners of the screen.

func (*Animation) SetPosition

func (img *Animation) SetPosition(pos image.Point)

SetPosition sets the top-left corner of the image in units of cells.

func (*Animation) SetSize

func (img *Animation) SetSize(size image.Point)

SetSize sets the size of the image in units of cells. In other words, it sets the bottom-right corner of the image relatively to the top-left corner of the image. Note that this merely sets a hint; the actual image will never be larger than the screen OR the source image.

func (*Animation) Update

func (anim *Animation) Update(state DrawState) Frame

type DrawState

type DrawState struct {
	// Delegate is a callback to draw the screen at a later point.  Calling this
	// function without being in a goroutine will deadlock.
	Delegate func()
	// Time is the time the screen was drawn.
	Time time.Time

	Sync   bool
	Cells  image.Point
	Pixels image.Point
}

DrawState stores the screen size in two units: cells and pixels.

func (DrawState) CellSize

func (sz DrawState) CellSize() image.Point

CellSize returns the size of each cell in pixels.

func (DrawState) PtInCells

func (sz DrawState) PtInCells(pt image.Point) image.Point

PtInCells converts a point which unit is in pixels to cells. The cells are rounded up (ceiling). If DrawState's cell size is a zero-value, then a zero point is returned.

func (DrawState) PtInPixels

func (sz DrawState) PtInPixels(pt image.Point) image.Point

PtInPixels converts a point which unit is in cells to pixels.

func (DrawState) RectInCells

func (sz DrawState) RectInCells(rect image.Rectangle) image.Rectangle

RectInCells converts a rectangle which unit is in pixels into one in cells.

func (DrawState) RectInPixels

func (sz DrawState) RectInPixels(rect image.Rectangle, round bool) image.Rectangle

RectInPixels converts a rectangle which unit is in cells into one in pixels. It accounts for the cell margins if round is true. The returned rectangle is guaranteed to have roughly the same aspect ratio.

func (DrawState) RoundPt

func (sz DrawState) RoundPt(pt image.Point) image.Point

RoundPt rounds a pixel point to be within SIXEL multiples. If DrawState's cell size is a zero-value, then a zero point is returned.

type Frame

type Frame struct {
	// SIXEL is the byte slice to the raw SIXEL data of the image. The slice
	// must only be changed when Update is called.
	SIXEL []byte
	// Bounds is the current image size and position on the screen in units of
	// cells.
	Bounds image.Rectangle
	// MustUpdate, if true, will force the screen to redraw the SIXEL. The
	// screen may still redraw the SIXEL if this is false.
	MustUpdate bool
}

Frame is a representation of the image frame after an update.

type Image

type Image struct {
	// contains filtered or unexported fields
}

Image represents a SIXEL image. This image holds the source image and resizes it as needed. Each image has its own buffer and its associated encoder. To set its boundaries, use the SetBounds method. Note that the setter methods don't update the screen; the caller must manually synchronize it.

An image is not thread-safe, so it is not safe to share it across multiple screens, even with the same dimensions. This is because the synchronization of an image entirely depends on the screen it is on.

func NewImage

func NewImage(img image.Image, opts ImageOpts) *Image

NewImage creates a new SIXEL image from the given image.

func (*Image) Bounds

func (img *Image) Bounds() image.Rectangle

Bounds returns the bounds of the image relative to the top-left corner of the screen in units of cells. It is capped to the dimensions of the screen and may not be the actual bounds set. The function will return a zero-sized rectangle if the image is not yet initialized.

func (*Image) BoundsPx

func (img *Image) BoundsPx() image.Rectangle

BoundsPx returns the Bounds but in pixels instead of cells.

func (*Image) RequestedBounds

func (img *Image) RequestedBounds() image.Rectangle

RequestedBounds calculates the bounds similarly to Bounds(), except the returned size is the one requested, not the one that's rescaled. This is useful for calculations relative to the corners of the screen.

func (*Image) SetImage

func (img *Image) SetImage(newSrc image.Image)

SetImage sets the new image source into the currnet image. The processing is done immediately, so the sizes returned by the methods are guaranteed to be updated.

func (*Image) SetPosition

func (img *Image) SetPosition(pos image.Point)

SetPosition sets the top-left corner of the image in units of cells.

func (*Image) SetSize

func (img *Image) SetSize(size image.Point)

SetSize sets the size of the image in units of cells. In other words, it sets the bottom-right corner of the image relatively to the top-left corner of the image. Note that this merely sets a hint; the actual image will never be larger than the screen OR the source image.

func (*Image) Update

func (img *Image) Update(state DrawState) Frame

Update updates the image's state to the given screen, resizes the src image, and updates the internal buffer. It implements the Imager interface.

type ImageOpts

type ImageOpts struct {
	// Scaler determines the scaler to use when scaling. Most of the time,
	// ApproxBiLinear should be used.
	//
	// If Scaler is nil, then the image is never resized.
	Scaler draw.Scaler
	// KeepRatio, if true, will maintain the aspect ratio of the image when it's
	// scaled down to fit the size. The image will be anchored on the top left.
	KeepRatio bool
	// Dither, if true, will apply dithering onto the image.
	Dither bool
	// NoRounding disables SIXEL rounding. This is useful if the image sizes
	// are dynamically calculated manually and are expected to be consistent.
	NoRounding bool
}

ImageOpts represents the options of a SIXEL image. It is meant to be constant to each image.

type Imager

type Imager interface {
	// UpdateSize updates the image's sizes. After this method is called, the
	// image must be synchronized using the given state. If Update returns true,
	// then the screen will redraw the SIXEL.
	Update(state DrawState) Frame
}

Imager represents an image interface.

type ResizePipeline

type ResizePipeline struct {
	// contains filtered or unexported fields
}

func MainResizePipeline

func MainResizePipeline() *ResizePipeline

func NewResizePipeline

func NewResizePipeline() *ResizePipeline

func NewResizePipelineContext

func NewResizePipelineContext(ctx context.Context) *ResizePipeline

NewResizePipelineContext creates a new resize pipeline with the given context. Once the context is canceled

func (*ResizePipeline) QueueJob

func (pipeline *ResizePipeline) QueueJob(job ResizerJob)

QueueJob queues a resizing job. If a job with the same Imager is already queued, then its size is updated and the callback is preserved.

func (*ResizePipeline) Start

func (pipeline *ResizePipeline) Start()

Start starts the pipeline. It does nothing if the pipeline is already stopped.

func (*ResizePipeline) Stop

func (pipeline *ResizePipeline) Stop()

Stop stops the pipeline. It does nothing if the pipeline is already stopped.

type ResizerJob

type ResizerJob struct {
	Done func(ResizerJob, []byte)

	SrcImg image.Image

	Options ImageOpts
	NewSize image.Point
}

ResizerJob describes a resizing job. The resize pipeline will batch up jobs, resize them asynchronously, and call the screen once it's done.

type Screen

type Screen struct {
	// contains filtered or unexported fields
}

Screen wraps around a tcell screen to manage and draw visible SIXEL images.

func WrapInitScreen

func WrapInitScreen(s tcell.Screen) (*Screen, error)

WrapInitScreen wraps around an initialized tcell screen to create a new screen with an internal SIXEL state. It returns an error if the screen is not capable of outputting SIXEL. Note that this does not check if the terminal can draw SIXEL images. This behavior may change in the future.

func (*Screen) AddAnyImage

func (s *Screen) AddAnyImage(img image.Image, opts ImageOpts) *Image

AddAnyImage adds any image type onto the screen. It is a convenient wrapper around NewImage and AddImage.

func (*Screen) AddImage

func (s *Screen) AddImage(img Imager)

AddImage adds a SIXEL image onto the screen. This method will not redraw, so the caller should call Sync on the screen.

func (*Screen) RemoveImage

func (s *Screen) RemoveImage(img Imager)

RemoveImage removes an image from the screen. It does not redraw.

type StaticImage

type StaticImage struct {
	// contains filtered or unexported fields
}

StaticImage provides the most simple implementation to draw a SIXEL image. It provides no resizing.

func NewStaticImage

func NewStaticImage(src image.Image) *StaticImage

NewStaticImage creates a new static image from the given image.

func NewStaticImageCustom

func NewStaticImageCustom(src image.Image, dither bool, colors int) *StaticImage

NewStaticImageCustom creates a new static image with custom encoder parameters. Colors can be in-between 2 and 255.

func (*StaticImage) Bounds

func (static *StaticImage) Bounds() image.Rectangle

Bounds returns the current bounds of the static image in cells. It works similarly to Image's Bounds.

func (*StaticImage) SetImage

func (static *StaticImage) SetImage(src image.Image)

SetImage sets a new image. The image is automatically resized in the method, but a redraw will not be triggered.

func (*StaticImage) SetPosition

func (static *StaticImage) SetPosition(pt image.Point)

SetPosition sets the image position.

func (*StaticImage) Update

func (static *StaticImage) Update(state DrawState) Frame

Update returns the current SIXEL data. It

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL