/* XPaint-image */
#include <Xpaint.h>

/*
 * The key-word "ImageCreate" is reserved for user-defined image routines;
 *
 * Pixels are unsigned char arrays p[0]=red, p[1]=green, p[2]=blue
 * (each value should be in the range 0..255)
 *
 * In the example below,  ip = input pixel,  op = output pixel 
 * The procedure below opens a list of images from files on the disk
 * and creates a new image produced as a combination of them. 
 * The "gluing" procedure is to be specified by users.
 *
 * The Merge procedure below is given as an example - it allows rescaling and
 * rotating images, as well as performing alpha blending
 *
 * The keyword 'LXP_files' is also reserved. The corresponding list of files
 * should end with NULL. File names should not contain the character \" 
 */

static char *LXP_files[] = {
  "cat.jpg",
  "bird.png",
  NULL
};

/*  
 *  Merging procedure for full color images (3 bytes per pixel), where
 *  alpha = blending parameter 0 ... 255
 *  r = rescaling factor, theta = rotation angle (degrees)
 *  (up, vp) = position of top left corner of input relative to output
 */

static void Merge(Image *output, Image *input, int alpha,
           double r, double theta, double up, double vp)
{
    unsigned char *ip, *op;
    int i, x, y, u, v;
    double a, b; 

    if (!output) return;
    theta = theta * M_PI/ 180.0;
    a = cos(theta) / r; b = sin(theta) / r;
    r = a * up - b * vp; theta = b * up + a * vp; up = r; vp = theta;
    
    for (y = 0; y < output->height; y++) {
        for (x = 0; x < output->width; x++) {
            op = ImagePixel(output, x, y);
            u = (int)(a * x - b * y - up + 0.5);
            v = (int)(b * x + a * y - vp + 0.5);            
            if (u >= 0 && u < input->width && v >= 0 && v < input->height) {
                ip = ImagePixel(input, u, v);
                for (i=0; i<=2; i++)
                    op[i] = ((255-alpha)*op[i]+alpha*ip[i])/255;
            }
        }
    }    
}  

Image * ImageCreate()
{
    Image **img, *output;
    int n; /* number of images is returned */
    
    /* Open files */
    img = ImagesFromList(LXP_files, &n);
    if (!img || !img[0]) return NULL;

    output = ImageDup(img[0]);
    Merge(output, img[1], 140, 1.2, -15.0, 45, 100);

    /* Remove images from memory since we are done with them */
    DeleteListedImages(img);

    return output;
}

