Skip to content
/ paa Public

Go implementation of the PAA texture format used in DayZ/Arma, with TexConvert-style config resolver, LZO/LZSS support, swizzle handling for normal maps.

License

Notifications You must be signed in to change notification settings

WoozyMasta/paa

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

paa

Go package for reading and writing PAA (Arma/DayZ texture) files. Supports DXT1/DXT5 and several uncompressed formats, mipmaps with LZO/LZSS, and optional registration with the standard image package.

Features

  • Decode and encode PAA (DXT1, DXT5, ARGB8, ARGB1555, ARGB4444, GRAYA/AI88)
  • Mipmap support; LZO and LZSS decompression for mip data
  • Optional registration with image via paa/img
  • TexConvert.cfg‑style resolution via texconfig (suffix → format/swizzle/etc.)

Usage

With image.Decode

Import the img subpackage so that PAA is registered:

import (
  _ "github.com/woozymasta/paa/img"
  "image"
)

img, format, err := image.Decode(f)
cfg, _, err := image.DecodeConfig(f)

Direct API

import "github.com/woozymasta/paa"

p, err := paa.DecodePAA(r)
img, err := p.MipMaps[0].Image()

err = paa.Encode(w, img)

Metadata-only fast path

If you only need texture headers/tags (for example, building texheaders) without decoding mip payloads, use metadata helpers:

meta, err := paa.DecodeMetadata(r)          // full GGAT map + mip headers
headers, err := paa.DecodeMetadataHeaders(r) // Type + mip headers + CGVA/CXAM/GALF only

meta2, err := paa.DecodeMetadataBytes(data)
headers2, err := paa.DecodeMetadataHeadersBytes(data)

For on-the-fly encode pipelines, you can collect compact metadata in the same encode pass (without reading the generated PAA again):

headers, err := paa.EncodeWithOptionsAndMetadataHeaders(w, img, opts)

PAA -> DDS/KTX (preserve mipmaps)

If you need DDS/KTX with the original mip chain (without re-generating mipmaps), use full PAA decode and convert:

import (
  "github.com/woozymasta/paa"
)

p, err := paa.DecodePAA(r)
dds, err := p.ToDDS()
err = dds.Write(w)

ktx, err := p.ToKTX()
err = ktx.Write(w)

Or use a single-step helper:

dds, err := paa.DecodeToDDS(r)
err = dds.Write(w)

ktx, err := paa.DecodeToKTX(r)
err = ktx.Write(w)

Note

direct conversion supports DXT-based PAA types.

TexConvert.cfg‑style encoding

Use texconfig to resolve filename hints and apply swizzle/format rules:

import (
  "github.com/woozymasta/paa"
  "github.com/woozymasta/paa/texconfig"
)

cfg, _ := texconfig.DefaultTexConvertConfig()
err := paa.EncodeWithTexConfig(w, img, "my_texture_nohq.paa", cfg)

You can also parse a real TexConvert.cfg and override values before encoding:

cfg, _ := texconfig.ParseFile("TexConvert.cfg")
cfg.DisableAutoReduce = true
err := paa.EncodeWithTexConfig(w, img, "my_texture_nohq.paa", cfg)

Encoding options

For explicit control, use EncodeWithOptions:

opts := &paa.EncodeOptions{
  Type:          paa.PaxDXT5,
  UseLZO:        true,
  ForceCXAMFull: true,
  BCn: &bcn.EncodeOptions{
    QualityLevel: bcn.QualityLevelBest,
  },
}
err := paa.EncodeWithOptions(w, img, opts)

About

Go implementation of the PAA texture format used in DayZ/Arma, with TexConvert-style config resolver, LZO/LZSS support, swizzle handling for normal maps.

Topics

Resources

License

Stars

Watchers

Forks