Categorygithub.com/ArtificialLegacy/image-format
repositorypackage
0.0.0-20241115170315-b86853b1eeb9
Repository: https://github.com/artificiallegacy/image-format.git
Documentation: pkg.go.dev

# Packages

No description provided by the author

# README

Some Image Format?

After working with images for awhile when building ImgScal, I've been wanting to make an image format for myself.

While this is not meant to be practical, I did have a few goals when making this:

  1. Be a 1-2 day project.
  2. Have an interesting result.
  3. Learn something.

For #1 this meant keeping it simple, and putting tight design constraints on the project.

For #2 I still wanted this format to be competent, this required picking and optimizing for a niche.

For #3 I decided I wanted to find a way to incorporate run length encoding. While I have understood how it works, this will be a first time implementation.

This format ultimately does well with monochromatic images, or with boolean mask images.

Design Constraints

  • Monochromatic
    • Allows for storing pixel data as 1 byte grayscale, but adding the hue shift in the header allows for more flexibility.
  • No Partial Transparency
    • Allows for 1 bit per pixel, and allows for more significant gains with run length encoding.
    • Having transparency to begin with allows for grayscale data for some pixels to be skipped.

Format

After the 32 byte header, the alpha mask and grayscale data is written using zlib compression. The lengths stored in the header are the lengths before the zlib compression.

Header (32 Bytes)

All multi-byte sections are encoded in little endian.

Tag

0123
'B''L''U''B'

Dimensions

4-56-7
WidthHeight

Data Byte Lengths

8-1112-15
Alpha Data LengthGrayscale Data Length

Hue Information

16
Hue Shift

Encoding Flags

17
Flags
01234567
CompressAlphaMaskExcludeMaskedPixels------

Reserved

18-31
Reserved

Alpha Mask

The alpha mask can be disabled, this is indicated by the length in the header being 0.

The CompressAlphaMask flag determines the mode used below:

Uncompressed

A 0 bit represents a transparent pixel, and a 1 bit represents an opaque pixel.

These are ordered starting from the left of each byte. The least significant bits of the final byte that are unused are 0s.

Compressed

The alpha mask is compressed using run length encoding. Here each byte represents a single boolean, and an amount.

The most significant bit represents the boolean value, and the 7 least significant bits represents the amount. It is arranged this way to make parsing them easier.

boolean := (b & 128) != 0
amount := b & 127

Grayscale Data

The grayscale data can be disabled, this is indicated by the length in the header being 0. If these is no grayscale data, all unmasked pixels are given a value of 0xFF.

The flag ExcludeMaskedPixels determines if transparent pixels should be removed from the grayscale data. In this case this data can only be read/written when the pixel is opaque.

Resulting Image Sizes

Alpha and Grayscale

.png.blub
50.7kB18.8kB

Alpha Only

.png.blub
16.6kB3.1kB