____ __
| __'____| |__ florian & alain's blender
| _| _ | _ | 2009 january - 2011 august
'_' '___._'_____'
!!! Might be incomplete, refer to html file instead
usage: fab function function_parameters
list of functions
~~~~~~~~~~~~~~~~~
File conversion
~~~~~~~~~~~~~~~
fab bmp2rgb in.bmp red.g green.g blue.g //in.bmp can be 1bpp, 4bpp, 8bpp or 24bpp
fab rgb2bmp red.g green.g blue.g out.bmp //if nb_colors is <257 will create 1bpp, 4bpp, 8bpp
fab palette2rgb in.pal in.g red.g green.g blue.g //assign pixels to a color palette
fab textpalette2rgb in.txt in.g red.g green.g blue.g //values in hexadecimal
fab grey2bitplanes nbbitplanes in.g out.xxx // bitplanes in ST mixed format
???fab getmask with .bmp and color as source???
???fab rgb2bitplanes ???
Arithmetic and logic functions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
fab add in1.g in2.g out.g
fab sub in1.g in2.g out.g
fab mul in1.g in2.g out.g
fab div in1.g in2.g out.g // in1.g is divided by in2.g
fab and in1.g in2.g out.g
fab or in1.g in2.g out.g
fab xor in1.g in2.g out.g
fab addI value in.g out.g // same as above but with an <b>I</b>mmediate value
fab subI in.g value out.g
fab rsbI value in.g out.g // rsb=reverse substract
fab mulI factor in.g out.g
fab divI in.g divisor out.g
fab rdvI dividend in.g out.g //rdv=reverse divide
fab andI value in.g out.g
fab orI value in.g out.g
fab xorI value in.g out.g
???fab modulo in1.g in2.g out.g???
???fab moduloI in.g divisor out.g???
Standard image manipulation
~~~~~~~~~~~~~~~~~~~~~~~~~~~
fab negative in.g out.g // BEWARE, pixel=65535-pixel, maybe rsbI 255 is what you want
fab rgb2grey red.g green.g blue.g grey.g // grey:=(red+green+blue)/3
fab rotate90 in.g out.g // clockwise
fab rotate180 in.g out.g
fab rotate270 in.g out.g
fab hmirror in.g out.g // image upside down
fab vmirror in.g out.g
fab addborders left right up down color in.g out.g
fab removeborders left right up down in.g out.g
fab autosetborders width in.g out.g
//check if a border colors exists (there must be at least one border with a
//unique color, and all borders with unique color share the same one) then
//modifies the image so that all borders have the same width (possibly 0).
???fab autosetborders with .bmp and color as source ???
???fab addborderstomultipleof???
???fab copyborderstomultipleof???
Scaling functions
~~~~~~~~~~~~~~~~~
fab sampleup_miller nbiterations in.g out.g //size will be multiplied by 2^nbiterations
//Each iteration goes like this: for every pixel h(x;y) you take h00=h(x+0;y+0); h01=h(x+0;y+1); h10=h(x+1,y+0);
//h11=h(x+1;y+1) and you create 4 points:<br>
//h(x+0.25;y+0.25)=0.75*0.75*h00+0.75*0.25*h01+0.25*0.75*h10+0.25*0.25*h11<br>
//h(x+0.75;y+0.25)=0.25*0.75*h00+0.25*0.25*h01+0.75*0.75*h10+0.75*0.25*h11<br>
//h(x+0.25;y+0.75)=0.75*0.25*h00+0.75*0.75*h01+0.25*0.25*h10+0.25*0.75*h11<br>
//h(x+0.75;y+0.75)=0.25*0.25*h00+0.25*0.75*h01+0.75*0.25*h10+0.75*0.75*h11<br>
//The old pixels are forgotten. The computations are in fact very easy since
//0.75*0.75=9/16, 0.75*0.25=3/16 and 0.25*0.25=1/16.
fab sampledown xratio yratio in.g out.g
fab scaleup xratio yratio in.g out.g
fab scaledown xratio yratio in.g out.g
???fab resize [w=... | h=... | x...] in.g out.g???
???fab resample [w=... | h=... | x...] in.g out.g (bilinear/biquadratic/bicubic... resampling)???
Drawing primitives
~~~~~~~~~~~~~~~~~~
The bottom left corner has coordinates (0;0).
fab disc xcenter ycenter radius color in.g out.g
fab rectangle xleft ybottom xright ytop color in.g out.g
fab rectangle2 xleft ybottom width height color in.g out.g
fab mknoise colormin colormax width height out.g // creates an image filled with noise
???fab gradient???
???fab circular_gradient???
Standard color manipulation
~~~~~~~~~~~~~~~~~~~~~~~~~~~
fab setmincolor newmincolor in.g out.g // substract oldmincolor-newmincolor to every pixel
fab setmaxcolor newmaxcolor in.g out.g // substract oldmaxcolor-newmaxcolor to every pixel
fab allcolorsabove mincolor in.g out.g // if color<mincolor then color=mincolor
fab allcolorsbelow maxcolor in.g out.g // if color>maxcolor then color=maxcolor
fab allcolorsbetween mincolor maxcolor in.g out.g // if color<mincolor then color=mincolor, etc
fab range mincolor maxcolor in.g out.g // = equalise
???fab darkest???
???fab lightest???
???fab couleur_majoritaire???
Color dithering
~~~~~~~~~~~~~~~
The output of all this functions will be a grey image with intensity in [0;nb_colors-1].
You'll often use the <b>range</b> function afterward to put the intensity back in
[0;255]. Also note that you must use the <b>range</b> function to make
nearest neighbourg ordering.
fab ordered2x1 nb_colors in.g out.g //vertical lines
fab ordered1x2 nb_colors in.g out.g //horizontal lines
fab ordered2x2 nb_colors in.g out.g
fab ordered3x3 nb_colors in.g out.g
fab ordered4x4 nb_colors in.g out.g
fab ordered4x4bis nb_colors in.g out.g //diagonals
fab floydsteinberg nb_colors in.g out.g //reduce colors using Floyd-Steinberg algorithm
. 7
3 5 1
fab stucki nb_colors in.g out.g
. 8 4
2 4 8 4 2
1 2 4 2 1
???fab floyd palette.pal red.g green.g blue.g out.g // <65536 couleurs???
???fab ordereddithering + page flip => 5+4=9 niveaux de gris???
???fab verticaldithering/horizontaldithering???<br>
//* There are many ways to find the nearest palette color with varying levels of efficiency
// and quality. A trivial algorithm is to search the color with minimum straight line
// distance in the color cube from the given color.
//* We can alternate between left-to-right and right-to-left (also reflect the diffusion
// matrix), this avoids some kind of artifacts.
Filter function
~~~~~~~~~~~~~~~
fab filter a b c d e f g h i n offset in.g out.g
(a b c)
(d e f) :n + offset
(g h i)
Applies a convolution filter with the surrounding pixel.
You control the effect by giving a 3x3 matrix (a to i) which
is used to multiply the value of the current pixel (in the center)
and its neighbourgs, all this is summed up and divided by n.
Finally we add an offset.
Some usefull filters:<br>
fab filter 0 1 0 1 1 1 0 1 0 5 0 in.g out.g // smooth1<br>
fab filter 1 2 1 2 4 2 1 2 1 16 0 in.g out.g // smooth2<br>
fab filter -1 1 -1 1 1 1 -1 1 -1 1 0 in.g out.g // unsmooth<br>
fab filter -2 -1 0 -1 0 1 0 1 2 1 128 in.g out.g // relief1<br>
fab filter -1 1 -1 1 0 1 -1 1 -1 1 128 in.g out.g // relief2<br>
fab filter 0 -1 0 -1 2 0 0 0 0 1 128 in.g out.g // relief3<br>
fab filter 1 0 1 0 -1 0 1 0 1 3 0 in.g out.g // strange1<br>
fab filter 0 1 0 1 -1 1 0 1 0 3 0 in.g out.g // strange2<br>
fab filter 0 -n 0 -n 4n+1 -n 0 -n 0 1 0 in.g out.g // sharpness<br>
fab filter -n -n -n -n 8n+1 -n -n -n -n 1 0 in.g out.g // sharpness2<br>
fab filter -1 -1 -1 -1 8 -1 -1 -1 -1 1 0 in.g out.g // edge=laplace<br>
fab filter 0 -1 0 -1 4 -1 0 -1 0 1 0 in.g out.g // laplace2<br>
fab filter -1 -1 -1 0 0 0 1 1 1 1 0 in.g out.g // edge2<br>
fab filter -5 0 0 0 0 0 0 0 5 1 0 in.g out.g // edge3<br>
fab filter 0 0 0 0 -1 0 0 0 1 1 0 in.g out.g // emboss<br>
fab filter 2 0 0 0 -1 0 0 0 -1 1 0 in.g out.g // emboss2<br>
fab filter -2 -1 0 -1 1 1 0 1 2 1 0 in.g out.g // repoussage<br>
Cool functions
~~~~~~~~~~~~~~
fab fillwithOs OutRMin OutRMax InRMmin InRMmax Border ClearColor CircleColor in.g out.g
// if you set ClearColor to 0, then you'll have circles inside circles
fab edge size emptycolor edgecolor in.g out.g // creates an edge around non empty pixels
fab explode nbpoints in.g out.g // moves randomly nbpoints points
fab landscape nbiterations in.g out.g
fab mkstrippedtube diameter nbsteps nbstripes col0 col1 out.g
???fab ntsc (Fred): a kind of sampleup_miller with randomness???
???fab voronoi???
NOT YET IMPLEMENTED
~~~~~~~~~~~~~~~~~~~
fab mask in1.g in2.g out.g
fab stretch (0;126;127 deviendra 0;~253;255)
fab tile (peut être émulé avec addborders+or)
fab mkpalette nbcolors red.g green.g blue.g out.pal
!!! Le emboss dans mk_Txtr2.asm=MkTxtr2G est
!!! ldrB r14,[r3],#1 ; r14=pixie up.
!!! ldrB r6,[r4],#1 ; r6=pixie down.
!!! and r14,r14,#&3f
!!! and r6,r6,#&1f
!!! sub r6,r6,r14,lsr #1 ; r6=delta.
!!! addS r6,r6,#middle ; Add the middle constant.
* Pour les valeurs les demander en hexa $01 ou &01... avec un char qui ne
peut pas être dans un nom de fichier?
On peut éviter d'avoir recours à une valeur en créant (random) une image .g
avec la dite valeur, mais c'est pas très propre...
* Pour certaines fonctions (and, or, add...) lorsqu'une des images est plus grande
que l'autre, faire l'opération sur la partie commune (de taille min(w0;w1)*min(h0;h1)
et qui part du bottom left).
* utiliser une clé usb en guise de ramdisk?
* faire les fonctions en wrap par défaut. Si l'utilisateur n'en veut pas il utilisera un
addborders+removeborders