PHGTK                                           (dgw v1.10 14th September 2017)
=====

A collection of QL SuperBASIC functions to produce and manipulate hi-colour
GD2 PIC files (modes 16, 32 and 33).

Keyword summary:

  FJPEG  MJPEG         Convert JPEG to PIC file
  FGIF   MGIF          Convert GIF to PIC file
  FPNG   MPNG          Convert PNG to PIC file

  FSCR   MSCR          Convert QL mode 4 screen area dumps to PIC
  FSCR8  MSCR8         Convert QL mode 8 screen area dumps to PIC
  FZXD   MZXD          Convert ZX Spectrum whole screen dump to PIC
  FPIC_QL              Convert mode 4/8 PIC to GD2 PIC

  WDW_XLIM  WDW_YLIM   Return window limits
  MODE_RGB%            Convert RGB to current mode native value
  MODE16%              Convert RGB to mode 16 native value
  MODE32%  MODE32R%    Convert RGB to mode 32 native value
  MODE33%              Convert RGB to mode 33 native value

  FPIC_SAVE            Save window area to PIC file
  FPIC_LOAD            Load PIC file into window
  FPIC_SCALE           Scale PIC image
  FPIC_TILE            Tile PIC image into larger area
  FPIC_TRANSFORM       Manipulate orientation of PIC image
  FPIC_FILTER          Perform filter on PIC image
  FPIC_BRIGHT          Alter overall brightness of PIC image
  FPIC_CONTRAST        Alter overall contrast of PIC image
  FPIC_TINT            Alter tint of RGB levels
  FPIC_SHADE           Alter shade of RGB levels
  FPIC_RGBMATRIX       Perform complex colour space changes
  FPIC_CROP            Reduce image size
  FPIC_BORDER          Add border or replicate (pre-filter)
  FPIC_FILL            Create blank canvas (for insert)
  FPIC_INSERT          Insert PIC image into another
  FPIC_SIZE            Return size of PIC image
  FPIC_MODE            Return mode of PIC image


Introduce new functions with:

  LRESPR phgtk_bin

(an internal Config block allows option not to overwrite output files)

If you wish to include the functions in your QLiberated program use:

   REMark $$asmb=phgtk_bin,0,10

In the following descriptions square brackets [] define optional parameter.

File names do not need to be with quotes. If display mode is omitted (or 0)
then current mode is assumed.


Convert JPEG to PIC file
========================

This function only supports JPEG file types known as DCT Baseline Sequential
(most common type).  No dithering is performed. JPEG decodes to 24 bit RGB.

   error% = FJPEG(inputfile$,outputfile$,dmode%[,addr])

returns 0  decoding succesful
       <0  QDOS errors (use TK2 REPORT procedure to get message)
      -19 'not implemented' i.e. Progressive JPEG image type
      -22 'unknown message' for bad JPEG file contents

dmode% mode 16/32/33/64/65, but adding the following values can modify output:

  +256       skip every third line (4:3 to 2:1 scaling)
  +512       output in sepia tones
  +512+1024  output in black & white

(mode 64 is raw 24bit RGB, mode 65 is YCbCr)

addr is optional parameter to define alternative 3 bit RGB table for mode 16.

To find potential image size or dimensions use:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  filesize = MJPEG(inputfile$,dmode%)
  IF filesize<0 THEN REPORT filesize : STOP
   
If you give dmode% as -1 it will return the X and Y pixel size of the image:

  p = MJPEG(inputfile$,-1)
  IF p<0 THEN REPORT p : STOP
  X% = p DIV 65536
  Y% = p MOD 65536


Convert GIF to PIC file
=======================

This function supports all known GIF formats (GIF87 and GIF89). Converts
Sequential, Interlaced and multi-frame animated images. No dithering is
performed. GIF decodes to 2 to 256 indexed colours only.

   error% = FGIF(inputfile$,outputfile$,dmode%[,frame%])

returns 0  decoding succesful
       <0  are QDOS errors (use TK2 REPORT procedure to get message)
      -19 'not implemented' for interlaced image in animation mode
      -22 'unknown message' for bad/incomplete GIF file

dmode% is mode 16/32/33, but adding the following values can modify output:

  +256       skip every third line (4:3 to 2:1 scaling)
  +512       output using 'animation mode'
  +1024      force black background to be white (when transparency used)

Non-animation mode (default) uses minimal memory and is usually the fastest.
It outputs raw decoded frame data and takes no account of previous frames.
This may render unexpected results (weird looking output, small frames).

Animation mode decodes whole image in memory before output. It allows frames
to be compounded and will always produce proper PIC images (of same size).
It accounts for partial frame updates, background colour, transparency and
different inter-frame disposal methods. (Animation mode does not deal with
interlaced images, if you get -19 error just revert to normal mode).

As with other GIF decoders (ie. GIFSICLE -careful option) it is left to user
to decide what output option to use.

On some GIF's a noticeable outline appears because it is supposed to match
background (shown through transparent areas). Using +1024 you can force
default black to white.

Multi-frame images (non-animation mode)
~~~~~~~~~~~~~~~~~~
Normally just the first frame is decoded to the PIC file. For multi-frame
images you can specify which frame you want (numbering starts at frame 0).

If you wish to decode all frames in an image, use something like this:

100 n%=0
110 REPeat loop
120   err% = FGIF('flp1_anim_gif','ram1_frame'&n%&'_pic',32,n%)
130   IF err% THEN EXIT loop : ELSE n%=n%+1
150 END REPeat loop
160 IF err%<>-10 THEN REPORT#1;err%

If you attempt to get a non-existent frame you'll get EOF (-10) returned.

The method used is to simply skip over all the preceeding frames data blocks
until the desired frame is found, and then just output frame as originally
encoded to a single PIC file.

As mentioned, this may render unexpected results on some multi-frame GIF files
since the frames may depend on previous frames contents. But for GIF files
which use full-frame animation this mode is quickest.

Multi-frame images (animation mode)
~~~~~~~~~~~~~~~~~~
By addind +512 to dmode% you can request output image is compounded version
from previous frames. This accounts for partial frame updates, transparency etc.

  frame% = 4
  err% = FGIF('flp1_anim_gif','ram1_frame_pic',32+512,frame%)

You could use the same Basic listing above to output each frame individually
(slow) but animation-mode offers a quick 'all-frames' output option.

If you give frame% as -1 the function will output all the frames and return the
number of frames found:

  total% = FGIF('flp_anim_gif','ram1_frame',32+512,-1)

The filenames will each have a four digit hex number appended. Hex was chosen
because it is quickest to form string from Basic:

  FOR n% = 0 TO total%-1
    PRINT 'ram1_frame'&HEX$(n%,16)
  END FOR n%

Beware that this option can potenially produce massive output.

In animation mode the PIC file header spare byte has been used to store the
frame delay parameter:

  0      no delay or unset (single frame files)
  1-254  QL ticks 1/50ths second (no user input)
  255    user input required (ie. any key/mouse button)

To find potential image size or dimensions use:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  filesize = MGIF(inputfile$,dmode%)
  IF filesize<0 THEN REPORT filesize : STOP

Give dmode% as -1 to return the maximum X and Y size of the image:

  p = MGIF(inputfile$,-1)
  IF p<0 THEN REPORT p : STOP
  X% = p DIV 65536
  Y% = p MOD 65536

To return the number of frames found in a GIF file also give frame% as -1:

  frames% = MGIF(inputfile$,-1,-1)

Therefore to quickly find potential output filing requirements use:

  storage = MGIF(inputfile$,dmode%) * MGIF(inputfile$,-1,-1)


Convert PNG to PIC file
=======================

This function supports all standard PNG colour modes :

  1/2/4/8 bit Indexed RGB
  1/2/4/8/16 bit Greyscale
  8/16 bit Greyscale with 8/16 bit Alpha
  8/16 bit RGB
  8/16 bit RGB with 8/16 bit Alpha

(Alpha is opacity/transparency, same bit depth as colour)

Interlaced is not supported, since it would require rendering the full image
in memory (Adam-7 interlacing uses dispersed pixels, not by line like GIF). 

Opacity/background is ignored in this version. This may cause some images to
have an odd appearence since it is often used in unexpected ways (eg. to
smooth edges and as window colour masks). No dithering is performed.

   error% = FPNG(inputfile$,outputfile$,dmode%)

returns 0  decoding succesful
       <0  are QDOS errors (use TK2 REPORT procedure to get message)
      -19 'not implemented' for unsupported interlaced PNG images
      -22 'unknown message' for bad PNG file contents

dmode% is mode 16/32/33, but adding the following value can modify output:

     +256  skip every third line (4:3 to 2:1 scaling)

To find potential image size or dimensions use:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  filesize = MPNG(inputfile$,dmode%)
  IF filesize<0 THEN REPORT filesize : STOP

If you give dmode% as -1 it will return the X and Y size of the image:

  p = MPNG(inputfile$,-1)
  IF p<0 THEN REPORT p : STOP
  X% = p DIV 65536
  Y% = p MOD 65536


Convert QL mode 4/8 screen dumps to PIC
=======================================

FSCR converts mode 4 screen dumps to PIC files of modes 4/16/32/33:

   error%=FSCR(input$,output$,dmode%[,X%])

FSCR8 converts mode 8 screen dumps to PIC files modes 8/16/32/33:

   error%=FSCR8(input$,output$,dmode%[,X%])

For complete screen dumps you can usually omit the X% parameter: the X/Y size
can be calculated from the filesize. But if you get -4 (out of range) returned
or the PIC file doesn't look correct then you need to try giving suitable
values for X% (1 to 16382).

If X% is given then an attempt is always made to render an image, regardless of
the possibility of producing an incomplete last line (padded out as required).

Y% is then returned as a positive number:

   Y% = FSCR(input$,output$,dmode%,X%)

By judicious use of X% you should be able to render any partial screen dump.
(Note: X% for mode 8 is real value!, ie. usually half that of mode 4)

For mode 4 there are 8 pixels per Word (4 for mode 8). No Words can be split
across lines, so if you over/under do it the image will get skewed.

If the value of X% is not a multiple of 8 (or 4 for mode 8) then any unused
pixels in the last Word in each line are not used in the output PIC image.
(Thus you could use this option to crop right hand side of upto 7/3 pixels.)

For dmode% 16/32/33 you can add two flags:

   dmode% +256   Reduce RGB levels to 75%. If the input is mode 8 then any QL
                 FLASHing pixels are made 100% RGB as a form of highlighting
                 (only ink colour is brightened, not paper)

   dmode% +512   Normally FSCR8 outputs double width pixels to maintain the
                 aspect ratio in output of modes 16/32/33. If you add this
                 flag then the pixels are forced to be single width.
                 (Note: without this flag set the output from FSCR8 will
                 have width twice that of input; X%*2)

Output modes 4/8 are just provided as a convenient way of converting screen
dumps to PIC files. The output lines will be rounded to a multiple of long
words if necessary. Any unused pixels will be blank, and out of range of the
X parameter in the PIC header. Since the flags have no meaning for mode 4/8
output they are rejected (-15, bad parameter).

Possible errors returned from functions:

       <0  are QDOS errors (use TK2 REPORT procedure to get message)
       -4 'out of range' in identifying screen size (try giving X%)
      -19  unsupported PIC mode or PIC header contents
      -22  'unknown message' bad PIC file header info or file size wrong


Convert ZX screen dumps to PIC
==============================

FZXD converts ZX screen dumps (6912 bytes) to PIC files of modes 8/16/32/33:

   error%=FZXD(input$,output$,dmode%)

The output size is always 256x192. Colour levels are 75% RGB normal and 100%
for BRIGHT pixels (this matches shading on ZX emulators).

For mode 8 output colour levels are fixed at 100% (no BRIGHT). ZX FLASH is
ignored since QL flashing is completely different and would produce poor
results.

Any flags added to dmode% are rejected (-15, bad parameter).


Convert mode 4/8 PIC to GD2 PIC
===============================

FPIC_QL converts mode 4/8 PIC files to PIC files of modes 16/32/33:

   error%=FPIC_QL(input$,output$,dmode%[,array%])

If array% is not given then normal colour mode conversion levels are used.
The same dmode% flags (as above for FSCR) apply to output.

If array% is given then it allows recolouring the QL 4/8 colour palettes to
new mode colours. In this case the +256 dmode% flag is ignored.

The array% parameter must be an integer array of 8 items, ie. DIM cols%(7)

The array indexes correspond to the 0-7 colours. The values given are the
native mode values. MODExx% functions described below make conversion from
discrete RGB values to native mode colours easier.


Image dimensions and file sizes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

  filesize = MSCR(input$,dmode%)
  filesize = MSCR8(input$,dmode%)
  filesize = MZXD(input$,dmode%)

If you give dmode% as -1 it will return the X and Y pixel size of the image:

  p = MSCR(input$,-1)
  IF p<0 THEN REPORT p : STOP
  X% = p DIV 65536
  Y% = p MOD 65536

If the value returned is -4 (out of range) then it means the screen dump is
a partial size (not 2:1 or 4:3 full image) and thus cannot be derived.


Return window limits
====================

   xsize% = WDW_XLIM [(#ch%)]
   ysize% = WDW_YLIM [(#ch%)]

Return specific window pixel size (less border), default channel #1.

The system Trap which returns this information has unfortunate side-effect
of performing any pending newline. Therefore if last print position in
window was the last line, pending a newline, it will cause window scroll.


Native colour functions
=======================

To convert RGB values to current display GD2 native colour value:

   native_colour% = MODE_RGB%(r%,g%,b%)

or more specifically for GD2 mode:

   native_colour% = MODE16%(r%,g%,b%)
   native_colour% = MODE32%(r%,g%,b%) : real_colour = MODE32R%(r%,g%,b%)
   native_colour% = MODE33%(r%,g%,b%)

These functions return values suitable for use with PAPER/INK etc, when the
COLOUR_NATIVE command is in force. The values returned have exactly the same
effect as if the RGB parameters had been used for COLOUR_24 values.

To concur with SMSQ, MODE16% returns a value which gives better colour spread
for use with PAPER/INK, rather than the scheme used for image dithering (which
uses smallest sum of squares of distances from colour combinations available).

MODE32R% returns little-endian version which is the real pixel word value (ie.
value used in PIC files and WSA/screen dumps).


PIC manipulation functions
++++++++++++++++++++++++++

Possible errors returned from functions:

       <0  are QDOS errors (use TK2 REPORT procedure to get message)
       -4  'out of range', scaling algorithm produced unexpected result
           or matrix parameters for FPIC_FILTER produce excessive sum
      -19  unsupported or mismatched PIC mode
      -22  'unknown message' bad PIC file header info or file size wrong


Load/Save PIC file into SuperBASIC window
=========================================

  error% = FPIC_LOAD(#ch%,input$ [,wx%,wy% [,px%,py%,px_size%,py_size%] ] )

  error% = FPIC_SAVE(#ch%,output$ [,wx%,wy%,wx_size%,wy_size% [,px%,py%] ] )

The parameter ch% must be a SuperBASIC window channel number, preceded by #
(else -6 'invalid channel ID or -12, 'bad device name' is returned). You may
omit the #ch% parameter and it will default to channel #1.

Filename input$/output$ must be a PIC file of same mode as current display
mode (else -19, 'not implemented' returned).  Supports modes 4/8/16/32/33.

 wx%,wy% is the top lefthand window pixel coordinate
 wx_size%,wy_size% is the size of the window area for the operation

 px%,py% is the top lefthand pixel position within the PIC file
 px_size%,py_size% is the size of the PIC area for the operation

If all the parameters between square brackets [ ] are omitted then the whole
PIC file image is loaded/saved at the window at pixel position 0,0.

If the parameters between double square brackets [[ ]] are omitted then the
whole PIC file image is loaded/saved at window pixel position wx%,wy%.  For
the save operation wx_size%,wy_size% specifies area size.

If all the parameters are supplied then only that part of the area given is
loaded/saved.

In all cases; if the parameters are incorrect for either the window or PIC
image dimensions, then -4, 'out of range' is returned.

The system traps which are used for window area save/restore do not support
ALPHA_BLEND. If you wish to perform such, try:

  ERT FPIC_SAVE(window_pic)
  ERT FPIC_INSERT(ghost_pic,window_pic,x%,y%,alpha%)
  ERT FPIC_LOAD(window_pic)


Scaling
=======
The output scaling can be controlled by the way the parameters are given:

   error% = FPIC_SCALE(input$,output$,X%,Y%[,bgnd%])    or
   error% = FPIC_SCALE(input$,output$,X%,Y%[r%,g%,b%])

Background colour can be given as single native value or RGB values.

Extreme down-scaling can produce ugly artefacts so you may need to use a
smoothing filter first (see FPIC_FILTER).

Both +X% and +Y%
~~~~~~~~~~~~~~~~
If bgnd% is not given then the input PIC file is scaled to fill output,
regardless of the aspect ratio.

If bgnd% is given then the aspect ratio of the input file is maintained. The
input is scaled to to fit within the output. Whatever area remains (top/bottom
or left/right) will be filled with the bgnd% colour. The image is centered.

Both -X% or -Y%
~~~~~~~~~~~~~~~
If bgnd% is not given then the input PIC file is scaled to fill output,
regardless of the aspect ratio.

If bgnd% is given then the aspect ratio of the input file is maintained. If the
input size is smaller than the output then the image is not scaled. The unused
area is filled in with the bgnd% colour.  If input is greater than output then
the image is down scaled and bgnd% filled as necessary.

Center unscaled image in sepia backgound with output size 1024x768:

   error% = FPIC_SCALE(input$,output$,-1024,-768,$64,$3B,$0F)

Scale using X%,0 return Y%
~~~~~~~~~~~~~~~~~~~~~~~~~~
If bgnd% is given then it is ignored.

If Y% is given as 0 then the output is scaled according to the aspect ratio of
the input and the value given in X%. Function returns Y% as a positive number.

   Y% = FPIC_SCALE(input$,output$,1024,0)

PIC file output is 1024 by Y% pixels in size. (If -Y% then it is system error.)

Other scalings
~~~~~~~~~~~~~~
To facilitate other scalings that maintain aspect ratio may require X% or Y% be
changed. Although you could work this out from reading input PIC file header
X/Y size and doing the math, another function has been provided to save you the
hard work:

   error% = FPIC_SIZE(input$,X%,Y%)         or
   error% = FPIC_SIZE(input$,X%,Y%,zoom%)

where X%,Y%    call and return parameters (must be set integer variables)
      zoom%    percentage increase or decrease (100 = unchanged)

The input$ PIC file header X/Y size is read. A calculation is then made based
on parameters given and X%/Y% are returned with suitable values to call the
FPIC_SCALE function with.

So if you want to scale image to be within 1024x768 (but still maintain aspect
ratio):

   X% = 1024 : Y% = 768
   error% = FPIC_SIZE(input$,X%,Y%)
   error% = FPIC_SCALE(input$,output$,X%,Y%)
   PRINT 'Image size ';X%,Y%

(If both X% and Y% are given as 0 then original dimensions are returned.)

If you want to scale image by 25% :

   X% = ? : Y% = ? : REMark ? = assigned values dont care
   error% = FPIC_SIZE(input$,X%,Y%,125)
   error% = FPIC_SCALE(input$,output$,X%,Y%)
   PRINT 'Image size ';X%,Y%


Tiling
======

   error% = FPIC_TILE(input$,output$,X%,Y%)

The input PIC file is tiled to fill the output file. If input is bigger than
the output then only top left of input is used. If a multiple of input does not
fill output width/heigth then partial input is used in output (right and/or
bottom). 

   error% = FPIC_TILE(input$,output$,1024,768)

Similar to scaling, if you give Y as zero the function returns its value.

   Y% = FPIC_TILE(input$,output$,1024,0)

PIC file output is 1024 by Y% pixels in size (ie. output maintains aspect
ratio with input; tiling is in same proportion).


Transformation
==============

   error% = FPIC_TRANSFORM(input$,output$,type%,param%)

The input PIC file is transformed to output based on type% :

   0  reduce resolution to param% size pixel blocks
   1  flip horizontally
   2  flip vertically
   3  turn upside down (180 degrees)
   4  clockwise by 90 degrees (right)
   5  anti-clockwise 90 degrees (left)
   6  flip top left to bottom right (effectively 1 and 4)
   7  flip top right to bottom left (effectively 1 and 5)

   (For type% 4 to 7 the output width/height will be the
    opposite of the input width/height.)

For type% 0 the param% specifies the size of the pixel blocks (X/Y).

If param% is a negative value then the output is opened overwrite (OPEN_OVER),
rather than new (OPEN_NEW).

For type% 1 to 7 the param% has no real value other than sign. Since these
transformations don't lose data you can use same input/output file name.
(This is only fatal to image data if a system filing error occurs.)

Hints for type% 0 : Images with framed borders may introduce false artefacts
into output (use FPIC_CROP beforehand). For mode 16 PIC files type% 0 is only
best used on images that have not been dithered.

Try transform type% 0 (reduce resolution) followed by FPIC_FILTER 4 (raised)
for a Roman tile effect.


Box filtering
=============

   error% = FPIC_FILTER(input$,output$,array%)    or
   error% = FPIC_FILTER(input$,output$,filter%)

The input PIC file is subjected to a convolution matrix. Useful for image
blurring, sharpening, embossing, and edge detection. 

Although the filters only work on GD2 PIC files, original mode 4/8 images
converted to GD2 modes (using FSCR/FSCR8) can be enhanced using suitable
smoothing filters (conversely sharpening filters have little effect).

You can either supply your own matrix (array% option) or use one the built-in
matrices (filter% option).

The array must be an integer array of size 3x3 else it will be rejected. The
name is unimportant, as long as it is DIMimensioned <name>%(2,2). 

Otherwise supply filter% as a simple integer:

   Standard effects:

    0  No filter (test)     [   0,  0,  0,  0,  1,  0,  0,  0,  0 ]
    1  Smoothing            [   1,  1,  1,  1,  2,  1,  1,  1,  1 ]
    2  Sharpen              [   0, -1,  0, -1,  5, -1,  0, -1,  0 ]
    3  Sharper              [  -1, -1, -1, -1,  9, -1, -1, -1, -1 ]
    4  Raised               [   0,  0, -2,  0,  2,  0,  1,  0,  0 ]
    5  Motion blur          [   0,  0,  1,  0,  0,  0,  1,  0,  0 ]
    6  Box blur             [   1,  1,  1,  1,  1,  1,  1,  1,  1 ]
    7  Gaussian blur        [   1,  2,  1,  2,  4,  2,  1,  2,  1 ]
    8  Edge detection       [  -1, -1, -1, -1,  8, -1, -1, -1, -1 ]

   Misc effects:

    9  Coarse               [   6, -2, -9, 14,  0, -5, 13, -4,-12 ]
   10  Medium               [  -6,  2,-14,  3, 19, -5,  4,  7, -9 ]
   11  Feint                [  -1,  3, -3, -3,-10,  9, 12,-11,  3 ]
   12  Feint edge           [  -8,  4, -8,  8,  4,  4,-10,1 0, -5 ]
   13  Feint coloured       [ -12, 11,-12,-12, 53, -9, -8, -3, -8 ] 

   Figures in [..] are equivalent array% data.

   The value for filter% is unrestricted so you can permanently add your
   own data to the end of the list. Just attach 9 integer words for each
   additional matrix to the end of the phgtk_bin file.

See Wiki page 'Kernel (image processing)' and other web pages for info on
image box filtering.

Basically the centre of a 3x3 matrix is the subject pixel. Each of its
neighbouring pixels contribute to the result based on their values in the
matrix. The value at each position is divided by the sum of the matrix.

  So this achieves nothing   0  0  0     sum is 0+0+0+0+1+0+0+0+0 = 1
                             0  1  0     neighbours contribute nothing,
                             0  0  0     centre pixel contributes 1/1

  This achieves smoothing    1  1  1     all neighbours contribute 1/10
  (ie. same as filter% 1)    1  2  1     of their value and the centre
                             1  1  1     itself contributes 2/10

The matrix values can range from -32768 to 32767 with the limit that total
matrix sum must also not exceed same range.

The matrix transverses the input image from left-right, top-bottom. The output
of the matrix is plotted as the centre pixel in the output image. The edge
pixels are not processed and are just copied to output.

Images with framed borders may introduce false artefacts into image (use
FPIC_CROP first to remove border). Conversely for some filters the unchanged
edges stand out; use FPIC_BORDER to add duplicate edge, filter, then FPIC_CROP
to reduce back to original size.


Brightness
==========

   error% = FPIC_BRIGHT(input$,output$,bright%)    or
   error% = FPIC_BRIGHT(input$,output$,r%,g%,b%)

Alter level of brightness or RGB levels (-255 to +255). Depending on mode,
small values will have no affect.

Effectively RGB = RGB + bright%  (or indivdually for r%/,g%,b%)

Contrast
========

    error% = FPIC_CONTRAST(input$,output$,contrast%)

Alter level of contrast (-255 to +255).

Effectively RGB = (RGB - 128) * F + 128

where F = ( 259 * (contrast% + 255) ) / (255 * (259 - contrast%) )

Tint
====

   error% = FPIC_TINT(input$,output$,tint%)    or
   error% = FPIC_TINT(input$,output$,r_tint%,g_tint%,b_tint%)

tint% value is percentage (0 to 100). A tint is produced by lightening a hue.

Effectively RGB = RGB + (255 - RGB) * tint% / 100

Shade
=====

   error% = FPIC_SHADE(input$,output$,shade%)    or
   error% = FPIC_SHADE(input$,output$,r_shade%,g_shade%,b_shade%)

shade% value is percentage (0 to 100). A shade is produced by darkening a hue.

Effectivey RGB = RGB * (100 - shade%) / 100


Other RGB colour space changes
==============================

   error% = FPIC_RGBMATRIX(input$,output$,array%)

array% must be an integer array of size 3x3 else it will be rejected. The name
is unimportant, as long as it is DIMimensioned <name>%(2,2). 

The matrix is applied to RGB values thus:

  R_out = R_in * array%(0,0) + G_in * array%(0,1) + B_in * array%(0,2)
  G_out = R_in * array%(1,0) + G_in * array%(1,1) + B_in * array%(1,2)
  B_out = R_in * array%(2,0) + G_in * array%(2,1) + B_in * array%(2,2)

The array elements are treated as floats which have been muliplied by 16384 to
allow them to be passed as integers (range -32768 to +32767).

Although this only performs one matrix operation it still allows some adequate
colour space changes. See Hue_bas as an example (if you come up with better
conversion, or others, please share info).


Cropping
========

   error% = FPIC_CROP(input$,output$,X_org%,Y_org%,X_size%,Y_size%)

If parameters exceed input image then out-of-range is returned and no output
is produced. A variation is to just crop edges:

   error% = FPIC_CROP(input$,output$,X_cut%,Y%_cut%)

X_cut% pixels are trimmed from both left/right, Y_cut% from top/bottom.


Borders
=======

   error% = FPIC_BORDER(input$,output$,size%,bgnd%)      or
   error% = FPIC_BORDER(input$,output$,size%,r%,g%,b%)

The output has a border of size% pixels added of colour bgnd% (or r%,g%,b%).

If no bgnd% is given then the edge pixels are replicated (for FPIC_FILTER).

You can add fancy borders quite easily (even if a bit slow), try:

  ERT FPIC_BORDER(ram1_image_pic,ram1_fancy_pic,1,-1)
  FOR n%=250 to 0 STEP -5
    ERT FPIC_BORDER(ram1_fancy_pic,ram1_fancy_pic,1,n%,n%,n%)
  END FOR n%
  EX Photon,ram1_fancy_pic

You'll need to Config phgtk_bin for 'Overwrite output files'. (The ERT command
is part of SMSQ, it only stops and reports if a negative error is returned.)


Fill
====

   error% = FPIC_FILL(output$,X%,Y%,bgnd%)      or
   error% = FPIC_FILL(output$,X%,Y%,r%,g%,b%)

   error% = FPIC_FILL(output$,dmode%,X%,Y%,bgnd%)      or
   error% = FPIC_FILL(output$,dmode%,X%,Y%,r%,g%,b%)

Simple function to create PIC file of size X%,Y% in mode% 16/32/33 filled with
pixels of colour bgnd% (or r%,b%,g%). Suitable as blank canvas for use with
FPIC_INSERT.


Insertion
=========

   error% = FPIC_INSERT(input$,output$,X_org%,Y_org%[,alpha%])

The input PIC image is inserted into output PIC file. The output PIC file must
exist and be of appropriate size for operation. If not, 'out of range' (-4) is
returned and the output is unchanged.

For input PIC files of mode 16/32/33: The output mode must match (else -19,
'not implemented'). If alpha% is supplied then the input pixels are combined
with output pixels based on value: Range 1 (transparent) to 255 (opaque). If
alpha% is not supplied then default of 255 is used.

For input PIC file of mode 66 (RGBA): Output PIC must be mode 16/32/33. If
alpha% is given then it is ignored, the alpha values for each pixel are used.


Mode/size of PIC file
=====================

   mode% = FPIC_MODE(input$)

Returns mode of PIC file (or -22 'unknown message' if not a PIC file)

To find image size:

   X% = 0 : Y% = 0 : REMark both must be assigned 0
   error% = FPIC_SIZE(input$,X%,Y%)
   PRINT 'Image size ';X%,Y%


Versions  (dd/mm/yy)
========

v1.00   01/03/17   Initial release
v1.10   19/09/17   Added FPIC_CONTRAST
