Metadata-Version: 2.4
Name: texture-courier
Version: 0.0.16
Summary: rips texture cache from second life viewers
Author-email: meri <meri@himawari.fun>
License-Expression: MIT
Project-URL: Homepage, https://github.com/furudean/texture-courier
Project-URL: Issues, https://github.com/furudean/texture-courier/issues
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: OS Independent
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: watcher
Requires-Dist: watchdog>=6; extra == "watcher"
Provides-Extra: cli
Requires-Dist: texture-courier[watcher]; extra == "cli"
Requires-Dist: tqdm>=4; extra == "cli"
Dynamic: license-file

![Courier from Hello Girl](https://github.com/furudean/texture-courier/blob/main/courier.png?raw=true)

# texture-courier

simple CLI program and high-level python API to interact with the second life texture cache.

if you're looking for a end-user tool, you may be interested in [lltexturecache-browser-qt](https://github.com/furudean/lltexturecache-browser-qt).

## goals

- output the entire texture cache in a commonly readable format
- support all platforms that support python
- be as fast as it is practical to be
- use few dependencies

## non goals

- no gui, no bells and whistles
- no option to transform outputs into other formats, as i believe this is better covered by other programs

## use CLI

install texture-courier from PyPI. conventionally this is done with pip. but [uv tool install](https://docs.astral.sh/uv/guides/tools/#installing-tools) gives you proper dependency isolation without having to worry about environments.

```bash
# with uv (preferred)
uv tool install texture-courier[cli]

# with pip
pip install texture-courier[cli]
```

then, run it on the command line like

```
texture-courier
```

texture-courier will attempt to find any texture caches on the system
automatically. if this does not work, find your texture cache and provide it
like so

```
texture-courier /Users/meri/Library/Caches/Firestorm_x64/texturecache
```

this dumps the contents of the cache to a directory (by default, to  
`./texturecache`).

see `texture-courier --help` for other options.

## use API

```python
from texture_courier import list_texture_caches, TextureCache

caches = list_texture_caches()
# [PosixPath('/Users/meri/Library/Caches/Firestorm_x64/texturecache')]

cache = TextureCache("/Users/meri/Library/Caches/Firestorm_x64/texturecache")
# <TextureCache /Users/meri/Library/Caches/Firestorm_x64/texturecache, 26478 textures, 3 GB>

# the cache implements an iterator, which is the main way to list textures
for tex in cache:
    print(tex)

# <Texture 93ff0fc0-731a-b04e-8a66-b6489c059e04, 2026-08-21 22:39:00, 20 KB, whole=True>
# <Texture eb2667d6-dbc8-7188-ea0e-2bc8bc8da19b, 2026-08-21 22:39:00, 39 KB, whole=True>
# <Texture f75d9ea7-2c6f-3d11-5645-7c7c0a195721, 2026-08-21 22:38:58, 597 bytes, whole=True>
# ...

# the api implements __getitem__, so you can interact with it like you would a list
first_ten = cache[:10]

for tex in first_ten:
    with open(f"{tex.uuid}.jp2", "wb") as f:
        f.write(tex.jpeg_2000())
```

### thumbnails

the viewer keeps a small decoded copy of each texture in a `FastCache.cache`
beside the cache. `texture.thumbnail` can read it

```python
thumb = cache[0].thumbnail

# <Thumbnail 32x32, 3 components, discard 5>

print(thumb.dimensions)  # (32, 32)

with open(f"{tex.uuid}.png", "wb") as f:
    f.write(thumb.png())
```

`thumb.pixels` holds the raw rows if you would rather encode them yourself.

refer to the [api.py](src/texture_courier/api.py) file for additional methods and helpers.

## hacking

i use `pip install --editable .` to install texture-courier as an editable
package, which allows the cli to be used like it was installed from pip.

[lltexturecache.h](https://github.com/secondlife/viewer/blob/develop/indra/newview/lltexturecache.h)
is the authoritative implementation of the texture cache, which much of this implementation was
engineered out of.

## prior art

- http://slcacheviewer.com
- https://github.com/jspataro791/PySLCacheDebugger
