Skip to content

Repository files navigation

carfile-go

carfile-go is a pure-Go library and CLI for parsing and extracting Apple's compiled Asset Catalog (Assets.car) format. It uses only the Go standard library and does not call CoreUI, assetutil, cgo, or third-party codecs at runtime.

CLI

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, 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/deepmap2"
    "github.com/devcxm/carfile-go/codec/kcbc"
    "github.com/devcxm/carfile-go/codec/lzfse"
    "github.com/devcxm/carfile-go/codec/lzvn"
)

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;
  • Deepmap2 default, lossless, and palette encodings;
  • ARGB/BGRA and GA8 pixels;
  • packed-image links, including lower-left coordinate conversion and atlas cropping.

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.

References and acknowledgements

This project benefited from the following public research and reference implementations:

Many thanks to the authors and maintainers for publishing their research and source code. carfile-go is an independent pure-Go implementation and does not copy or invoke Apple's private CoreUI framework.

About

Pure-Go library and CLI for parsing and extracting Apple Assets.car files.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages