carfile

package module
v0.5.3 Latest Latest
Warning

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

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

README

carfile-go

carfile-go is a Go library and CLI for parsing and extracting Apple's compiled Asset Catalog (Assets.car) format. Most formats are decoded in pure Go with no third-party codecs. Native decoding is available on Darwin, with portable Go fallbacks for supported encodings.

CLI

Download the archive for your platform and architecture from the GitHub Release. Darwin, Linux, and Windows packages are published for both amd64 and arm64. Each release includes a checksum manifest and signed GitHub build provenance. Verify both before running the binary:

grep ' carfile_0.5.3_darwin_arm64.tar.gz$' checksums.txt | shasum -a 256 -c -
gh attestation verify carfile_0.5.3_darwin_arm64.tar.gz \
  --repo devcxm/carfile-go

Build the command:

go build -o carfile ./cmd/carfile

Running it with only an input file recovers every logical resource into an <name>-extracted directory beside the input:

carfile Assets.car

Options:

Usage:
  carfile [options] <Assets.car>

Options:
  -o, --output DIR       Output directory
  -f, --format FORMAT    resources (default), xcassets, raw, png, or json
  -i, --include PATTERN  Include asset/file glob; may be repeated
  -q, --quiet            Disable progress output
  -v, --version          Print version
  -h, --help             Show help

Examples:

carfile Assets.car
carfile -o output Assets.car
carfile -i AppIcon Assets.car
carfile -i 'myBannerImage_*' -i '*@2x.png' Assets.car
carfile --format xcassets --output restored Assets.car
carfile -f raw -o payloads Assets.car
carfile -f json -o metadata Assets.car
Output formats
Format Output
resources All logical resources. Single Data resources keep their original file name; rendition families are grouped by asset name. Packed atlas entries are cropped into individual files. This is the default.
xcassets A flat, compilable Assets.xcassets with generated Contents.json files.
raw Physical CAR payloads with wrappers removed where possible. Compressed data stays compressed.
png Every directly stored compressed bitmap as PNG, including packed atlas images.
json Parsed CAR metadata in catalog.json.

Every extraction directory includes a machine-readable manifest except the JSON format, whose output is already self-describing.

Selective extraction

--include/-i accepts Go-style glob patterns and can be repeated. Patterns are ORed and are matched against the logical asset name, rendition filename, and asset/file path. Filtering happens before bitmap decompression and PNG encoding.

# Both @2x and @3x renditions from one logical asset
carfile -i myBannerImage_de Assets.car

# One exact rendition
carfile -i myBannerImage_de@2x.png Assets.car

# Several asset families
carfile -i 'HomePage_*' -i 'AppIcon' Assets.car

# Precise asset/file selection
carfile -i 'AppIcon/Icon-iPhone-60@3x.png' Assets.car

The same filter is available to library callers through ExtractOptions.Includes. Include filters apply to resources, xcassets, raw, and png; JSON output always describes the complete catalog.

For a logical image stored inside a packed atlas, use resources or xcassets; these formats resolve the internal link and crop the requested image. The png format intentionally operates on directly stored physical bitmap renditions, while raw operates on physical payloads.

Progress

The CLI displays the current percentage, item count, asset name, and rendition filename while extracting. Interactive terminals reuse one line; redirected output uses one event per line. Use --quiet/-q to disable progress.

Library callers can receive the same synchronous, serial progress events:

result, err := carfile.ExtractFile("Assets.car", carfile.ExtractOptions{
    Format:          carfile.FormatResources,
    OutputDirectory: "output",
    Progress: func(event carfile.Progress) {
        log.Printf("%d/%d %s/%s", event.Current, event.Total, event.AssetName, event.FileName)
    },
})

Library

The module root is a regular importable Go package; the CLI is isolated under cmd/carfile.

package main

import (
    "log"

    carfile "github.com/devcxm/carfile-go"
)

func main() {
    result, err := carfile.ExtractFile("Assets.car", carfile.ExtractOptions{
        Format:          carfile.FormatXCAssets,
        OutputDirectory: "restored",
        Includes:        []string{"AppIcon", "myBannerImage_*"},
    })
    if err != nil {
        log.Fatal(err)
    }
    log.Printf("wrote %d files to %s", result.Written, result.OutputDirectory)
}

For parsing without immediately exporting:

catalog, err := carfile.Open("Assets.car")
if err != nil {
    return err
}

result, err := catalog.Export(carfile.ExtractOptions{
    Format:          carfile.FormatResources,
    OutputDirectory: "output",
})

Individual codecs are independently importable:

import (
	"github.com/devcxm/carfile-go/codec/deepmap"
	"github.com/devcxm/carfile-go/codec/deepmap2"
	"github.com/devcxm/carfile-go/codec/kcbc"
	"github.com/devcxm/carfile-go/codec/lzfse"
	"github.com/devcxm/carfile-go/codec/lzvn"
	"github.com/devcxm/carfile-go/codec/palette"
	"github.com/devcxm/carfile-go/codec/rle"
)

Supported formats

The parser reads:

  • BOMStore headers, block indices, variables, and linked B+ tree leaves;
  • CARHEADER, EXTENDED_METADATA, and KEYFORMAT;
  • APPEARANCEKEYS, FACETKEYS, and RENDITIONS;
  • CSI headers, TLV metadata, internal links, and common RAWD, CELM, and COLR payloads.

The decoder supports:

  • LZFSE bvx2, raw bvx-, and embedded LZVN bvxn streams;
  • raw LZVN instruction streams;
  • KCBC horizontal bitmap chunks and row-padding removal;
  • row-oriented RLE and quantized palette-img bitmaps;
  • legacy Deepmap and Deepmap2 default, lossless, and palette encodings;
  • ARGB/BGRA, GA8, and wide-gamut RGBW pixels;
  • packed-image links, including lower-left coordinate conversion and atlas cropping.

On Darwin with cgo enabled, supported Deepmap variants can use native decoding. Portable decoding is used on other platforms and whenever native decoding is unavailable.

Original RAWD files such as SVG and JPEG are copied byte-for-byte. Compiled bitmaps are re-encoded as PNG; their original PNG compression, ancillary metadata, and source group hierarchy are not present in the CAR and cannot be reconstructed exactly.

Documentation

Overview

Package carfile parses and extracts Apple's compiled Asset Catalog files.

Most formats are decoded in pure Go. On Darwin with cgo enabled, Deepmap variants use the system Accelerate framework for CoreUI-compatible output. High-level callers normally use ExtractFile. Callers that need metadata or repeated exports can use Open followed by methods on Catalog. Specialized compression formats are also exposed as importable packages under codec/.

Example (SpecializedCodecPackage)
package main

import (
	"fmt"

	"github.com/devcxm/carfile-go/codec/lzfse"
)

func main() {
	_, _ = lzfse.Decode([]byte("not an LZFSE stream"))
	fmt.Println("codec is independently importable")
}
Output:
codec is independently importable

Index

Examples

Constants

View Source
const Version = "0.5.3"

Version is the library and CLI semantic version.

Variables

This section is empty.

Functions

func DecodeKCBC

func DecodeKCBC(src []byte, width, height uint32, bytesPerPixel int) ([]byte, error)

DecodeKCBC decodes a CoreUI chunked bitmap payload.

func DecodeLZFSE

func DecodeLZFSE(src []byte) ([]byte, error)

DecodeLZFSE decodes an Apple LZFSE stream.

func DecodeLZVN

func DecodeLZVN(src []byte, outputSize int) ([]byte, error)

DecodeLZVN decodes a raw Apple LZVN stream to outputSize bytes.

func DecodePaletteImage added in v0.5.3

func DecodePaletteImage(src []byte, width, height uint32, pixelFormat string) ([]byte, error)

DecodePaletteImage decodes a CoreUI palette-img bitmap payload.

func DecodeRLE added in v0.5.3

func DecodeRLE(src []byte, width, height uint32, bytesPerPixel int) ([]byte, error)

DecodeRLE decodes a CoreUI row-oriented run-length encoded bitmap.

func DecodeRenditionImage

func DecodeRenditionImage(rendition Rendition) (image.Image, error)

DecodeRenditionImage converts a supported compressed pixel rendition into a standard-library image. On Darwin with cgo enabled, Deepmap variants use Accelerate's CoreUI-compatible vImage decoders; other formats are decoded in Go.

func DefaultOutputDirectory

func DefaultOutputDirectory(inputPath string) string

DefaultOutputDirectory returns the zero-configuration extraction directory used by the CLI and ExtractFile.

Types

type Appearance

type Appearance struct {
	Name string `json:"name"`
	ID   uint16 `json:"id"`
}

type AttributeType

type AttributeType uint32

func (AttributeType) String

func (t AttributeType) String() string

type AttributeValue

type AttributeValue struct {
	Type  AttributeType `json:"type"`
	Name  string        `json:"name"`
	Value uint16        `json:"value"`
}

type BOM

type BOM struct {
	Header BOMHeader
	// contains filtered or unexported fields
}

func ParseBOM

func ParseBOM(r io.ReaderAt, size int64) (*BOM, error)

ParseBOM reads a BOMStore without using Apple's private Bom.framework.

func (*BOM) Block

func (b *BOM) Block(id uint32) ([]byte, error)

func (*BOM) Info

func (b *BOM) Info() BOMInfo

func (*BOM) NamedBlock

func (b *BOM) NamedBlock(name string) ([]byte, error)

func (*BOM) TreeEntries

func (b *BOM) TreeEntries(name string) ([]BOMTreeEntry, error)

TreeEntries walks every linked leaf in a named BOM B+ tree.

func (*BOM) VariableNames

func (b *BOM) VariableNames() []string

type BOMBlock

type BOMBlock struct {
	Offset uint32 `json:"offset"`
	Length uint32 `json:"length"`
}

BOMBlock points to a block in the BOMStore file.

type BOMHeader

type BOMHeader struct {
	Version        uint32 `json:"version"`
	NumberOfBlocks uint32 `json:"number_of_blocks"`
	IndexOffset    uint32 `json:"index_offset"`
	IndexLength    uint32 `json:"index_length"`
	VarsOffset     uint32 `json:"vars_offset"`
	VarsLength     uint32 `json:"vars_length"`
}

BOMHeader describes the big-endian BOMStore container header.

type BOMInfo

type BOMInfo struct {
	Header     BOMHeader         `json:"header"`
	BlockCount int               `json:"block_count"`
	Variables  map[string]uint32 `json:"variables"`
}

BOMInfo is the container-level information included in Catalog output.

type BOMTreeEntry

type BOMTreeEntry struct {
	KeyBlock   uint32
	ValueBlock uint32
	Key        []byte
	Value      []byte
}

BOMTreeEntry contains the raw key and value blocks from a BOM B+ tree.

type CARHeader

type CARHeader struct {
	Tag                 string `json:"tag"`
	CoreUIVersion       uint32 `json:"coreui_version"`
	StorageVersion      uint32 `json:"storage_version"`
	StorageTimestamp    uint32 `json:"storage_timestamp"`
	RenditionCount      uint32 `json:"rendition_count"`
	MainVersion         string `json:"main_version"`
	AssetStorageVersion string `json:"asset_storage_version"`
	UUID                string `json:"uuid"`
	AssociatedChecksum  uint32 `json:"associated_checksum"`
	SchemaVersion       uint32 `json:"schema_version"`
	ColorSpaceID        uint32 `json:"color_space_id"`
	KeySemantics        uint32 `json:"key_semantics"`
}

type CSI

type CSI struct {
	Tag              string         `json:"tag"`
	Version          uint32         `json:"version"`
	Flags            RenditionFlags `json:"flags"`
	Width            uint32         `json:"width"`
	Height           uint32         `json:"height"`
	ScaleFactor      uint32         `json:"scale_factor"`
	PixelFormat      string         `json:"pixel_format,omitempty"`
	ColorSpaceID     uint8          `json:"color_space_id"`
	ModificationTime uint32         `json:"modification_time"`
	Layout           uint16         `json:"layout"`
	LayoutName       string         `json:"layout_name"`
	Name             string         `json:"name,omitempty"`
	BitmapLengths    []uint32       `json:"bitmap_lengths,omitempty"`
	TLVs             []TLV          `json:"tlvs,omitempty"`
	Payload          Payload        `json:"payload"`
}

type Catalog

type Catalog struct {
	BOM         BOMInfo           `json:"bom"`
	Header      CARHeader         `json:"header"`
	Metadata    *ExtendedMetadata `json:"extended_metadata,omitempty"`
	KeyFormat   KeyFormat         `json:"key_format"`
	Appearances []Appearance      `json:"appearances,omitempty"`
	Facets      []Facet           `json:"facets"`
	Renditions  []Rendition       `json:"renditions"`
}

Catalog is a parsed compiled Asset Catalog.

func Open

func Open(path string) (*Catalog, error)

Open parses the CAR file at path.

func Parse

func Parse(r io.ReaderAt, size int64) (*Catalog, error)

Parse parses a CAR file from a random-access reader.

func (*Catalog) Export

func (c *Catalog) Export(options ExtractOptions) (ExtractResult, error)

Export writes an already parsed catalog using one of the supported formats.

func (*Catalog) ExportImages

func (c *Catalog) ExportImages(directory string) (ImageExportResult, error)

ExportImages decodes compressed bitmap renditions and writes PNG files plus a manifest describing both successful and unsupported renditions.

func (*Catalog) ExportRaw

func (c *Catalog) ExportRaw(directory string) (ExportResult, error)

ExportRaw writes rendition payloads without invoking CoreUI or external decompressors. Standard RAWD files are unwrapped; CELM files have their 16-byte wrapper removed but remain compressed.

func (*Catalog) ExportRecovered

func (c *Catalog) ExportRecovered(directory string) (RecoveryResult, error)

ExportRecovered is kept for compatibility. New callers should use ExportXCAssets or the format-independent Export method.

func (*Catalog) ExportResources

func (c *Catalog) ExportResources(directory string) (RecoveryResult, error)

ExportResources recovers all logical assets without generating Asset Catalog metadata. Single Data resources keep their original file name; rendition families are grouped by asset name.

func (*Catalog) ExportXCAssets

func (c *Catalog) ExportXCAssets(directory string) (RecoveryResult, error)

ExportXCAssets recreates a flat, valid Assets.xcassets directory. It resolves internal references into packed images and crops every referenced subimage back into an individual PNG. Original RAWD data such as SVG and JPEG files is copied without re-encoding.

type Deepmap2Bitmap

type Deepmap2Bitmap = deepmap2.Bitmap

Deepmap2Bitmap is kept as a root-package alias for callers that do not need to import the specialized codec package directly.

func DecodeDeepmap added in v0.5.3

func DecodeDeepmap(src []byte, width, height uint32) (Deepmap2Bitmap, error)

DecodeDeepmap decodes a legacy CoreUI Deepmap bitmap payload.

func DecodeDeepmap2

func DecodeDeepmap2(src []byte) (Deepmap2Bitmap, error)

DecodeDeepmap2 decodes a CoreUI Deepmap2 bitmap payload.

func DecodeDeepmap2WithGeometry added in v0.5.3

func DecodeDeepmap2WithGeometry(src []byte, width, height uint16) (Deepmap2Bitmap, error)

DecodeDeepmap2WithGeometry decodes a CoreUI Deepmap2 payload using the complete rendition geometry, including chunked streams.

type ExportRecord

type ExportRecord struct {
	Index         int              `json:"index"`
	AssetName     string           `json:"asset_name,omitempty"`
	RenditionName string           `json:"rendition_name,omitempty"`
	Layout        string           `json:"layout"`
	PixelFormat   string           `json:"pixel_format,omitempty"`
	Compression   string           `json:"compression,omitempty"`
	File          string           `json:"file,omitempty"`
	Openable      bool             `json:"openable"`
	Status        string           `json:"status"`
	LinkedKey     []AttributeValue `json:"linked_key,omitempty"`
}

type ExportResult

type ExportResult struct {
	Directory string         `json:"directory"`
	Written   int            `json:"written"`
	Skipped   int            `json:"skipped"`
	Files     []ExportRecord `json:"files"`
}

type ExtendedMetadata

type ExtendedMetadata struct {
	Tag                       string `json:"tag"`
	ThinningArguments         string `json:"thinning_arguments,omitempty"`
	DeploymentPlatformVersion string `json:"deployment_platform_version,omitempty"`
	DeploymentPlatform        string `json:"deployment_platform,omitempty"`
	AuthoringTool             string `json:"authoring_tool,omitempty"`
}

type ExtractOptions

type ExtractOptions struct {
	OutputDirectory string
	Format          OutputFormat
	// Includes limits output to matching asset names, rendition file names,
	// or "asset/file" paths. Patterns use path.Match glob syntax.
	Includes []string
	// Progress is called synchronously before each selected item is decoded or
	// written. Current is one-based and callbacks are never concurrent.
	Progress func(Progress)
}

ExtractOptions controls high-level file extraction. An empty Format means FormatResources. ExtractFile also derives OutputDirectory when it is empty.

Example
package main

import (
	"fmt"

	carfile "github.com/devcxm/carfile-go"
)

func main() {
	options := carfile.ExtractOptions{Format: carfile.FormatXCAssets, OutputDirectory: "restored"}
	fmt.Println(options.Format)
}
Output:
xcassets

type ExtractResult

type ExtractResult struct {
	Format          OutputFormat `json:"format"`
	OutputDirectory string       `json:"output_directory"`
	Written         int          `json:"written"`
	Skipped         int          `json:"skipped,omitempty"`
	Failed          int          `json:"failed,omitempty"`
}

ExtractResult is the format-independent summary returned to library and CLI callers. Detailed per-file results are stored in each output manifest.

func ExtractFile

func ExtractFile(path string, options ExtractOptions) (ExtractResult, error)

ExtractFile opens a compiled asset catalog and exports it according to options. With zero-value options it recovers all logical resources beside the input file in a <name>-extracted directory.

type Facet

type Facet struct {
	Name       string           `json:"name"`
	HotSpotX   uint16           `json:"hot_spot_x,omitempty"`
	HotSpotY   uint16           `json:"hot_spot_y,omitempty"`
	Attributes []AttributeValue `json:"attributes"`
}

type ImageExportRecord

type ImageExportRecord struct {
	Index       int    `json:"index"`
	AssetName   string `json:"asset_name,omitempty"`
	Name        string `json:"name,omitempty"`
	Compression string `json:"compression"`
	File        string `json:"file,omitempty"`
	Error       string `json:"error,omitempty"`
}

type ImageExportResult

type ImageExportResult struct {
	Directory string              `json:"directory"`
	Written   int                 `json:"written"`
	Failed    int                 `json:"failed"`
	Files     []ImageExportRecord `json:"files"`
}

type KeyFormat

type KeyFormat struct {
	Tag            string          `json:"tag"`
	Version        uint32          `json:"version"`
	Attributes     []AttributeType `json:"attributes"`
	AttributeNames []string        `json:"attribute_names"`
}

type OutputFormat

type OutputFormat string

OutputFormat selects the representation written by ExtractFile or Export.

const (
	// FormatResources recovers every logical resource into ordinary folders.
	FormatResources OutputFormat = "resources"
	// FormatXCAssets recreates a compilable Assets.xcassets directory.
	FormatXCAssets OutputFormat = "xcassets"
	// FormatRaw writes physical rendition payloads without decoding them.
	FormatRaw OutputFormat = "raw"
	// FormatPNG decodes physical bitmap payloads as PNG files, including atlases.
	FormatPNG OutputFormat = "png"
	// FormatJSON writes the parsed catalog metadata as JSON.
	FormatJSON OutputFormat = "json"
)

func ParseOutputFormat

func ParseOutputFormat(value string) (OutputFormat, error)

ParseOutputFormat validates a user-facing format name and accepts a few convenient aliases.

type Payload

type Payload struct {
	Tag             string    `json:"tag,omitempty"`
	Version         uint32    `json:"version,omitempty"`
	Length          int       `json:"length"`
	DeclaredLength  uint32    `json:"declared_length,omitempty"`
	CompressionType *uint32   `json:"compression_type,omitempty"`
	Compression     string    `json:"compression,omitempty"`
	ColorSpaceID    *uint32   `json:"color_space_id,omitempty"`
	ColorComponents []float64 `json:"color_components,omitempty"`
	Data            []byte    `json:"-"`
}

type PixelRect

type PixelRect struct {
	X      uint32 `json:"x"`
	Y      uint32 `json:"y"`
	Width  uint32 `json:"width"`
	Height uint32 `json:"height"`
}

type Progress

type Progress struct {
	Current        int    `json:"current"`
	Total          int    `json:"total"`
	RenditionIndex int    `json:"rendition_index"`
	AssetName      string `json:"asset_name,omitempty"`
	FileName       string `json:"file_name"`
}

Progress describes the item currently being processed by an export.

type RecoveryRecord

type RecoveryRecord struct {
	Index       int    `json:"index"`
	AssetName   string `json:"asset_name"`
	Name        string `json:"name"`
	File        string `json:"file,omitempty"`
	Mode        string `json:"mode,omitempty"`
	TargetIndex *int   `json:"target_index,omitempty"`
	Error       string `json:"error,omitempty"`
}

type RecoveryResult

type RecoveryResult struct {
	Directory        string           `json:"directory"`
	CatalogDirectory string           `json:"catalog_directory,omitempty"`
	AssetSets        int              `json:"asset_sets"`
	Written          int              `json:"written"`
	CopiedOriginals  int              `json:"copied_originals"`
	Decoded          int              `json:"decoded"`
	Cropped          int              `json:"cropped"`
	Duplicates       int              `json:"duplicates_skipped"`
	Failed           int              `json:"failed"`
	Files            []RecoveryRecord `json:"files"`
}

type Rendition

type Rendition struct {
	AssetName string           `json:"asset_name,omitempty"`
	Key       []AttributeValue `json:"key"`
	CSI       CSI              `json:"csi"`
}

type RenditionFlags

type RenditionFlags struct {
	Raw                           uint32 `json:"raw"`
	HeaderFlaggedFPO              bool   `json:"header_flagged_fpo"`
	ExcludedFromContrastFilter    bool   `json:"excluded_from_contrast_filter"`
	VectorBased                   bool   `json:"vector_based"`
	Opaque                        bool   `json:"opaque"`
	BitmapEncoding                uint8  `json:"bitmap_encoding"`
	OptOutOfThinning              bool   `json:"opt_out_of_thinning"`
	Flippable                     bool   `json:"flippable"`
	Tintable                      bool   `json:"tintable"`
	PreservedVectorRepresentation bool   `json:"preserved_vector_representation"`
}

type TLV

type TLV struct {
	Type         uint32           `json:"type"`
	Name         string           `json:"name"`
	Length       uint32           `json:"length"`
	Text         string           `json:"text,omitempty"`
	Hex          string           `json:"hex,omitempty"`
	LinkedRect   *PixelRect       `json:"linked_rect,omitempty"`
	LinkedLayout *uint16          `json:"linked_layout,omitempty"`
	LinkedKey    []AttributeValue `json:"linked_key,omitempty"`
}

Directories

Path Synopsis
cmd
carfile command
codec
deepmap
Package deepmap decodes the legacy CoreUI deepmap-lzfse container.
Package deepmap decodes the legacy CoreUI deepmap-lzfse container.
deepmap2
Package deepmap2 decodes CoreUI Deepmap2 bitmap payloads.
Package deepmap2 decodes CoreUI Deepmap2 bitmap payloads.
kcbc
Package kcbc decodes CoreUI's chunked bitmap container.
Package kcbc decodes CoreUI's chunked bitmap container.
lzfse
Package lzfse decodes Apple LZFSE streams without cgo.
Package lzfse decodes Apple LZFSE streams without cgo.
lzvn
Package lzvn decodes Apple's raw LZVN instruction streams.
Package lzvn decodes Apple's raw LZVN instruction streams.
palette
Package palette decodes CoreUI palette-img bitmap payloads.
Package palette decodes CoreUI palette-img bitmap payloads.
rle
Package rle decodes CoreUI row-oriented run-length encoded bitmaps.
Package rle decodes CoreUI row-oriented run-length encoded bitmaps.

Jump to

Keyboard shortcuts

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