Filtress



General Information



Filtress is an image mangling filter language written in golang.


Background


Filtress was inspired by a wonderful project called Interval. Interval generates sound from a small domain specific language. Filtress modifies images based on something similar.

The language opperates similar to interval in that it updates a set of registers/variables with new numerical information and has some basic looping structures. At present the language does not have any conditional logic but does allow nested loops of predetermined length. In the end the language bears some passing similarity to assembly language, but don't let that scare you off: the similarities are mostly skin deep if there at all.


Quick Start


Once Filtress is installed on a system, and a suitable frs file has been created a user may run:

filtress --image=[path to image] [path to filter file]
... and like that a new updated image is created.

At present there are two other valid flags, in addition to --image: -h and -v. -h displays command line help. -v will validate an frs file without an input image.




Documentation



General


Filtress is equipped to filter or otherwise modify and mangle jpg and png images. It will save the output file in the same format as the input file. Filtress is programmed via the filtress domain specific language documented in this documentation.

At a top level the filtress language allows users to get values, store values, do mathmatical opperations on values, and do loops (including nested loops). The language has very few constructs: procedures, opperators, opperands, separators, and comments. There is also, via procedures and opperands, some loose concept of variables.

Filtress keeps track of a number of values including: red, green, blue, alpha, image x axis location, image y axis location, register one, register two, and mode. There are also two constants (values that do not change): width and height.

Filtress only works with positive integers (whole numbers greater than or equal to zero). As a result all math opperations will return integers. Division that would otherwise result in a float or fractional number will be rounded down to a whole number.


Opperators


Opperators are used to update values, and are relative to the value in question. The following table shows the opperators available in filtress:


-- Opperators --
Opperator Notes
+ Addition. Add the value following the plus to the number in question.
- Subtraction. Subtract the value following the minus from the number in question.
* Multiplication. Multiply the value folowing the asterisk by the number in question.
/ Division. Divide the number in question by the value. If the number is zero, the result is zero. If the value is 0, the result is 1. This is a quirk of how math is done in filtress and prevents division by zero errors.
% Remainder division. Divide the number in question by the value and return the remainder as an integer.
= Equals. This sets a number to a new value. If an opperator is omitted from an expression, then equals is used.

Opperands


In Filtress, all numbers are positive integers. Most of the procedures, talked about in the next section, can also be called as variables within other procedures. For example, you can set the color red with the RED procedure. But you can also set the x position to the value or RED.

In addition to integers and variables there are two constants available in any Filtress filter, the iamges width and height. These values can be used as variables, but cannot be changed.

Variables, except the two constants, have a maximum and minimum value. If the maximum is exceeded, the number will loop around to one and count upward. For example if a variables with a maximum of 10 is set to 8 and a filter adds 5 to it, the new value would be three. The opposite also holds true, if a value goes below its minimum, it will come down from the maximum. For those that are interested this is done via remainder opperation: numberGreaterThanMax % max = finalValue or, in the case of coming down from above: max - numberGreaterThanMax % max = finalValue.


-- Variables --
Variable Min Max Notes
WID N/A N/A The images width in pixels. This is a constant and cannot be changed.
HIG N/A N/A The images height in pixels. This is a constant and cannot be changed.
RG1,
RG2
System dependent 32/64 bit integer (platform dependant) Registers for storing values
RED,
GRN,
BLU,
APH
0 255 Red, green, blue, and alpha values. Updated with their respective procedures or the COL procedure (updates all four).
LOX 0 The image's WID value The x axis location.
LOY The image's HIG value The y axis location.

Procedures


Opperators are used to update values, and are relative to the value in question. The following table shows the opperators available in filtress:


-- Procedures --
Procedure Pram Format Notes
COL [opperator]integer:[opperator]integer:[opperator]integer:[opperator]integer Set or modify the RGBA values all in one call.
RG1,
RG2
RG1 [operator]integer Store a number to a register, or with an opperator, update a number in a register.
RED,
GRN,
BLU,
APH
RED [opperator]integer Red, green, blue, and alpha values. Updated with their respective procedures or the COL procedure (updates all four).
LOX LOX [opperator]integer Set or update the x axis location.
LOY LOY [opperator]integer Set or update the y axis location.
LOC LOC [opperator]integer:[opperator]integer Set or update the x and y axis locations
BEG BEG integer Start a loop that loops [integer] number of times. This must be a hard coded value (not a variable). Loops may be nested. A loop goes until an END call is reached.
END END End the current, innermost at the time END is reached, loop.
APY APY
APY [opperator]integer:[opperator]integer
Apply the current filter settings to the image. When called with no paramaters it applies the filter to the current x/y pixel location. When called with paramaters it creates a rectangle using the current position and an offset equal to the x/y provided by the paramaters and applies the filter to everything in that square.
MOD MOD [opperator]integer Switch modes. Mode 0 is average mode, filter colors will be averaged with the colors already present in the image. Mode 1 is hard mode, filter colors will replace the colors already present in the image. More modes are planned, but only these two are currently functional.
GET GET The get procedure fills up the filter (RGB & A values) with the RGB & A values at the current LOC (x and y). This allows a filter to sample parts of an image and move them elsewhere, to get similar or complimentary colors set up, etc.

Putting it all together


A user should write their filter in a file with the suffix .frs. Each procedure should be on its own line. Any lines that begin with a # will be treated by filtress as comments. COmments can be a full line or as the last part of a line (in which anything from # onward until the end of line will be ignored by filtress).

To run filtress, put it on your path and run:

filtress -image=[image filepath] [filter filepath]

To validate a .frs file run:

filtress -v [filter filepath]





Getting Filtress



Filtress is coded in [Go] and can be built from source. No outside libraries are used, just the Go standard library. The source code is available at [https://tildegit.org/sloum/filtress].




Image Examples



Below you will find images produced with filtress, plus the original image. All images are produced with example filters that come in the repo. The first shows a number of different ways an image can be mangled and modified, the second does some color-line overlays to create a geometric effect of sorts, the third does a simple overlay of semi-transparent colored boxes.



Ripley in her space suit, from the film Alien; example a
Generalrated using example_a.frs

Ripley in her space suit, from the film Alien; example b
Generated using example_b.frs

Ripley in her space suit, from the film Alien; example c
Generated using example_c.frs

Ripley in her space suit, from the film Alien; original, no filter
original image



Inspiration



Filtress was inspired by a project called [Interval]. Rather than an image filtering language it is a sound generation language. It is really super cool and you should definitely check it out.