Documentation
¶
Overview ¶
Package fits implements a pure-Go reader/writer for the FITS (Flexible Image Transport System) file format as defined by the FITS Standard v4.0.
This file defines the public error sentinels and typed errors.
Index ¶
- Variables
- func CanConvert[T Numeric](h *ImageHDU) bool
- func Decode(r io.Reader) (image.Image, error)
- func DecodeConfig(r io.Reader) (image.Config, error)
- func EditFile(path string, fn func(in *File, out *Writer) error) error
- func EditFileContext(ctx context.Context, path string, fn func(in *File, out *Writer) error) error
- func OverwritePixels[T Numeric](h *ImageHDU, data []T) error
- func ReadASCIIColumn[T ColumnValue](t *ASCIITableHDU, col int) ([]T, error)
- func ReadColumn[T ColumnValue](t *BinaryTableHDU, col int) ([]T, error)
- func ReadFloat32(h HDU) ([]float32, error)
- func ReadFrame(path string) (pix []float32, width, height int, err error)
- func ReadFrameRGB(path string) (r, g, b []float32, width, height int, err error)
- func ReadPixels[T Numeric](h *ImageHDU) ([]T, error)
- func ReadPixelsCompressed[T Numeric](h *CompressedImageHDU) ([]T, error)
- func ReadPixelsCompressedContext[T Numeric](ctx context.Context, h *CompressedImageHDU) ([]T, error)
- func ReadPixelsContext[T Numeric](ctx context.Context, h *ImageHDU) ([]T, error)
- func ReadPixelsMasked[T Numeric](h *ImageHDU) ([]T, []bool, error)
- func ReadSubset[T Numeric](h *ImageHDU, lower, upper, stride []int64) ([]T, error)
- func ReadVectorColumn[T Numeric](t *BinaryTableHDU, col int) ([]T, error)
- func VerifyChecksum(h HDU) error
- func WriteChecksum(h HDU) (dataSum, checkSum uint32, err error)
- func WriteMono(path string, pix []float32, width, height int) error
- func WriteRGB(path string, r, g, b []float32, width, height int) error
- type ASCIITableHDU
- func (h *ASCIITableHDU) ColumnByName(name string) (Column, bool)
- func (h *ASCIITableHDU) Columns() ([]Column, error)
- func (*ASCIITableHDU) Compressed() bool
- func (*ASCIITableHDU) CompressionType() string
- func (h *ASCIITableHDU) Header() *header.Header
- func (h *ASCIITableHDU) Index() int
- func (h *ASCIITableHDU) NumRows() int64
- func (h *ASCIITableHDU) Type() HDUType
- type BinaryTableHDU
- func (h *BinaryTableHDU) ColumnByName(name string) (Column, bool)
- func (h *BinaryTableHDU) ColumnIndex(name string) int
- func (h *BinaryTableHDU) Columns() ([]Column, error)
- func (*BinaryTableHDU) Compressed() bool
- func (*BinaryTableHDU) CompressionType() string
- func (h *BinaryTableHDU) Header() *header.Header
- func (h *BinaryTableHDU) Index() int
- func (h *BinaryTableHDU) NumRows() int64
- func (h *BinaryTableHDU) RowBytes(row int64) ([]byte, error)
- func (h *BinaryTableHDU) Type() HDUType
- type Column
- type ColumnData
- type ColumnType
- type ColumnValue
- type CompressFloatOptions
- type CompressOptions
- type CompressedImageHDU
- func (h *CompressedImageHDU) BITPIX() int
- func (h *CompressedImageHDU) BSCALE() float64
- func (h *CompressedImageHDU) BZERO() float64
- func (h *CompressedImageHDU) Compressed() bool
- func (h *CompressedImageHDU) CompressionType() string
- func (h *CompressedImageHDU) Header() *header.Header
- func (h *CompressedImageHDU) Index() int
- func (h *CompressedImageHDU) NAXIS() int
- func (h *CompressedImageHDU) Shape() []int64
- func (h *CompressedImageHDU) Type() HDUType
- type ErrMissingRequiredKeyword
- type ErrTruncatedData
- type ErrUnterminatedHeader
- type File
- func Create(name string) (*File, error)
- func CreateContext(ctx context.Context, name string) (*File, error)
- func CreateWriter(rws io.ReadWriteSeeker) (*File, error)
- func Open(name string) (*File, error)
- func OpenContext(ctx context.Context, name string) (*File, error)
- func OpenForEdit(name string) (*File, error)
- func OpenForEditContext(ctx context.Context, name string) (*File, error)
- func OpenReadAll(r io.Reader) (*File, error)
- func OpenReader(r io.ReadSeeker) (*File, error)
- func (f *File) Close() error
- func (f *File) CloseAndFlush() error
- func (f *File) CopyTo(w io.Writer) error
- func (f *File) Flush() error
- func (f *File) HDU(i int) (HDU, error)
- func (f *File) HDUByName(name string) (HDU, error)
- func (f *File) Mode() Mode
- func (f *File) Name() string
- func (f *File) NumHDU() int
- func (f *File) Primary() (*ImageHDU, error)
- type FloatColor
- type FloatGray
- type HDU
- type HDUType
- type ImageHDU
- func (h *ImageHDU) AsImage() (image.Image, error)
- func (h *ImageHDU) BITPIX() int
- func (h *ImageHDU) BSCALE() float64
- func (h *ImageHDU) BZERO() float64
- func (*ImageHDU) Compressed() bool
- func (*ImageHDU) CompressionType() string
- func (h *ImageHDU) Header() *header.Header
- func (h *ImageHDU) Index() int
- func (h *ImageHDU) NAXIS() int
- func (h *ImageHDU) Shape() []int64
- func (h *ImageHDU) Type() HDUType
- type KeyNotFoundError
- type Mode
- type Numeric
- type TypeMismatchError
- type VarColumn
- type WriteTarget
- type Writer
Constants ¶
This section is empty.
Variables ¶
var ( // ErrEmptyFile is returned when an input stream is zero bytes. ErrEmptyFile = errors.New("fits: empty file") // ErrNotFITS is returned when the first block does not begin with // "SIMPLE =". ErrNotFITS = errors.New("fits: not a FITS file") // ErrKeyNotFound is returned by typed keyword getters when the key is // absent from a header. ErrKeyNotFound = errors.New("fits: key not found") // ErrNotImageHDU is returned when an image operation is attempted on a // non-image HDU. ErrNotImageHDU = errors.New("fits: not an image HDU") // ErrNotImageCompatible is returned by AsImage() for HDUs that cannot be // losslessly represented as an image.Image (multi-dim, complex BITPIX, // etc.). ErrNotImageCompatible = errors.New("fits: not image.Image-compatible") // ErrTypeMismatch is returned when a generic read is asked for a target // type that cannot losslessly represent the on-disk type. ErrTypeMismatch = errors.New("fits: type mismatch") // ErrReadOnly is returned when a write or edit operation is attempted on // a read-only *File. ErrReadOnly = errors.New("fits: file is read-only") // ErrShapeMismatch is returned when OverwritePixels or a similar // shape-preserving call receives data of the wrong length or dimension. ErrShapeMismatch = errors.New("fits: shape mismatch") // ErrRandomGroups is returned for random-groups (§6) HDUs, which // this library does not support by design — random groups are a // legacy radio-interferometry format superseded by binary tables. ErrRandomGroups = errors.New("fits: random-groups HDUs not supported") )
Sentinel errors — match via errors.Is.
var FloatGrayModel color.Model = floatGrayModel{}
FloatGrayModel is the color model for FloatGray images.
Functions ¶
func CanConvert ¶
CanConvert reports whether ReadPixels[T] on h would succeed without returning ErrTypeMismatch. It does not touch the file content.
func Decode ¶
Decode implements image.Decode for FITS files. Returns ErrNotImageCompatible if the primary HDU (or first HDU) is not losslessly representable as an image.Image.
func DecodeConfig ¶
DecodeConfig implements image.DecodeConfig for FITS files.
func EditFile ¶
EditFile provides a streaming-rebuild surface for structural changes (image resize, row/column insert/delete, HDU insert-in-middle, HDU delete, VLA heap reorganization).
It opens src read-only, creates a temp file in the same directory, passes the caller an (in, writer) pair, fsyncs on success, and atomically renames the temp file over src. On any error (callback returns err or panic) the temp file is removed and src is untouched.
Crash-safe by construction (temp + rename on same filesystem).
See plan decision 5.8.
func EditFileContext ¶
EditFileContext is EditFile with an explicit context.
func OverwritePixels ¶
OverwritePixels writes new pixel values over the existing data allocation of an ImageHDU. It requires ModeEdit; ModeRead returns ErrReadOnly.
The call fails with:
- ErrReadOnly if the parent file is not in ModeEdit.
- ErrShapeMismatch if len(data) != NAXIS1 × NAXIS2 × ... for the HDU.
- A wrapped ErrTypeMismatch if T does not correspond exactly to the HDU's BITPIX. Writing requires an exact-width match — we do not round or clip.
OverwritePixels does NOT resize the HDU; resize operations must go through EditFile.
func ReadASCIIColumn ¶
func ReadASCIIColumn[T ColumnValue](t *ASCIITableHDU, col int) ([]T, error)
ReadASCIIColumn reads a scalar column from an ASCII table. For string columns (TFORM 'A') T must be ~string; for integer and float columns T must be a Numeric type.
func ReadColumn ¶
func ReadColumn[T ColumnValue](t *BinaryTableHDU, col int) ([]T, error)
ReadColumn reads a scalar column (Repeat==1) across all rows and returns one value per row as a []T. For Char columns (TFORM "A") use T=string. For Logical columns use T=bool. For numeric columns use any Numeric T that can hold the column type (same rules as CanConvert on images).
TSCAL/TZERO are applied to numeric columns (BSCALE/BZERO analogue).
func ReadFloat32 ¶ added in v1.2.0
ReadFloat32 reads the image pixels as float32 normalized to [0, 1]. Accepts both *ImageHDU and *CompressedImageHDU — callers do not need to type-switch.
For integer BITPIX (8, 16, 32, 64), the normalization maps the full physical range (after BSCALE/BZERO) into [0, 1]:
normalized = (physical - physMin) / (physMax - physMin)
The raw range per BITPIX:
BITPIX=8: [0, 255] → phys via BSCALE/BZERO BITPIX=16: [-32768, 32767] → commonly [0, 65535] with BZERO=32768 BITPIX=32: [-2^31, 2^31-1] → phys via BSCALE/BZERO BITPIX=64: [-2^63, 2^63-1] → phys via BSCALE/BZERO
For float BITPIX (-32, -64), values are returned as-is after BSCALE/BZERO application — assumed already in [0, 1] per the Siril convention used by astrophotography processing pipelines.
This is the standard entry point for processing pipelines (stacking, debayering, calibration, background extraction, etc.) that operate on normalized float32 data.
func ReadFrame ¶ added in v1.2.1
ReadFrame reads a 2D mono image from a FITS file path and returns the pixels normalized to [0, 1] via ReadFloat32.
Returned dims follow the FITS convention: width == NAXIS1 (columns, the fastest-varying axis), height == NAXIS2 (rows). Pixels are row-major: index pixel (x, y) as pix[y*width + x].
Accepts:
- NAXIS == 2
- NAXIS == 3 with NAXIS3 == 1 (degenerate single-plane cube)
The image is taken from the primary HDU if it has image data, otherwise from HDU 1 (the standard tile-compressed layout). Tile-compressed images are supported transparently. Integer BITPIX is normalized to [0, 1]; float BITPIX passes through unchanged. NaN and BLANK pixels are not masked — callers who need that should use ReadPixelsMasked directly.
Returns an error for NAXIS != 2 (or NAXIS == 3 with NAXIS3 != 1), with a hint pointing at ReadFrameRGB for 3-plane color cubes.
func ReadFrameRGB ¶ added in v1.2.1
ReadFrameRGB reads a 3D planar RGB image (NAXIS=3, NAXIS3=3) from a FITS file path and returns the three color planes normalized to [0, 1] via ReadFloat32.
Returned dims follow the FITS convention: width == NAXIS1 (columns, the fastest-varying axis), height == NAXIS2 (rows). Each plane is row-major: index pixel (x, y) as r[y*width + x] (and likewise for g, b).
Layout on disk is R plane, then G plane, then B plane (NAXIS1 fastest, NAXIS3=3 slowest) — the standard FITS/Siril/astropy convention.
HDU selection, normalization, and masking semantics match ReadFrame. Returns an error for NAXIS != 3 or NAXIS3 != 3.
func ReadPixels ¶
ReadPixels reads every pixel of h into a single flat slice of type T, applying BSCALE/BZERO. Returns an error (wrapping ErrTypeMismatch) if the requested type cannot losslessly hold the file's data. Row-major order matches the FITS on-disk layout: the first axis varies fastest.
func ReadPixelsCompressed ¶
func ReadPixelsCompressed[T Numeric](h *CompressedImageHDU) ([]T, error)
ReadPixelsCompressed reads and decompresses every tile of h, returning a flat slice of pixels in row-major order matching the logical image shape (Shape()). BSCALE/BZERO from the Z-prefixed keywords are applied as with a regular ImageHDU.
This is the compressed counterpart to ReadPixels[T] for regular *ImageHDU. Users who open a file via fits.Open do not need to call this directly — they can continue to use the uniform ReadPixels[T] form and the library dispatches to the compressed path automatically.
func ReadPixelsCompressedContext ¶
func ReadPixelsCompressedContext[T Numeric](ctx context.Context, h *CompressedImageHDU) ([]T, error)
ReadPixelsCompressedContext is ReadPixelsCompressed with an explicit context.
func ReadPixelsContext ¶
ReadPixelsContext is ReadPixels with an explicit context. The context is consulted before the read and can be used to abort long reads.
func ReadPixelsMasked ¶
ReadPixelsMasked is like ReadPixels but also returns a per-pixel validity mask. A pixel is invalid (mask[i] == false) if the underlying raw value equals BLANK (integer BITPIX only) or is IEEE NaN (float BITPIX). BSCALE/BZERO are applied to valid pixels only; invalid pixels are left at the zero value of T.
func ReadSubset ¶
ReadSubset reads an n-dimensional hyperslab from h.
lower, upper, and stride each must have length equal to h.NAXIS(). The slab selected is the half-open interval [lower[i], upper[i]) along each axis, stepping by stride[i] (stride==1 means contiguous). Coordinates are 0-based and match the order of h.Shape() (axis 0 varies fastest on disk).
The output slice has length Π ceil((upper[i]-lower[i]) / stride[i]) and is laid out row-major matching the same axis order as Shape() — i.e. the first axis is the fastest-varying dimension, as on disk.
Unlike ReadPixels, ReadSubset does not issue one big read. It computes a per-row byte range along axis 0 and reads each row independently, seeking between them. For stride[0]==1 and contiguous axis-0 runs this is near-optimal; for large strided axes it issues more seeks than an all-at-once read would.
BSCALE/BZERO are applied as in ReadPixels.
func ReadVectorColumn ¶
func ReadVectorColumn[T Numeric](t *BinaryTableHDU, col int) ([]T, error)
ReadVectorColumn reads a fixed-width vector column (Repeat>1) and returns a flat slice of length nrows*repeat in row-major order.
func VerifyChecksum ¶
VerifyChecksum verifies the CHECKSUM and DATASUM keywords on an HDU if they are present. It returns nil if both verify (or if they are absent). If one or both are present but wrong, it returns an error identifying which failed.
Algorithm (FITS Appendix J):
- DATASUM is the 32-bit 1's-complement checksum of the data section only, encoded as an ASCII integer.
- CHECKSUM is the 16-char ASCII-encoded 1's-complement checksum such that the combined (header + data) checksum sums to all-ones.
func WriteChecksum ¶
WriteChecksum updates (or creates) the CHECKSUM and DATASUM cards on an HDU in edit mode. It must be called BEFORE Flush so that the re-serialized header contains the correct cards. The computed values are returned for inspection.
Checksums are not computed automatically on Close — callers must opt in via WriteChecksum per HDU. This keeps the strict-fidelity promise: users get byte-exact round-trip unless they explicitly ask for mutation.
func WriteMono ¶ added in v1.2.1
WriteMono writes a 2D mono float32 image to a FITS file at path.
The output is a BITPIX=-32 primary HDU with shape [width, height] (NAXIS1=width, NAXIS2=height). Input pixels are row-major — pixel (x, y) at pix[y*width + x] — matching the layout ReadFrame returns. Values are written verbatim (no scaling, no clamping). Any existing file at path is truncated.
func WriteRGB ¶ added in v1.2.1
WriteRGB writes a 3D planar RGB float32 image to a FITS file at path.
The output is a BITPIX=-32 primary HDU with shape [width, height, 3] (NAXIS1=width, NAXIS2=height, NAXIS3=3). The three planes are concatenated in R, G, B order (NAXIS1 fastest, NAXIS3=3 slowest) — the standard FITS/Siril/astropy convention. Each input plane is row-major — pixel (x, y) at r[y*width + x] (and likewise for g, b) — matching the layout ReadFrameRGB returns. Values are written verbatim (no scaling, no clamping). Any existing file at path is truncated.
Types ¶
type ASCIITableHDU ¶
type ASCIITableHDU struct {
// contains filtered or unexported fields
}
ASCIITableHDU represents an ASCII TABLE extension (§7.2).
func (*ASCIITableHDU) ColumnByName ¶
func (h *ASCIITableHDU) ColumnByName(name string) (Column, bool)
ColumnByName returns the column whose TTYPE matches name.
func (*ASCIITableHDU) Columns ¶
func (h *ASCIITableHDU) Columns() ([]Column, error)
Columns returns the column metadata for the ASCII table.
func (*ASCIITableHDU) Compressed ¶
func (*ASCIITableHDU) Compressed() bool
Compressed returns false — ASCII tables are never compressed.
func (*ASCIITableHDU) CompressionType ¶
func (*ASCIITableHDU) CompressionType() string
CompressionType returns the empty string for ASCII tables.
func (*ASCIITableHDU) Header ¶
func (h *ASCIITableHDU) Header() *header.Header
Header returns the parsed header (lazy).
func (*ASCIITableHDU) Index ¶
func (h *ASCIITableHDU) Index() int
Index returns the 0-based HDU index.
func (*ASCIITableHDU) NumRows ¶
func (h *ASCIITableHDU) NumRows() int64
NumRows returns the number of rows from NAXIS2.
type BinaryTableHDU ¶
type BinaryTableHDU struct {
// contains filtered or unexported fields
}
BinaryTableHDU represents a BINTABLE extension (§7.3).
func AppendBinaryTable ¶
func AppendBinaryTable(f *File, hdr *header.Header, cols []ColumnData) (*BinaryTableHDU, error)
AppendBinaryTable appends a new BINTABLE HDU to the file. All columns must have the same row count. The TFORM code is inferred from the DataXxx slice that is populated (or from an explicit .TForm if set).
func (*BinaryTableHDU) ColumnByName ¶
func (h *BinaryTableHDU) ColumnByName(name string) (Column, bool)
ColumnByName returns the column whose TTYPE matches name, or ok=false. The comparison is case-sensitive.
func (*BinaryTableHDU) ColumnIndex ¶
func (h *BinaryTableHDU) ColumnIndex(name string) int
ColumnIndex returns the 1-based column index for name, or 0 if absent.
func (*BinaryTableHDU) Columns ¶
func (h *BinaryTableHDU) Columns() ([]Column, error)
Columns returns the ordered column metadata for the binary table. The result is parsed lazily on first call and cached.
func (*BinaryTableHDU) Compressed ¶
func (*BinaryTableHDU) Compressed() bool
Compressed returns false — plain binary tables are not compressed. (CompressedImageHDU is a separate type backed by a binary table with ZIMAGE=T, not a BinaryTableHDU.)
func (*BinaryTableHDU) CompressionType ¶
func (*BinaryTableHDU) CompressionType() string
CompressionType returns the empty string for plain binary tables.
func (*BinaryTableHDU) Header ¶
func (h *BinaryTableHDU) Header() *header.Header
Header returns the parsed header (lazy).
func (*BinaryTableHDU) Index ¶
func (h *BinaryTableHDU) Index() int
Index returns the 0-based HDU index.
func (*BinaryTableHDU) NumRows ¶
func (h *BinaryTableHDU) NumRows() int64
NumRows returns the number of rows from NAXIS2.
type Column ¶
type Column struct {
Index int // 1-based per FITS convention
Name string // TTYPEn
Unit string // TUNITn
TForm string // raw TFORMn
Repeat int64
Type ColumnType
Scale float64 // TSCALn, default 1
Zero float64 // TZEROn, default 0
Null any // TNULLn if set
Display string // TDISPn
Dim []int64 // TDIMn if set
// contains filtered or unexported fields
}
Column describes a single table column.
type ColumnData ¶
type ColumnData struct {
Name string
Unit string
Display string
TForm string // optional override; if empty, inferred from Data*
Dim []int64
// One of the following (mutually exclusive). Fixed-width columns take a
// flat slice; variable-length array (VLA) columns take a slice of
// slices, one row per outer element.
DataUint8 []uint8
DataInt16 []int16
DataInt32 []int32
DataInt64 []int64
DataFloat32 []float32
DataFloat64 []float64
DataString []string // for Char columns; all entries must be the same length
DataBool []bool
// Variable-length arrays (§7.3.5). Each outer element is one row; the
// inner slice length may differ per row. The writer emits a 1P<type>
// descriptor column and appends payloads to the heap area.
DataVarUint8 [][]uint8
DataVarInt16 [][]int16
DataVarInt32 [][]int32
DataVarInt64 [][]int64
DataVarFloat32 [][]float32
DataVarFloat64 [][]float64
}
ColumnData describes a single column to write into a new binary table. Exactly one of Data* fields may be set; the type selects the TFORM code.
type ColumnType ¶
type ColumnType int
ColumnType enumerates the supported table column types.
const ( ColByte ColumnType = iota ColInt16 ColInt32 ColInt64 ColFloat32 ColFloat64 ColString ColLogical ColBit ColComplex64 ColComplex128 ColVarArray )
type ColumnValue ¶
type ColumnValue interface {
~uint8 | ~int8 | ~int16 | ~uint16 | ~int32 | ~uint32 |
~int64 | ~uint64 | ~float32 | ~float64 |
~string | ~bool
}
ColumnValue is the constraint for the typed ReadColumn API. It accepts every Numeric type plus string and bool for Char/Logical columns.
type CompressFloatOptions ¶
type CompressFloatOptions struct {
// Algorithm is the compression method. Must be one of RICE_1,
// GZIP_1, GZIP_2, or NoCompress — HCOMPRESS_1 and PLIO_1 do not
// support float input in the compressed image convention.
// Default: RICE_1.
Algorithm compress.Algorithm
// TileShape picks per-tile dimensions, same convention as
// CompressOptions.TileShape. Default: whole-row tiles.
TileShape []int64
// BlockSize is the RICE_1 block size. Default 32.
BlockSize int
// QLevel is the quantization level. Positive values set the
// step as sigma/QLevel; negative values use an absolute step of
// -QLevel. Default 4.0.
QLevel float32
// DitherMethod selects SUBTRACTIVE_DITHER_1 (default),
// SUBTRACTIVE_DITHER_2 (zero-preserving), or NoDither.
DitherMethod compress.DitherMethod
// ZDither0 is the per-image dither seed written as the ZDITHER0
// keyword. Default 1.
ZDither0 int
// NullValue is the float sentinel for null pixels. Default: -1e30.
// The writer substitutes NaN inputs with this value before
// quantization, and the quantizer emits NullValueInt32 at those
// positions. The sentinel is also written as the ZBLANK header.
NullValue float32
// Nullcheck, if true, enables null detection. If false, NaN in
// the input will produce undefined quantized output — the caller
// is asserting there are no nulls. Default false.
Nullcheck bool
}
CompressFloatOptions configures a tile-compressed float image write. Fields have sensible defaults so the zero value is usable for the common case (RICE_1, whole-row tiles, qlevel=4, SUBTRACTIVE_DITHER_1).
type CompressOptions ¶
type CompressOptions struct {
// Algorithm is the compression method. Defaults to RICE_1.
Algorithm compress.Algorithm
// TileShape is the per-tile dimensions in the same order as the
// image's logical shape (first axis varies fastest). A zero or nil
// value picks the cfitsio default: ZTILE1 = NAXIS1, ZTILE2..n = 1
// (whole-row tiles).
TileShape []int64
// BlockSize is the RICE_1 block size. Default 32.
BlockSize int
// HCompressScale is the HCOMPRESS_1 quantization scale. 0 = lossless.
HCompressScale int
// ZDither0 is the dither seed (for float images compressed via
// RICE_1 or GZIP with quantize_level > 0). Default 1.
ZDither0 int
}
CompressOptions configures a tile-compressed image write. Fields have sensible defaults so the zero value is usable for the common case (RICE_1, whole-row tiles, lossless).
type CompressedImageHDU ¶
type CompressedImageHDU struct {
// contains filtered or unexported fields
}
CompressedImageHDU represents a tile-compressed image stored as a binary table HDU with ZIMAGE=T per the "Compressed Images" FITS convention (Pence et al. 2010).
From the user's point of view, a CompressedImageHDU behaves exactly like an ImageHDU: the same ReadPixels[T] / ReadPixelsContext[T] / ReadPixelsMasked[T] / BITPIX / NAXIS / Shape / Header methods are available, and the decompression pipeline runs transparently under the covers. Callers who care can ask Compressed() to tell them it's backed by tiles rather than raw bytes.
The physical backing is a binary table with:
- COMPRESSED_DATA VLA column — one row per tile, carrying the compressed byte stream for that tile.
- UNCOMPRESSED_DATA VLA column (optional) — fallback raw bytes for tiles that could not be compressed better than raw.
- GZIP_COMPRESSED_DATA VLA column (optional) — secondary fallback when the primary algorithm fails and gzip is used instead.
- ZSCALE, ZZERO columns (for float data) — per-tile quantization parameters.
- ZBLANK column (optional) — per-tile null sentinel.
func AppendCompressedFloat32Image ¶
func AppendCompressedFloat32Image(f *File, hdr *header.Header, shape []int64, data []float32, opts CompressFloatOptions) (*CompressedImageHDU, error)
AppendCompressedFloat32Image writes a float32 image HDU with tile compression. The pixel values are quantized to int32 per tile (using cfitsio's fits_quantize_float algorithm, ported to Go), then the integer tiles are fed through the chosen integer compression algorithm (RICE_1, GZIP_1, GZIP_2, or NoCompress).
This is lossy compression: the precision of reconstructed pixels is approximately sigma/QLevel, where sigma is the per-tile noise estimate. Tiles that cannot be quantized (e.g. constant-value regions) automatically fall back to gzip compression of the raw float bytes via the GZIP_COMPRESSED_DATA column, recovering those pixels bit-exactly on read.
The resulting HDU is a BINTABLE with ZIMAGE=T, ZQUANTIZ set to the dither method name, plus per-tile ZSCALE / ZZERO columns. Open() transparently decompresses it back to float32 on read.
func AppendCompressedImage ¶
func AppendCompressedImage[T Numeric](f *File, hdr *header.Header, shape []int64, data []T, opts CompressOptions) (*CompressedImageHDU, error)
AppendCompressedImage writes a new tile-compressed image HDU to the destination file. For integer BITPIX the compression is lossless. For float BITPIX callers should use AppendCompressedFloat32Image / AppendCompressedFloat64Image which handle quantization explicitly.
This is the write counterpart of the read-side CompressedImageHDU. The resulting HDU is a binary table with ZIMAGE=T and is automatically recognized by Open() when re-reading the file.
func (*CompressedImageHDU) BITPIX ¶
func (h *CompressedImageHDU) BITPIX() int
BITPIX returns the logical BITPIX of the uncompressed image (from ZBITPIX), NOT the BITPIX=8 of the wrapping binary table.
func (*CompressedImageHDU) BSCALE ¶
func (h *CompressedImageHDU) BSCALE() float64
BSCALE returns the BSCALE from the compressed image's Z-prefixed keyword (ZBSCALE) or falls back to BSCALE. Defaults to 1.0.
func (*CompressedImageHDU) BZERO ¶
func (h *CompressedImageHDU) BZERO() float64
BZERO returns the BZERO for the uncompressed image. Defaults to 0.
func (*CompressedImageHDU) Compressed ¶
func (h *CompressedImageHDU) Compressed() bool
Compressed always returns true for a CompressedImageHDU.
func (*CompressedImageHDU) CompressionType ¶
func (h *CompressedImageHDU) CompressionType() string
CompressionType returns the ZCMPTYPE value (e.g. "RICE_1").
func (*CompressedImageHDU) Header ¶
func (h *CompressedImageHDU) Header() *header.Header
Header returns the parsed header of the underlying binary table. Callers see every keyword on the HDU, including the Z* compression keywords. To access the "logical" image header (what the uncompressed image would have looked like), reconstruct it from the Z-prefixed keywords via the compressedMetadata fields below.
func (*CompressedImageHDU) Index ¶
func (h *CompressedImageHDU) Index() int
Index returns the 0-based HDU index within the parent file.
func (*CompressedImageHDU) NAXIS ¶
func (h *CompressedImageHDU) NAXIS() int
NAXIS returns the logical NAXIS of the uncompressed image (ZNAXIS).
func (*CompressedImageHDU) Shape ¶
func (h *CompressedImageHDU) Shape() []int64
Shape returns the logical image dimensions (ZNAXIS1..ZNAXISn).
func (*CompressedImageHDU) Type ¶
func (h *CompressedImageHDU) Type() HDUType
Type returns TypeImage — the compressed HDU presents an image-shaped view to callers regardless of its physical binary-table backing.
type ErrMissingRequiredKeyword ¶
ErrMissingRequiredKeyword describes a missing mandatory keyword.
func (*ErrMissingRequiredKeyword) Error ¶
func (e *ErrMissingRequiredKeyword) Error() string
type ErrTruncatedData ¶
ErrTruncatedData describes a data section that ends before the declared data size.
func (*ErrTruncatedData) Error ¶
func (e *ErrTruncatedData) Error() string
type ErrUnterminatedHeader ¶
ErrUnterminatedHeader describes a header that does not contain an END card within a generous block limit.
func (*ErrUnterminatedHeader) Error ¶
func (e *ErrUnterminatedHeader) Error() string
type File ¶
type File struct {
// contains filtered or unexported fields
}
File is a handle to an open FITS file. Not safe for concurrent use by multiple goroutines; see the package doc for the concurrency model.
func Create ¶
Create opens a new file for writing, truncating any existing contents. The returned *File is in ModeCreate and accepts HDU appends through the Append* family of functions. Callers must call Close() to finalize the trailing block pad.
func CreateContext ¶
CreateContext is Create with an explicit context.
func CreateWriter ¶
func CreateWriter(rws io.ReadWriteSeeker) (*File, error)
CreateWriter opens a FITS writer over an existing io.ReadWriteSeeker. The caller retains ownership of rws and must not close it via *File.Close.
func OpenContext ¶
OpenContext is Open with explicit context.Context. The context is consulted during the initial HDU scan; if it is cancelled, the open fails early.
func OpenForEdit ¶
OpenForEdit opens a FITS file for in-place mutation.
The returned *File supports header keyword update/add/delete (via the Header() surface), same-shape pixel overwrite (OverwritePixels), and HDU append at EOF (AppendImage/AppendBinaryTable). Structural mutations (resize, insert-in-middle, delete) must be done through EditFile.
On Open we check for a stale journal file from a crashed previous edit; if present it is either replayed or rolled back before returning. See plan decision 5.8 and implementation step 27.
func OpenForEditContext ¶
OpenForEditContext is OpenForEdit with an explicit context.
func OpenReadAll ¶
OpenReadAll slurps the contents of an io.Reader into memory and returns a regular *File. This is the helper for stream sources that do not already provide random access (see plan decision 5.3).
func OpenReader ¶
func OpenReader(r io.ReadSeeker) (*File, error)
OpenReader opens a FITS file over an existing io.ReadSeeker. The caller retains ownership of r — Close() on the returned *File will NOT close r.
func (*File) Close ¶
Close releases any resources owned by the *File. It is safe to call on a *File returned from OpenReader; in that case only internal state is released.
func (*File) CloseAndFlush ¶
Close finalizes the file. In write modes it flushes pending header mutations and syncs. In all modes it releases any owned file handle.
func (*File) CopyTo ¶
CopyTo walks every HDU in f and writes its raw header + data + pad bytes to w in file order. When f was opened from a valid FITS file, the output is byte-for-byte identical to the input — this is the heart of the regression tool cmd/fitscopy.
CopyTo does not re-encode or modify anything: headers pass through from rec.rawHeader (which still holds the on-disk bytes unless the caller has mutated the parsed header and called Flush), data passes through via ReadRange on the block reader. Callers that want a structural rebuild must use EditFile instead.
func (*File) Flush ¶
Flush persists any pending header mutations. Only meaningful in ModeEdit and ModeCreate. Returns ErrReadOnly for read-only files.
Implementation strategy (plan decision 5.8):
- For each dirty HDU, re-serialize the full header into bytes.
- If new length == old length (block count unchanged), overwrite in place and fsync. O(KB) per HDU.
- If new length differs, walk the dirty HDUs in reverse order and shift the file tail using a journal protocol (step 27). For v1 we conservatively refuse any flush that would require a tail shift and point the caller at EditFile. Journaled shift is implemented below but gated behind explicit opt-in while the crash-safety tests mature.
func (*File) HDU ¶
HDU returns the i-th HDU (zero-indexed; HDU(0) is the primary). An out-of- range index returns an error.
func (*File) HDUByName ¶
HDUByName returns the first extension HDU whose EXTNAME matches name. EXTNAME comparison is case-sensitive per convention. Returns an error if no matching HDU is found.
type FloatColor ¶
type FloatColor struct {
V float32
}
FloatColor wraps a float32 as a color.Color. RGBA returns the float value scaled to the 16-bit RGBA space via a lossy saturating cast. This is the only place the library does anything that could be called "scaling", and it exists solely to satisfy the color.Color interface contract. Callers that need faithful display MUST NOT rely on this mapping — they must build their own transform from the raw Pix[] slab.
func (FloatColor) RGBA ¶
func (c FloatColor) RGBA() (r, g, b, a uint32)
RGBA implements color.Color. The float value is saturating-cast to the 0..0xFFFF range — a cheap placeholder that exists only to satisfy the interface. For real rendering, read Pix[] directly and transform.
type FloatGray ¶
FloatGray is an image.Image over raw float32 pixels. It does NOT rescale — rendering through png.Encode without a caller-provided transform produces garbage, which is intentional. The purpose of this type is to let float FITS data participate in the image.Image ecosystem with lossless fidelity.
func (*FloatGray) ColorModel ¶
ColorModel returns a pass-through float color model.
type HDU ¶
type HDU interface {
Type() HDUType
// Header returns the full parsed header. Mutations to the returned
// *header.Header persist in memory but are only written to disk when
// (*File).Flush is called on a ModeEdit *File. See plan decision 5.8.
Header() *header.Header
// Index returns the 0-based HDU index in the parent file.
Index() int
// Compressed reports whether this HDU is a tile-compressed image
// backed by a binary table with ZIMAGE=T. Always false for plain
// ImageHDU / BinaryTableHDU / ASCIITableHDU; true only for
// CompressedImageHDU.
Compressed() bool
// CompressionType returns the ZCMPTYPE value ("RICE_1", "GZIP_1",
// etc.) for compressed HDUs, or "" for uncompressed HDUs.
CompressionType() string
}
HDU is the common interface implemented by every HDU kind.
Concrete types are *ImageHDU, *ASCIITableHDU, *BinaryTableHDU, and *CompressedImageHDU. Narrow to the concrete type via type assertion.
type ImageHDU ¶
type ImageHDU struct {
// contains filtered or unexported fields
}
ImageHDU represents a FITS primary HDU or an IMAGE extension.
func AppendImage ¶
func AppendImage[T Numeric](f *File, hdr *header.Header, shape []int64, data []T) (*ImageHDU, error)
AppendImage appends a new image HDU to a ModeEdit or ModeCreate file. It is a thin wrapper over WriteImage. hdr may be nil.
func WriteImage ¶
func WriteImage[T Numeric](dst WriteTarget, hdr *header.Header, shape []int64, data []T) (*ImageHDU, error)
WriteImage appends a new image HDU to the destination. The destination is either a *File in ModeCreate / ModeEdit (image is placed at EOF) or a *Writer returned from EditFile.
The HDU's mandatory structural keywords (SIMPLE/XTENSION, BITPIX, NAXIS, NAXISn, END) are synthesized from T, shape, and the destination position; callers must NOT add these to hdr themselves. Any keywords in hdr other than the mandatory structural ones are emitted after the structural block.
BSCALE/BZERO, if present in hdr, are honored on the write side: the library applies the inverse scaling to each value before encoding (so that reading the file back through ReadPixels[T] with the same BSCALE/BZERO returns the original values exactly).
func (*ImageHDU) AsImage ¶
AsImage returns a native image.Image for HDUs that can be represented losslessly:
- 2D BITPIX=8 → *image.Gray (uint8)
- 2D BITPIX=16 → *image.Gray16 (uint16, with TZERO=32768 unsigned handling)
- 2D BITPIX=-32 / -64 → *FloatGray with raw float values (not rescaled)
Returns ErrNotImageCompatible for HDUs that cannot be represented without loss (multi-dim, complex, NAXIS < 2, signed int32/int64, etc.). Callers that want lower-dim views must Slice() first. No auto-rescaling — see plan guiding principle.
func (*ImageHDU) BITPIX ¶
BITPIX returns the integer BITPIX value from the HDU's structural metadata.
func (*ImageHDU) Compressed ¶
Compressed returns false — plain ImageHDUs are raw, not tile-compressed.
func (*ImageHDU) CompressionType ¶
CompressionType returns the empty string for uncompressed images.
func (*ImageHDU) Header ¶
Header returns the parsed header, loading it lazily on first call. Errors during parse panic here; callers that need to handle parse errors explicitly must call (*File).HDU followed by direct access via the header package — in practice the scan pass already validated structure, so a lazy parse failure indicates programmer error or disk corruption between open and access.
type KeyNotFoundError ¶
KeyNotFoundError carries detail about an ErrKeyNotFound failure.
func (*KeyNotFoundError) Error ¶
func (e *KeyNotFoundError) Error() string
func (*KeyNotFoundError) Is ¶
func (e *KeyNotFoundError) Is(target error) bool
type Mode ¶
type Mode int
Mode is the access mode of an open *File.
const ( // ModeRead opens the file read-only. Set/Add/Delete on returned headers // may succeed in memory but (*File).Flush returns ErrReadOnly. ModeRead Mode = iota // ModeEdit opens the file read-write for in-place mutations and // end-of-file HDU appends. Structural changes require EditFile. ModeEdit // ModeCreate opens a new file for writing. Existing contents are // truncated. ModeCreate )
type Numeric ¶
type Numeric interface {
~uint8 | ~int8 | ~int16 | ~uint16 | ~int32 | ~uint32 |
~int64 | ~uint64 | ~float32 | ~float64
}
Numeric is the constraint for generic pixel and column access. The library does NOT auto-convert across BITPIX widths — if the target type cannot losslessly hold the file's on-disk values, ReadPixels returns ErrTypeMismatch. See plan decision 5.1.
type TypeMismatchError ¶
TypeMismatchError carries detail about an ErrTypeMismatch failure.
func (*TypeMismatchError) Error ¶
func (e *TypeMismatchError) Error() string
func (*TypeMismatchError) Is ¶
func (e *TypeMismatchError) Is(target error) bool
type VarColumn ¶
type VarColumn[T Numeric] struct { // contains filtered or unexported fields }
VarColumn stores all rows' variable-length data in a single contiguous slab plus an offsets table. This layout mirrors the FITS on-disk heap and avoids one allocation per row.
See plan decision 5.5.
func ReadVarColumn ¶
func ReadVarColumn[T Numeric](t *BinaryTableHDU, col int) (*VarColumn[T], error)
ReadVarColumn reads a variable-length (P/Q) binary-table column into a VarColumn[T]. The declared element type in the TFORM (e.g. "1PE(256)") must match T after scale/zero application.
func (*VarColumn[T]) At ¶
At returns a zero-copy view into the backing Values slab for row r. The returned slice aliases the backing buffer; if the caller needs an independent copy, they must clone it.
type WriteTarget ¶
type WriteTarget interface {
// contains filtered or unexported methods
}
WriteTarget abstracts the two sinks WriteImage can emit into: a *File (ModeCreate or ModeEdit) and a *Writer produced by EditFile. The interface is unexported to keep the write surface closed at v1.
type Writer ¶
type Writer struct {
// contains filtered or unexported fields
}
Writer is the streaming output side of EditFile. Users emit HDUs to it using CopyHDU (pass-through), CopyHDUWithHeader (new header, same data bytes), SkipHDU (omit from output), or AppendImage/AppendBinaryTable to add new HDUs.
Writer tracks whether the caller has emitted a primary HDU and rejects SkipHDU for the primary (every valid FITS file must have a primary).
func (*Writer) CopyHDU ¶
CopyHDU writes h to the output verbatim — both header bytes and data bytes are passed through with no re-parse.
func (*Writer) CopyHDUWithHeader ¶
CopyHDUWithHeader writes h to the output, replacing its header with hdr but passing the data bytes through verbatim. The caller's hdr must not include any mandatory structural keyword that would conflict with the data shape on disk — the library does not validate this; the output file's integrity is the caller's responsibility.
Source Files
¶
- ascii_table.go
- ascii_table_columns.go
- bin_table.go
- bin_table_columns.go
- bin_table_read.go
- checksum.go
- compressed.go
- compressed_read.go
- copy.go
- create.go
- edit.go
- editfile.go
- errors.go
- fits.go
- frame.go
- hdu.go
- image.go
- journal.go
- overwrite.go
- pixels.go
- scan.go
- stdimage.go
- subset.go
- var_column.go
- write_compressed.go
- write_image.go
- write_table.go
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
fitscopy
command
fitscopy reads an input FITS file through the fits library, walks every HDU, and writes them byte-for-byte to an output file via the library's public CopyTo API.
|
fitscopy reads an input FITS file through the fits library, walks every HDU, and writes them byte-for-byte to an output file via the library's public CopyTo API. |
|
fitsdump
command
fitsdump prints a human-readable summary of every HDU in a FITS file, including the full header keyword list.
|
fitsdump prints a human-readable summary of every HDU in a FITS file, including the full header keyword list. |
|
Package compress implements decoders for the FITS tile-compression algorithms defined by the "Compressed Images" FITS convention (Pence et al.
|
Package compress implements decoders for the FITS tile-compression algorithms defined by the "Compressed Images" FITS convention (Pence et al. |
|
Package header implements FITS header-card parsing and serialization.
|
Package header implements FITS header-card parsing and serialization. |
|
Package healpix implements HEALPix pixel indexing for the Hierarchical Equal-Area isoLatitude Pixelisation of the sphere (Gorski et al.
|
Package healpix implements HEALPix pixel indexing for the Hierarchical Equal-Area isoLatitude Pixelisation of the sphere (Gorski et al. |
|
internal
|
|
|
bigendian
Package bigendian provides typed big-endian read/write helpers and bulk in-place byte-swapping for FITS data sections.
|
Package bigendian provides typed big-endian read/write helpers and bulk in-place byte-swapping for FITS data sections. |
|
bitpix
Package bitpix defines the BITPIX enumeration and helpers.
|
Package bitpix defines the BITPIX enumeration and helpers. |
|
block
Package block provides 2880-byte block I/O over io.ReadSeeker and io.WriteSeeker.
|
Package block provides 2880-byte block I/O over io.ReadSeeker and io.WriteSeeker. |
|
checksum
Package checksum implements the FITS checksum algorithm defined in Appendix J of the FITS Standard v4.0.
|
Package checksum implements the FITS checksum algorithm defined in Appendix J of the FITS Standard v4.0. |
|
tform
Package tform parses the FITS TFORMn and TDIMn column-format keyword values for ASCII and binary tables.
|
Package tform parses the FITS TFORMn and TDIMn column-format keyword values for ASCII and binary tables. |
|
Package stats provides generic, NaN-aware statistics functions for astronomical image data.
|
Package stats provides generic, NaN-aware statistics functions for astronomical image data. |
|
Package stretch implements image stretching operations for FITS astronomical images.
|
Package stretch implements image stretching operations for FITS astronomical images. |
|
Package wcs parses the FITS World Coordinate System keyword set defined in Greisen & Calabretta 2002 ("Representations of world coordinates in FITS", Paper I) into a typed in-memory struct.
|
Package wcs parses the FITS World Coordinate System keyword set defined in Greisen & Calabretta 2002 ("Representations of world coordinates in FITS", Paper I) into a typed in-memory struct. |
|
transform
Package transform computes forward and inverse FITS World Coordinate System mappings between image pixel coordinates and celestial spherical coordinates.
|
Package transform computes forward and inverse FITS World Coordinate System mappings between image pixel coordinates and celestial spherical coordinates. |