/*
 *  libpipi       Proper image processing implementation library
 *  Copyright (c) 2004-2008 Sam Hocevar <sam@zoy.org>
 *                All Rights Reserved
 *
 *  $Id$
 *
 *  This library is free software. It comes without any warranty, to
 *  the extent permitted by applicable law. You can redistribute it
 *  and/or modify it under the terms of the Do What The Fuck You Want
 *  To Public License, Version 2, as published by Sam Hocevar. See
 *  http://sam.zoy.org/wtfpl/COPYING for more details.
 */

/*
 * stock.c: stock images
 */

#include "config.h"
#include "common.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "pipi.h"
#include "pipi_internals.h"

pipi_image_t *pipi_load_stock(char const *name)
{
    pipi_image_t *ret;
    pipi_pixels_t *pix;
    float *data;

    /* Generate a Bayer dithering pattern. */
    if(!strncmp(name, "bayer", 5))
    {
        int i, j, w, h, n;

        w = atoi(name + 5);
        name = strchr(name + 5, 'x');
        if(!name)
            return NULL;
        h = atoi(name + 1);
        if(w <= 0 || h <= 0)
            return NULL;

        for(n = 1; n < w || n < h; n *= 2)
            ;

        ret = pipi_new(w, h);
        pix = pipi_getpixels(ret, PIPI_PIXELS_Y_F);
        data = (float *)pix->pixels;

        for(j = 0; j < h; j++)
            for(i = 0; i < w; i++)
            {
                int k, l, x = 0;

                for(k = 1, l = n * n / 4; k < n; k *= 2, l /= 4)
                {
                    if((i & k) && (j & k))
                        x += l;
                    else if(i & k)
                        x += 3 * l;
                    else if(j & k)
                        x += 2 * l;
                }

                data[j * w + i] = (double)(x + 1) / (n * n + 1);
            }

        return ret;
    }

    /* Generate a completely random image. */
    if(!strncmp(name, "random", 6))
    {
        unsigned int ctx = 1;
        int x, y, t, w, h;

        w = atoi(name + 6);
        name = strchr(name + 6, 'x');
        if(!name)
            return NULL;
        h = atoi(name + 1);
        if(w <= 0 || h <= 0)
            return NULL;

        ret = pipi_new(w, h);
        pix = pipi_getpixels(ret, PIPI_PIXELS_RGBA_F);
        data = (float *)pix->pixels;

        for(y = 0; y < h; y++)
            for(x = 0; x < w; x++)
            {
                for(t = 0; t < 3; t++)
                {
                    long hi, lo;

                    hi = ctx / 12773L;
                    lo = ctx % 12773L;
                    ctx = 16807L * lo - 2836L * hi;
                    if(ctx <= 0)
                        ctx += 0x7fffffffL;

                    data[4 * (y * w + x) + t]
                        = (double)((ctx % 65536) / 65535.);
                }
                data[4 * (y * w + x) + 3] = 1.0;
            }

        return ret;
    }

    return NULL;
}