xtx

package module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Feb 24, 2026 License: MIT Imports: 17 Imported by: 0

README

xtx

Go library and CLI for encoding, decoding, and manipulating Xteink e-paper image and comic container formats.

Formats

Format Extension Description
XTG .xtg 1-bit monochrome image (MSB-first, packed)
XTH .xth 2-bit grayscale image (4 levels, column-major dual bit-plane)
XTC .xtc Comic container (multiple XTG pages + metadata)
XTCH .xtch Comic container (multiple XTH pages + metadata)

All formats use little-endian binary encoding. See SPEC.md for the full binary specification.

Install

Library
go get github.com/phrozen/xtx
CLI Tool

Download a pre-built binary from the Releases page (Windows, macOS, Linux), or build from source:

go install github.com/phrozen/xtx/cmd/xtx@latest

CLI Usage

xtx <command> [flags] [arguments]
Commands
encode — Convert image to XTG/XTH

The output format is inferred from the file extension (.xtg = monochrome, .xth = grayscale).

# Monochrome (inferred from .xtg)
xtx encode photo.png page.xtg

# Grayscale with dithering (inferred from .xth)
xtx encode -d photo.png page.xth

# Resize to exact dimensions
xtx encode -resize 480x800 photo.png page.xth

# Resize by width, auto-calculate height (preserves aspect ratio)
xtx encode -resize 480x-1 photo.png page.xth

# Resize by height, auto-calculate width
xtx encode -resize -1x800 photo.png page.xth
Flag Description
-g Force XTH (grayscale) regardless of extension
-dither str Dithering algorithm (none, floyd-steinberg, atkinson, sierra, sierra-lite, stucki)
-resize WxH Resize before encoding; use -1 for auto (e.g. 480x-1)
decode — Convert XTG/XTH to PNG or JPEG

Output format is inferred from extension (.jpg/.jpeg = JPEG, default = PNG).

xtx decode page.xtg output.png
xtx decode page.xth output.jpg
info — Display file header
xtx info page.xtg
# Format:      XTG (Monochrome)
# Size:        800 × 480
# Data size:   48000 bytes

xtx info comic.xtc
# Format:      XTC (Comic Container)
# Pages:       52
# Direction:   Left → Right
# Title:       My Manga
# Author:      Author Name
pack — Build XTC/XTCH from images
xtx pack -g -dither atkinson -title "My Comic" -author "Author" comic.xtc page1.png page2.png
Flag Description
-g Encode pages as XTH instead of XTG (auto-selects XTCH container)
-dither str Dithering algorithm (none, floyd-steinberg, atkinson, sierra, sierra-lite, stucki)
-dir N Reading direction: 0=LTR, 1=RTL, 2=TTB (default: 0)
-title X Set comic title
-author X Set comic author
-publisher X Set publisher name
-lang X Set language code (e.g. en, ja)
-cover N Set cover page index, 0-based (default: 0)
unpack — Extract pages from XTC/XTCH
xtx unpack comic.xtc ./pages/
# Extracts page_000.png, page_001.png, ...
cbz — Convert CBZ comic archive to XTC

Reads a CBZ (ZIP of images) and converts to an XTC container. The -format flag controls how source images are processed into pages:

Format Strategy Direction
comic Fit width, split height per-image (default) LTR
manga Fit width, split height per-image RTL
webtoon Continuous vertical stitching across images TTB

comic/manga: Each source image is resized to fit the page width, then split into multiple pages if it exceeds the page height. Page boundaries respect image boundaries — no content from one source image bleeds into the next.

webtoon: All source images are treated as a continuous vertical strip. Content flows across image boundaries, producing tightly packed pages.

# Western comic (default format, LTR)
xtx cbz -title "Batman" -author "DC Comics" volume1.cbz

# Japanese manga (RTL, per-image split)
xtx cbz -format manga -title "One Piece" -author "Oda" volume1.cbz

# Webtoon (TTB, continuous stitching)
xtx cbz -format webtoon -title "Solo Leveling" -author "Chugong" volume1.cbz

# Landscape reading: pages composed at 800×480 then rotated for e-reader
xtx cbz -format manga -landscape -title "Berserk" volume1.cbz
Flag Description
-o path Output file path (default: input with .xtc/.xtch extension)
-format X Page format: comic, manga, or webtoon (default: comic)
-landscape Landscape reading: swap page dimensions and rotate pages 90°
-mono Encode as monochrome (XTG) instead of grayscale
-dither str Dithering algorithm (none, floyd-steinberg, atkinson, sierra, sierra-lite, stucki)
-width N Page width in pixels (default: 480)
-height N Page height in pixels (default: 800)
-title X Set comic title
-author X Set comic author
-publisher X Set publisher name
-lang X Set language code (e.g. en, ja)
-cover N Set cover page index, 0-based (default: 0)

Library Usage

The library follows standard Go image idioms. Encode writes to an io.Writer, Decode reads from an io.Reader, and all image types implement image.Image.

Encoding
import "github.com/phrozen/xtx"

// func Encode(w io.Writer, img image.Image, opts *Options) error

// Encode any image.Image as monochrome XTG (nil opts = defaults)
f, _ := os.Create("page.xtg")
err := xtx.Encode(f, img, nil)

// Encode as grayscale XTH with Floyd-Steinberg dithering
f, _ := os.Create("page.xth")
err := xtx.Encode(f, img, &xtx.Options{
    Format: xtx.FormatGrayscale,
    Dither: true,
})
Decoding
// func Decode(r io.Reader) (image.Image, error)

// Decode XTG or XTH (format auto-detected from magic bytes)
f, _ := os.Open("page.xtg")
img, err := xtx.Decode(f)

// XTG/XTH are also registered with image.RegisterFormat,
// so importing the package enables standard library decoding:
import _ "github.com/phrozen/xtx"
img, format, err := image.Decode(f) // format = "xtg" or "xth"
Image Types

Both Monochrome and Grayscale implement image.Image, draw.Image, and work with the standard library's image/draw package.

// Create a 1-bit monochrome image
mono := xtx.NewMonochrome(image.Rect(0, 0, 800, 480))
mono.SetMono(x, y, xtx.MonoBlack)

// Create a 2-bit grayscale image (4 levels)
gray := xtx.NewGrayscale(image.Rect(0, 0, 480, 800))
gray.SetGray4(x, y, xtx.Gray4{V: 2}) // light grey

// Floyd-Steinberg dithering via stdlib
draw.FloydSteinberg.Draw(mono, mono.Bounds(), src, src.Bounds().Min)
Color Models
Type Bits Levels Bit Values
Mono 1 2 0=black, 1=white
Gray4 2 4 0=white, 1=dark grey, 2=light grey, 3=black

The Gray4 level mapping follows the non-linear Xteink e-paper LUT (levels 1 and 2 are swapped relative to a linear ramp).

Note: The zero-value convention is inconsistent between formats — 0 means black in Mono but white in Gray4. This matches the Xteink hardware LUT and cannot be changed. The library handles this internally, so users working with image.Image don't need to worry about it.

Comic Containers
comic := xtx.NewXTC(false) // true for XTCH variant
comic.SetDirection(xtx.RightToLeft)
comic.SetMetadata(xtx.Metadata{
    Title:  "My Manga",
    Author: "Author Name",
})

// Add pages (accepts any image.Image, encodes internally)
comic.AddPage(page1)     // as XTG (monochrome)
comic.AddPageXTH(page2)  // as XTH (grayscale)

// Write container
err := comic.Encode(w)
Image Transforms
// Resize (uses approximate bilinear interpolation)
resized := xtx.Resize(img, 480, 800)

// Aspect-ratio preserving resize
resized := xtx.ResizeToWidth(img, 480)
resized := xtx.ResizeToHeight(img, 800)

// Rotation (90° clockwise / counter-clockwise)
rotated := xtx.RotateCW(img)
rotated := xtx.RotateCCW(img)

// Create a blank white page
page := xtx.NewWhitePage(480, 800)
Reading CBZ Archives
// Read and decode all images from a CBZ file
// (filters hidden files, sorts alphabetically)
images, err := xtx.ReadCBZ("volume1.cbz")

Reading Direction

Comic containers support three reading directions, matching the XTC specification:

Value Constant Description
0 LeftToRight Western comics (default)
1 RightToLeft Japanese manga
2 TopToBottom Webtoons / vertical scroll

Project Structure

cmd/
└── xtx/
    ├── main.go        CLI entry point and usage text
    ├── encode.go      encode command
    ├── decode.go      decode command
    ├── info.go        info command
    ├── pack.go        pack command
    ├── unpack.go      unpack command
    ├── cbz.go         cbz command
    └── util.go        shared helpers (image loading)
xtx.go               Core types, constants, errors
color.go             Mono and Gray4 color types and models
monochrome.go        1-bit image type (image.Image)
grayscale.go         2-bit image type (image.Image)
header.go            22-byte XTG/XTH header read/write/validate
encode.go            Encode image.Image → XTG/XTH
decode.go            Decode XTG/XTH → image.Image
xtc.go               XTC/XTCH container builder and encoder
transform.go         Resize, rotate, white page utilities
cbz.go               CBZ archive reader
SPEC.md              Full binary format specification

License

MIT — see LICENSE.

Documentation

Overview

Package xtx implements encoding and decoding of Xteink XTG/XTH image formats and XTC/XTCH comic container formats for ESP32 e-paper displays.

Image types Monochrome (1-bit) and Grayscale (2-bit, 4-level) implement the image.Image interface and can be used with the standard library's image processing tools.

The Encode function writes any image.Image to XTG or XTH format:

// Encode as monochrome (XTG) with dithering
xtx.Encode(w, img, &xtx.Options{Dither: true})

// Encode as grayscale (XTH)
xtx.Encode(w, img, &xtx.Options{Format: xtx.FormatGrayscale})

The Decode function auto-detects the format from magic bytes:

img, err := xtx.Decode(r)

XTG and XTH formats are also registered with image.RegisterFormat, so importing this package enables image.Decode to handle them:

import _ "github.com/phrozen/xtx"
img, format, err := image.Decode(r)

The XTC type provides a builder for comic containers:

comic := xtx.NewXTC()
comic.SetMetadata(xtx.Metadata{Title: "My Manga"})
comic.AddPage(page1)
comic.Encode(w)

Index

Constants

View Source
const (
	MagicXTG  uint32 = 0x00475458 // "XTG\0"
	MagicXTH  uint32 = 0x00485458 // "XTH\0"
	MagicXTC  uint32 = 0x00435458 // "XTC\0"
	MagicXTCH uint32 = 0x48435458 // "XTCH"
)

File format magic bytes (little-endian uint32).

View Source
const (
	HeaderSize     = 22  // Image header (XTG/XTH)
	XTCHeaderSize  = 56  // XTC/XTCH container header
	MetadataSize   = 256 // XTC metadata block
	ChapterSize    = 96  // XTC chapter entry
	IndexEntrySize = 16  // XTC page index entry
)

Structure sizes in bytes.

View Source
const (
	MetaTitleSize     = 128
	MetaAuthorSize    = 64
	MetaPublisherSize = 32
	MetaLanguageSize  = 16
)

Field sizes for metadata strings.

Variables

View Source
var (
	MonoBlack = Mono{V: false}
	MonoWhite = Mono{V: true}
)

Predefined monochrome colors.

View Source
var (
	Gray4White     = Gray4{V: 0}
	Gray4DarkGrey  = Gray4{V: 1}
	Gray4LightGrey = Gray4{V: 2}
	Gray4Black     = Gray4{V: 3}
)

Predefined Gray4 colors.

View Source
var (
	DitherFloydSteinberg = DitherAlgorithm{
		Name:    "floyd-steinberg",
		Divisor: 16,
		Coeffs: []ErrorCoeff{
			{1, 0, 7},
			{-1, 1, 3}, {0, 1, 5}, {1, 1, 1},
		},
	}

	DitherAtkinson = DitherAlgorithm{
		Name:    "atkinson",
		Divisor: 8,
		Coeffs: []ErrorCoeff{
			{1, 0, 1}, {2, 0, 1},
			{-1, 1, 1}, {0, 1, 1}, {1, 1, 1},
			{0, 2, 1},
		},
	}

	DitherSierra = DitherAlgorithm{
		Name:    "sierra",
		Divisor: 32,
		Coeffs: []ErrorCoeff{
			{1, 0, 5}, {2, 0, 3},
			{-2, 1, 2}, {-1, 1, 4}, {0, 1, 5}, {1, 1, 4}, {2, 1, 2},
			{-1, 2, 2}, {0, 2, 3}, {1, 2, 2},
		},
	}

	DitherSierraLite = DitherAlgorithm{
		Name:    "sierra-lite",
		Divisor: 4,
		Coeffs: []ErrorCoeff{
			{1, 0, 2},
			{-1, 1, 1}, {0, 1, 1},
		},
	}

	DitherStucki = DitherAlgorithm{
		Name:    "stucki",
		Divisor: 42,
		Coeffs: []ErrorCoeff{
			{1, 0, 8}, {2, 0, 4},
			{-2, 1, 2}, {-1, 1, 4}, {0, 1, 8}, {1, 1, 4}, {2, 1, 2},
			{-2, 2, 1}, {-1, 2, 2}, {0, 2, 4}, {1, 2, 2}, {2, 2, 1},
		},
	}
)

Standard dithering algorithms.

View Source
var (
	ErrInvalidMagic           = errors.New("xtx: invalid magic bytes")
	ErrDimensionOverflow      = errors.New("xtx: image dimensions exceed uint16 range")
	ErrDimensionZero          = errors.New("xtx: image dimensions must be non-zero")
	ErrDataSizeMismatch       = errors.New("xtx: data size does not match expected")
	ErrUnsupportedCompression = errors.New("xtx: compression is not supported")
)

Sentinel errors.

View Source
var DitherNone draw.Drawer = draw.Src

DitherNone is a draw.Drawer that performs no dithering (nearest-color mapping).

View Source
var Gray4Model = color.ModelFunc(gray4Model)

Gray4Model converts any color.Color to Gray4 using nearest-level quantization. The thresholds account for the non-linear Xteink LUT mapping.

View Source
var MonoModel = color.ModelFunc(monoModel)

MonoModel converts any color.Color to Mono using luminance thresholding. Colors with luminance >= 128 become white; below 128 become black.

Functions

func Decode

func Decode(r io.Reader) (image.Image, error)

Decode reads an XTG or XTH image from r, auto-detecting the format from the magic bytes in the header.

func DecodeConfig

func DecodeConfig(r io.Reader) (image.Config, error)

DecodeConfig returns the image dimensions and color model without reading the pixel data.

func Encode

func Encode(w io.Writer, img image.Image, opts *Options) error

Encode writes img to w in XTG or XTH format.

The target format is determined by:

  1. If img is *Monochrome, encodes as XTG (skips conversion).
  2. If img is *Grayscale, encodes as XTH (skips conversion).
  3. Otherwise, uses opts.Format (default FormatMonochrome).

When opts.Ditherer is provided and the source requires conversion, it is used to dither the image into the target color space.

A nil opts is equivalent to &Options{Format: FormatMonochrome}.

func NewWhitePage

func NewWhitePage(w, h int) *image.RGBA

NewWhitePage creates a new RGBA image of the given dimensions filled with white.

func ReadCBZ

func ReadCBZ(path string) ([]image.Image, error)

ReadCBZ opens a CBZ (ZIP) file and returns all images sorted alphabetically by filename. It skips directories, hidden files, and macOS metadata (__MACOSX).

func Resize

func Resize(img image.Image, width, height int) *image.RGBA

Resize scales img to the given width and height using bilinear interpolation. For aspect-ratio-preserving variants, use ResizeToWidth or ResizeToHeight.

func ResizeToHeight

func ResizeToHeight(img image.Image, targetHeight int) *image.RGBA

ResizeToHeight scales img so its height equals targetHeight, maintaining the original aspect ratio. Uses bilinear interpolation.

func ResizeToWidth

func ResizeToWidth(img image.Image, targetWidth int) *image.RGBA

ResizeToWidth scales img so its width equals targetWidth, maintaining the original aspect ratio. Uses bilinear interpolation.

func RotateCCW

func RotateCCW(img image.Image) *image.RGBA

RotateCCW rotates an image 90° counter-clockwise. A W×H image becomes H×W.

func RotateCW

func RotateCW(img image.Image) *image.RGBA

RotateCW rotates an image 90° clockwise. A W×H image becomes H×W.

Types

type Chapter

type Chapter struct {
	Name      string
	StartPage uint16 // 0-based, inclusive
	EndPage   uint16 // 0-based, inclusive
}

Chapter represents a named range of pages within an XTC/XTCH container.

type Dither added in v0.2.0

type Dither struct {
	Algo DitherAlgorithm
}

Dither is a draw.Drawer that applies an error diffusion algorithm.

func (Dither) Draw added in v0.2.0

func (d Dither) Draw(dst draw.Image, r image.Rectangle, src image.Image, sp image.Point)

Draw implements the draw.Drawer interface using the selected algorithm.

type DitherAlgorithm added in v0.2.0

type DitherAlgorithm struct {
	Name    string
	Divisor int
	Coeffs  []ErrorCoeff
}

DitherAlgorithm defines an error diffusion matrix.

func AllDitherAlgorithms added in v0.2.0

func AllDitherAlgorithms() []DitherAlgorithm

AllDitherAlgorithms returns a list of supported error diffusion algorithms.

func ParseDitherAlgorithm added in v0.2.0

func ParseDitherAlgorithm(name string) (DitherAlgorithm, bool)

ParseDitherAlgorithm returns the algorithm matching the given name, or DitherFloydSteinberg if not found. Name matching is case-insensitive.

type ErrorCoeff added in v0.2.0

type ErrorCoeff struct {
	Dx, Dy int
	Weight int
}

ErrorCoeff represents an error diffusion distribution step.

type Format

type Format uint8

Format specifies the target image format for encoding.

const (
	// FormatMonochrome encodes as XTG (1-bit per pixel).
	FormatMonochrome Format = iota
	// FormatGrayscale encodes as XTH (2-bit per pixel, 4-level).
	FormatGrayscale
)

type Gray4

type Gray4 struct {
	V uint8 // 0–3
}

Gray4 represents a 2-bit grayscale color with 4 levels. Values 0–3 map to the Xteink e-paper LUT:

0 = White
1 = Dark Grey  (non-linear: swapped with level 2)
2 = Light Grey (non-linear: swapped with level 1)
3 = Black

func (Gray4) RGBA

func (c Gray4) RGBA() (r, g, b, a uint32)

RGBA implements the color.Color interface. Maps Gray4 levels to 8-bit grayscale, accounting for the non-linear LUT.

type Grayscale

type Grayscale struct {
	// Pix holds both bit planes concatenated: [plane1][plane2].
	// Each plane uses vertical scan order: columns right-to-left,
	// 8 vertical pixels packed per byte (MSB = topmost).
	Pix []uint8
	// Rect is the image bounds.
	Rect image.Rectangle
	// PlaneSize is the size of one bit plane in bytes.
	PlaneSize int
	// ColBytes is the number of bytes per column: (height + 7) / 8.
	ColBytes int
}

Grayscale is a 2-bit per pixel, 4-level grayscale image corresponding to the XTH format. It implements image.Image and stores pixels in dual bit-plane format with vertical scan order (column-major, right-to-left) matching the Xteink e-paper display refresh pattern.

The pixel value mapping follows the non-linear Xteink LUT:

0 = White, 1 = Dark Grey, 2 = Light Grey, 3 = Black

func NewGrayscale

func NewGrayscale(r image.Rectangle) *Grayscale

NewGrayscale creates a new Grayscale image with the given bounds.

func (*Grayscale) At

func (img *Grayscale) At(x, y int) color.Color

At returns the color of the pixel at (x, y).

func (*Grayscale) Bounds

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

Bounds returns the image bounds.

func (*Grayscale) ColorModel

func (img *Grayscale) ColorModel() color.Model

ColorModel returns Gray4Model.

func (*Grayscale) DataSize

func (img *Grayscale) DataSize() uint32

DataSize returns the total size of the pixel data in bytes (both planes), matching the XTH spec: ((width * height + 7) / 8) * 2.

func (*Grayscale) Gray4At

func (img *Grayscale) Gray4At(x, y int) Gray4

Gray4At returns the Gray4 color at (x, y) without bounds checking.

func (*Grayscale) Set

func (img *Grayscale) Set(x, y int, c color.Color)

Set sets the pixel at (x, y) to color c, converting through Gray4Model.

func (*Grayscale) SetGray4

func (img *Grayscale) SetGray4(x, y int, c Gray4)

SetGray4 sets the pixel at (x, y) to the Gray4 value without color conversion.

type Header struct {
	Mark        uint32 // File identifier (MagicXTG or MagicXTH)
	Width       uint16 // Image width in pixels
	Height      uint16 // Image height in pixels
	ColorMode   uint8  // Color mode (0 = monochrome)
	Compression uint8  // Compression (0 = uncompressed)
	DataSize    uint32 // Image data size in bytes
	MD5         uint64 // Truncated MD5 checksum (first 8 bytes); 0 = unused
}

Header represents the 22-byte image header shared by XTG and XTH formats.

func (*Header) ReadFrom

func (h *Header) ReadFrom(r io.Reader) (int64, error)

ReadFrom reads the header in little-endian binary format from r.

func (*Header) Validate

func (h *Header) Validate() error

Validate checks the header for consistency and returns an error if invalid.

func (*Header) WriteTo

func (h *Header) WriteTo(w io.Writer) (int64, error)

WriteTo writes the header in little-endian binary format to w.

type Metadata

type Metadata struct {
	Title     string
	Author    string
	Publisher string
	Language  string

	CreateTime uint32 // Unix timestamp
	CoverPage  uint16 // 0-based page index; 0xFFFF = none
}

Metadata holds optional metadata for an XTC/XTCH container.

type Mono

type Mono struct {
	V bool // true = white, false = black
}

Mono represents a 1-bit monochrome color (black or white).

func (Mono) RGBA

func (c Mono) RGBA() (r, g, b, a uint32)

RGBA implements the color.Color interface.

type Monochrome

type Monochrome struct {
	// Pix holds the packed bitmap data. Bit 7 of each byte is the leftmost pixel.
	// A set bit (1) represents white; a cleared bit (0) represents black.
	Pix []uint8
	// Stride is the number of bytes per row: (width + 7) / 8.
	Stride int
	// Rect is the image bounds.
	Rect image.Rectangle
}

Monochrome is a 1-bit per pixel image (black and white) corresponding to the XTG format. It implements image.Image and stores pixels in packed bitmap format: row-major, MSB-first, 8 pixels per byte.

func NewMonochrome

func NewMonochrome(r image.Rectangle) *Monochrome

NewMonochrome creates a new Monochrome image with the given bounds.

func (*Monochrome) At

func (img *Monochrome) At(x, y int) color.Color

At returns the color of the pixel at (x, y).

func (*Monochrome) Bounds

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

Bounds returns the image bounds.

func (*Monochrome) ColorModel

func (img *Monochrome) ColorModel() color.Model

ColorModel returns MonoModel.

func (*Monochrome) DataSize

func (img *Monochrome) DataSize() uint32

DataSize returns the size of the pixel data in bytes, matching the XTG spec: ((width + 7) / 8) * height.

func (*Monochrome) MonoAt

func (img *Monochrome) MonoAt(x, y int) Mono

MonoAt returns the Mono color at (x, y) without bounds checking.

func (*Monochrome) Set

func (img *Monochrome) Set(x, y int, c color.Color)

Set sets the pixel at (x, y) to color c, converting through MonoModel.

func (*Monochrome) SetMono

func (img *Monochrome) SetMono(x, y int, c Mono)

SetMono sets the pixel at (x, y) to the Mono value without color conversion.

type Options

type Options struct {
	// Format selects XTG (FormatMonochrome) or XTH (FormatGrayscale).
	// Ignored when the source image is already *Monochrome or *Grayscale.
	Format Format

	// Ditherer specifies the algorithm to use for error-diffusion dithering
	// during encoding (when the source image requires conversion).
	// If nil, defaults to DitherNone (no dithering, simple threshold/quantization).
	Ditherer draw.Drawer
}

Options controls encoding behavior. A nil *Options is valid and uses defaults (FormatMonochrome, no dithering).

type ReadDirection

type ReadDirection uint8

ReadDirection specifies the reading direction for comic containers.

const (
	LeftToRight ReadDirection = 0 // Normal (left to right)
	RightToLeft ReadDirection = 1 // Japanese manga (right to left)
	TopToBottom ReadDirection = 2 // Vertical (top to bottom)
)

type XTC

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

XTC represents an XTC or XTCH comic container. Use NewXTC to create one, add pages and metadata, then call XTC.Encode to write it out.

func DecodeXTC

func DecodeXTC(r io.ReadSeeker) (*XTC, error)

DecodeXTC reads an XTC/XTCH container from r.

func NewXTC

func NewXTC(xtch bool) *XTC

NewXTC creates a new empty container. If xtch is true, the container uses the XTCH variant; otherwise standard XTC.

func (*XTC) AddChapter

func (c *XTC) AddChapter(ch Chapter)

AddChapter appends a chapter to the container.

func (*XTC) AddPage

func (c *XTC) AddPage(img image.Image) error

AddPage encodes img as XTG and appends it as a page to the container.

func (*XTC) AddPageXTH

func (c *XTC) AddPageXTH(img image.Image) error

AddPageXTH encodes img as XTH and appends it as a page to the container.

func (*XTC) AddThumbnail

func (c *XTC) AddThumbnail(img *Monochrome) error

AddThumbnail appends a pre-built *Monochrome image as a thumbnail. Thumbnails are optional and stored in the thumbnail area of the container.

func (*XTC) Chapters

func (c *XTC) Chapters() []Chapter

Chapters returns the chapter list.

func (*XTC) Direction

func (c *XTC) Direction() ReadDirection

Direction returns the reading direction.

func (*XTC) Encode

func (c *XTC) Encode(w io.Writer) error

Encode writes the complete XTC/XTCH container to w.

func (*XTC) GetMetadata

func (c *XTC) GetMetadata() *Metadata

GetMetadata returns the container metadata, or nil if not set.

func (*XTC) Page

func (c *XTC) Page(i int) (image.Image, error)

Page decodes and returns the i-th page as an image.Image. The returned image is either *Monochrome or *Grayscale depending on the page's format.

func (*XTC) PageCount

func (c *XTC) PageCount() int

PageCount returns the number of pages in the container.

func (*XTC) SetDirection

func (c *XTC) SetDirection(d ReadDirection)

SetDirection sets the reading direction of the comic.

func (*XTC) SetMetadata

func (c *XTC) SetMetadata(m Metadata)

SetMetadata sets the container's metadata block.

Directories

Path Synopsis
cmd
xtx command
Command xtx is a utility for working with Xteink XTG/XTH image formats and XTC/XTCH comic containers.
Command xtx is a utility for working with Xteink XTG/XTH image formats and XTC/XTCH comic containers.

Jump to

Keyboard shortcuts

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