Convert PNG image files to binary for use with AgonLight (TM)

Overview

image2agon

Converts PNG files to binary data for AgonLight (TM) usage.

This document is for version V1.0 of the program.

V1.0 - initial upload

NOTE: The "prepsample.sh" script in the "samples" subdirectory has been renamed to "prepsample_linux.sh", and a new "prepsample_windows.bat" script has been added. The "prepsample_linux.sh" should work on a Mac, as well.

This program converts PNG file data into binary data for use on the AgonLight (TM) retro computer. It reads multiple PNG files, combines their needed color palettes, and outputs palette entries in both text and binary, plus it outputs binary pixel data (palette indexes and also color values). Additionally, the program arranges a simple memory map, and outputs that information, which may be helpful in loading the binary data into RAM.

NOTE: The memory map is presently based on the packed-pixel output, not on the RGB ("widened" colors) output. That may change in the future if needed.

NOTE: Even though the program can emit 1, 2, 3, 4, or 6 bits-per-pixel in the output for Agon, the input PNG files may contain 24-bit RGB or 32-bit RGBA data. The program does not expect the PNG file to be an indexed file (i.e., it should not have its own color palette).

Besides the packed-pixel output, the program also outputs an RGB file, where 3 bytes are used to represent red, green, and blue, and the colors are "widened", as follows:

  • Color component value of 0 is output as 00H.
  • Color component value of 1 is output as 55H.
  • Color component value of 2 is output as AAH.
  • Color component value of 3 is output as FFH.

The output palette will always be a set of 64 (or less) 6-bit colors, meaning that it represents (up to) 63 colors out of a set of 64 possible colors. Color index 0 always represents transparency. That does not prevent using the color black (RGB(0,0,0)) in one of the palette entries, with an index greater than zero. After the program consolidates colors into palette indexes, trailing unused palette indexes may be used at your discretion. The palette map is also written using "widened" colors.

The palette contents are printed to the console (and can be piped to a file), as assembler source text. The palette contents are written to the "PALETTE.BIN" file.

The program can be run in one of 3 ways. If no directory is specified, or if the current directory is specified, the app searches for PNG files in the current directory.

If a list of one or more directories is specified, the app searches for files in those directories. In either case, all files are processed together, where the resulting palette is concerned, so that any of the images can be displayed on the Agon, using the resulting palette, assuming that a proper video mode is used.

NOTE: If you want to display images using different palettes at different times, run the program multiple times, in different directories, with different inputs, to yield separate palette files.

The third way is that you can specify individual PNG files, instead of or along with other directories. This can be quite useful when trying to arrange files with different purposes (such as tiles versus sprites) into a memory map in a custom order.

NOTE: This program does not recursively traverse directories. To process subdirectories beneath the specified directories, run the program multiple times, with different command line arguments.

The command-line format for this program is as follows:

image2agon { [-w width] [-h height] [-b <1|2|3|4|6>] [-n] [ <dir2|png2> | ./] } ...

'-w' and '-width' are synonyms (either one is allowed)
For a PNG file (in a directory or specific), 'width' is given in pixels.

'-h' and '-height' are synonyms
For a PNG file (in a directory or specific), 'height' is given in pixels.

'b' and '-bpp' are synonyms
This may be used to specify the number of bits per pixel in the output binary file, which provides the intended range of color indexes (1: 2 colors, 2: 4 colors, 3: 8 colors, 4: 16 colors, 6: 64 colors). The default value is 6, for 64 colors. As always, color index #0 means transparent, so the actual number of unique colors is one less than the range might imply.

'-n' and '-nooutput' are synonymns
When this option is specified, the output file will not exist, meaning that there will be no output file for the given input image. This option may be used simply to modify the color palette.

'dir1' and 'dir2' are names or paths of directories

'png1' and 'png2' are names or paths of individual PNG files

As an example of changing image size, the "painting.png" file in the "samples"" directory of this project was processed using "-w 320 -h 240" as the command parameters (note the spaces), to yield the BIN file in that same directory. Here is the entire command line:

./image2agon -w 320 -h 240 painting.png >painting.log

There is a sample script called "prepsample_linux.sh" in the "samples" subdirectory. It executes the above command line, as well as the one shown further below.

The output image can be displayed on the Agon using the following steps:

  • TBD
  • TBD
  • TBD

Another example illustrates specifying individual files, rather than directories.

The "individual" sample directory may be processed like this (as shown in the "prepsample_linux.sh" script):

../image2agon \
 -b 1 monochrome.png \
 seq08.png \
 seq16.png \
 seq32.png \
 seq64.png  >individual.log

The resulting log file will contain a RAM memory map, such as the following.

Relative Memory Map

Start  End    Size   Width Height Path/Name
------ ------ ------ ----- ------ ----------------------------------
00000H 00019H     26    13    13  monochrome.png
0001aH 00319H    768     8    96  seq08.png
0031aH 00f19H   3072    16   192  seq16.png
00f1aH 03f19H  12288    32   384  seq32.png
03f1aH 0ff19H  49152    64   768  seq64.png

In the above example, there is one file that is processed with 1 bit-per-pixel color. The PNG file contains pixels that are either white or transparent (there is no black). The resulting palette contains the following lines in it. This implies that any '0' bits in the MONOCHROME.PNG file will show as transparent, and any '1' bits in that file will show as white (color index #1 is RGB(3,3,3)), in the palette.

; Palette entries by index:
;           Agon            Dec Hex:   R G B
;
begin_palette_table:
    DB    000H,000H,000H  ; 000 000H:  0 0 0 (FREE)
    DB    0FFH,0FFH,0FFH  ; 001 001H:  3 3 3
    DB    0FFH,000H,000H  ; 002 002H:  3 0 0
    DB    0FFH,055H,055H  ; 003 003H:  3 1 1
    DB    055H,000H,000H  ; 004 004H:  1 0 0
    DB    0AAH,055H,000H  ; 005 005H:  2 1 0
    DB    0AAH,000H,000H  ; 006 006H:  2 0 0
    DB    055H,055H,000H  ; 007 007H:  1 1 0
    DB    000H,000H,000H  ; 008 008H:  0 0 0
    DB    0AAH,0AAH,000H  ; 009 009H:  2 2 0
    DB    0FFH,000H,055H  ; 010 00aH:  3 0 1
    DB    055H,0AAH,000H  ; 011 00bH:  1 2 0
    DB    0FFH,0AAH,0AAH  ; 012 00cH:  3 2 2
    DB    0AAH,0AAH,055H  ; 013 00dH:  2 2 1
    DB    000H,055H,000H  ; 014 00eH:  0 1 0
    DB    0FFH,055H,0AAH  ; 015 00fH:  3 1 2
    DB    000H,000H,000H  ; 016 010H:  0 0 0 (FREE)
    ...

There are also other example conversions of the 'painting' file, as shell scripts, in sub-directories off of the "samples" directory. If you run a script, it should convert the image file to binary, based on the command line in the script. Some of the output sizes generated by these sample scripts are physically too large to fit inside the RAM, but using the output is not the point; these are just examples to show how the command line affects the output data.

On a per-input (file or directory) basis, you may choose to specify the output width and/or height, in pixels. If neither width nor height is specified, then the width and height are taken from the input files. If one or both dimensions are specified, then the output pixel data (palette map indexes) is sized accordingly, either by padding with transparent pixels, or by cropping (discarding) extra pixels. The input is always centered over the output.

For example, using an input image of 57x64 pixels (width x height), and a command line option "-w 64", the output image will be 64x64 pixels, because the height is taken from the input image file. Specifying "-w 640 -h 480" for the same input image will result in the original, small image being centered in a 640x480 space.

NOTE: This program does not resize an image by stretching or shrinking it, and it does not attempt to optimize the palette, such as converting an image with 152 colors into an image with just 63 colors. The only color conversion that is does is to take 24-bit RGB data, and right-shift each of the color components by 6 (i.e., divide by 64), to yield a 6-bit color from the input 24-bit color. This implies that detail may be lost, if the original image had non-zero values in the least significant 6 bits of any color component of any pixel.

The overall processing is as follows:

  • Obtain a list of all files to process.
  • Read all files.
  • Determine how many unique 6-bit colors are used in ALL files together.
  • Organize a new color palette (index 0 means transparent; indexes 1..63 mean color).
  • Output palette information as binary data.
  • Output palette information as source text.
  • Output image data as binary palette indexes, one index per pixel.
  • Output image data as binary RGB values, using widened colors.
  • Compute and output memory map as text.

NOTE: Regardless of which portion (some or all) of each input file is copied (either in whole or in part) to the output, the entire input image is used to determine the combined palette. The main intent of this program is to create a single palette that can be used for multiple images, tiles, and/or sprites, so that they can all be shown on a single screen.

You might also like...
Rust library for hardware accelerated drawing of 2D shapes, images, and text, with an easy to use API.
Rust library for hardware accelerated drawing of 2D shapes, images, and text, with an easy to use API.

Speedy2D Hardware-accelerated drawing of shapes, images, and text, with an easy to use API. Speedy2D aims to be: The simplest Rust API for creating a

Make and use playgrounds locally.

cargo playground Cargo playground opens a local playground in the editor of your choice. Install You can install it directly using cargo $ cargo insta

A tool to use docker / podman / oci containers with rust

contain-rs A tool to use docker / podman / oci containers with rust TODO improve error types improve error reporting handle std error for child proces

Small, clean, easy to use programming language

Thistle A modern, simplistic multi-paradigm language supporting object-oriented features Hello World! import IO object Main def main(): unit

A collection (eventually) of examples that use some non-beginner things.

nannou examples A collection (eventually) of examples that use some non-beginner things. Right now the only example combines nannou's standard draw AP

Demonstration of how to use the rust object_store crate

Introduction Demonstration of how to use the Rust object_store crate Example

Game development practices with Rust programming language. I want to use different crates for this.

Hazır Oyun Motorlarını Kullanarak Rust Dili Yardımıyla Oyunlar Geliştirmek Rust programlama dilinde oyun geliştirmek için popüler birkaç hazır çatıyı

rust database for you to use and help me make!

Welcome To Rust Database! What is this? this is a database for you to git clone and use in your project! Why should i use it? It is fast and it takes

A dos attack for you to use!

Welcome To Rust Dos attacker! Why should I use it? It has unrivaled speeds because it is built in rust and hand optimized. It also comes with an AI mo

Owner
null
A simpler and 5x faster alternative to HashMap in Rust, which doesn't use hashing and doesn't use heap

At least 5x faster alternative of HashMap, for very small maps. It is also faster than FxHashMap, hashbrown, ArrayMap, and nohash-hasher. The smaller

Yegor Bugayenko 12 Apr 19, 2023
A Rust trait to convert numbers of any type and size to their English representation.

num2english This Rust crate provides the NumberToEnglish trait which can be used to convert any* number to its string representation in English. It us

Travis A. Wagner 6 Mar 8, 2023
Tool to convert variable and function names in C/C++ source code to snake_case

FixNameCase Tool to convert variable and function names in C/C++ source code to snake_case. Hidden files and files listed in .gitignore are untouched.

AgriConnect 4 May 25, 2023
Rust on ESP32 STD "Hello, World" app. A "Hello, world!" STD binary crate for the ESP32[XX] and ESP-IDF.

Rust on ESP32 STD "Hello, World" app A "Hello, world!" STD binary crate for the ESP32[XX] and ESP-IDF. This is the crate you get when running cargo ne

Ivan Markov 138 Jan 1, 2023
CBOR: Concise Binary Object Representation

CBOR 0x(4+4)9 0x49 “The Concise Binary Object Representation (CBOR) is a data format whose design goals include the possibility of extremely small cod

quininer 37 Dec 27, 2022
Serialize & deserialize device tree binary using serde

serde_device_tree Use serde framework to deserialize Device Tree Blob binary files; no_std compatible. Use this library Run example: cargo run --examp

Luo Jia 20 Aug 20, 2022
Base Garry's Mod binary module (Rust)

gmod-module-base-rs A base for developing Garry's Mod binary modules in Rust. Getting Started Install Rust Download or git clone this repository Open

William 7 Jul 30, 2022
Safe Rust bindings to the DynamoRIO dynamic binary instrumentation framework.

Introduction The dynamorio-rs crate provides safe Rust bindings to the DynamoRIO dynamic binary instrumentation framework, essentially allowing you to

S.J.R. van Schaik 17 Nov 21, 2022
This crate allows to generate a flat binary with the memory representation of an ELF.

flatelf Library This crate allows to generate a flat binary with the memory representation of an ELF. It also allows to generate a FLATELF with the fo

Roi Martin 3 Sep 29, 2022
It's a library AND a binary, but at what cost?

aria-of-borrow It's a library AND a binary, but at what cost? This is a simple toy project that demonstrates the various failure modes of trying to ma

Aria Beingessner 5 Apr 2, 2024