/* Copyright (C) 2007-2008 The Android Open Source Project
**
** This software is licensed under the terms of the GNU General Public
** License version 2, as published by the Free Software Foundation, and
** may be copied, distributed, and modified under those terms.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
*/
#include "android/skin/image.h"
#include "android/skin/resource.h"

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

#define  DEBUG  0

#if DEBUG
static void D(const char*  fmt, ...)
{
    va_list  args;
    va_start(args, fmt);
    vfprintf(stderr, fmt, args);
    va_end(args);
}
#else
#define  D(...)  do{}while(0)
#endif

/********************************************************************************/
/********************************************************************************/
/*****                                                                      *****/
/*****            U T I L I T Y   F U N C T I O N S                         *****/
/*****                                                                      *****/
/********************************************************************************/
/********************************************************************************/

// Create a rotated copy of an input image. |data| is the address of the
// source image pixel buffer, while |width| and |height| are its pixel
// dimensions. This function assumes 32-bit pixel values, and a pitch of
// exactly |4 * width| bytes.
// |rotation| is a SkinRotation value indicating which rotation to apply,
// in clockwise-90-degrees increments.
// Returns the address of a new pixel buffer containing the rotated
// pixels of the copy.
static void*
rotate_image(void* data,
             unsigned width,
             unsigned height,
             SkinRotation rotation) {
    void* result = malloc(width * height * 4);
    if (result == NULL) {
        return NULL;
    }

    switch (rotation & 3) {
        case SKIN_ROTATION_0:
            memcpy((char*)result, (const char*)data, width * height *4);
            break;

        case SKIN_ROTATION_270: {
            unsigned*  start    = (unsigned*)data;
            unsigned*  src_line = start + (width - 1);
            unsigned*  dst_line = (unsigned*)result;
            unsigned   hh;

            for (hh = width; hh > 0; hh--)
            {
                unsigned*  src   = src_line;
                unsigned*  dst   = dst_line;
                unsigned   count = height;

                for ( ; count > 0; count-- ) {
                    dst[0] = src[0];
                    dst += 1;
                    src += width;
                }

                src_line -= 1;
                dst_line += height;
            }
            break;
        }

        case SKIN_ROTATION_180: {
            unsigned*  start    = (unsigned*)data;
            unsigned*  src_line = start + width * (height - 1);
            unsigned*  dst_line = (unsigned*)result;
            unsigned   hh;

            for (hh = height; hh > 0; hh--) {
                unsigned*  src = src_line + (width - 1);
                unsigned*  dst = dst_line;

                while (src >= src_line) {
                    *dst++ = *src--;
                }
                dst_line += width;
                src_line -= width;
            }
            break;
        }

        case SKIN_ROTATION_90: {
            unsigned*  start    = (unsigned*)data;
            unsigned*  src_line = start + width * (height - 1);
            unsigned*  dst_line = (unsigned*)result;
            unsigned   hh;

            for (hh = width; hh > 0; hh--) {
                unsigned*  src = src_line;
                unsigned*  dst = dst_line;
                unsigned   count;

                for (count = height; count > 0; count--) {
                    dst[0] = src[0];
                    dst   += 1;
                    src   -= width;
                }

                dst_line += height;
                src_line += 1;
            }
            break;
        }

        default:
            ;
    }

    return result;
}


// Compute the blended (alpha-attenuated) pixels of a given source image.
// |dst_pixels| and |src_pixels| are the address of the destination and
// source pixel buffers, respectively. |w| and |h| are the width and height
// of both input and output images. |alpha| is an attenuation factor.
//
// This function assumes 32-bit ARGB or BGRA pixels, and a pitch of exactly
// |4 * w| for both buffers. For each pixel, it will compute:
//
//        dst_pixels[n].R = (src_pixels[n].R * alpha) >> 8;
//        dst_pixels[n].G = (src_pixels[n].G * alpha) >> 8;
//        dst_pixels[n].B = (src_pixels[n].B * alpha) >> 8;
//        dst_pixels[n].A = (src_pixels[n].A * alpha) >> 8;
//
static void
blend_image(unsigned*  dst_pixels,
            unsigned*  src_pixels,
            unsigned   w,
            unsigned   h,
            int        alpha) {
    unsigned*  dst     = dst_pixels;
    unsigned*  dst_end = dst + w * h;
    unsigned*  src     = src_pixels;

    for ( ; dst < dst_end; dst++, src++ ) {
        unsigned  ag = (src[0] >> 8) & 0xff00ff;
        unsigned  rb =  src[0]       & 0xff00ff;

        ag = (ag * alpha) & 0xff00ff00;
        rb = ((rb * alpha) >> 8) & 0x00ff00ff;

        dst[0] = ag | rb;
    }
}


static unsigned
skin_image_desc_hash(const SkinImageDesc* desc) {
    unsigned  h = 0;
    int       n;

    for (n = 0; desc->path[n] != 0; n++) {
        int  c = desc->path[n];
        h = h * 33 + c;
    }
    h += desc->rotation * 1573;
    h += desc->blend * 7;

    return  h;
}


static int
skin_image_desc_equal(const SkinImageDesc* a,
                      const SkinImageDesc* b)
{
    return (a->rotation == b->rotation &&
            a->blend    == b->blend    &&
            !strcmp(a->path, b->path));
}

/********************************************************************************/
/********************************************************************************/
/*****                                                                      *****/
/*****            S K I N   I M A G E S                                     *****/
/*****                                                                      *****/
/********************************************************************************/
/********************************************************************************/

enum {
    SKIN_IMAGE_CLONE = (1 << 0)   /* this image is a clone */
};

struct SkinImage {
    unsigned         hash;
    SkinImage*       link;
    int              ref_count;
    SkinImage*       next;
    SkinImage*       prev;
    SkinSurface*     surface;
    unsigned         flags;
    unsigned         w, h;
    void*            pixels;  /* 32-bit ARGB */
    SkinImageDesc    desc;
};


static const SkinImage _no_image[1] = {
    {
        .hash = 0,
        .link = NULL,
        .ref_count = 0,
        .next = NULL,
        .prev = NULL,
        .surface = NULL,
        .flags = 0,
        .w = 0,
        .h = 0,
        .pixels = NULL,
        .desc = (SkinImageDesc){
            .path = "<none>",
            .rotation = SKIN_ROTATION_0,
            .blend = 0,
        }
    }
};

SkinImage* SKIN_IMAGE_NONE = (SkinImage*)&_no_image;

static void
skin_image_free( SkinImage*  image )
{
    if (image && image != _no_image)
    {
        skin_surface_unrefp(&image->surface);

        if (image->pixels) {
            free( image->pixels );
            image->pixels = NULL;
        }

        free(image);
    }
}


static SkinImage*
skin_image_alloc( SkinImageDesc*  desc, unsigned  hash )
{
    int         len   = strlen(desc->path);
    SkinImage*  image = calloc(1, sizeof(*image) + len + 1);

    if (image) {
        image->desc = desc[0];
        image->desc.path = (const char*)(image + 1);
        memcpy( (char*)image->desc.path, desc->path, len );
        ((char*)image->desc.path)[len] = 0;

        image->hash      = hash;
        image->next      = image->prev = image;
        image->ref_count = 1;
    }
    return image;
}


extern void *loadpng(const char *fn, unsigned *_width, unsigned *_height);
extern void *readpng(const unsigned char*  base, size_t  size, unsigned *_width, unsigned *_height);

static int
skin_image_load( SkinImage*  image )
{
    void*     data;
    unsigned  w, h;
    const char*  path = image->desc.path;

    if (path[0] == ':') {
        size_t                size;
        const unsigned char*  base;

        if (path[1] == '/' || path[1] == '\\')
            path += 1;

        base = skin_resource_find( path+1, &size );
        if (base == NULL) {
            fprintf(stderr, "failed to locate built-in image file '%s'\n", path );
            return -1;
        }

        data = readpng(base, size, &w, &h);
        if (data == NULL) {
            fprintf(stderr, "failed to load built-in image file '%s'\n", path );
            return -1;
        }
    } else {
        data = loadpng(path, &w, &h);
        if (data == NULL) {
            fprintf(stderr, "failed to load image file '%s'\n", path );
            return -1;
        }
    }

   /* the data is loaded into memory as RGBA bytes by libpng. we want to manage
    * the values as 32-bit ARGB pixels, so swap the bytes accordingly depending
    * on our CPU endianess
    */
    {
        unsigned*  d     = data;
        unsigned*  d_end = d + w*h;

        for ( ; d < d_end; d++ ) {
            unsigned  pix = d[0];
#if HOST_WORDS_BIGENDIAN
            /* R,G,B,A read as RGBA => ARGB */
            pix = ((pix >> 8) & 0xffffff) | (pix << 24);
#else
            /* R,G,B,A read as ABGR => ARGB */
            pix = (pix & 0xff00ff00) | ((pix >> 16) & 0xff) | ((pix & 0xff) << 16);
#endif
            d[0] = pix;
        }
    }

    image->pixels = data;
    image->w      = w;
    image->h      = h;

    image->surface = skin_surface_create_argb32_from(w, h, w * 4, image->pixels);
    if (image->surface == NULL) {
        fprintf(stderr, "failed to create skin surface for '%s' image\n", path);
        return -1;
    }
    return 0;
}


/* simple hash table for images */

#define  NUM_BUCKETS  64

typedef struct {
    SkinImage*     buckets[ NUM_BUCKETS ];
    SkinImage      mru_head;
    int            num_images;
    unsigned long  total_pixels;
    unsigned long  max_pixels;
    unsigned long  total_images;
} SkinImageCache;


static void
skin_image_cache_init( SkinImageCache*  cache )
{
    memset(cache, 0, sizeof(*cache));
#if DEBUG
    cache->max_pixels = 1;
#else
    cache->max_pixels = 4*1024*1024;  /* limit image cache to 4 MB */
#endif
    cache->mru_head.next = cache->mru_head.prev = &cache->mru_head;
}


static void
skin_image_cache_remove( SkinImageCache*  cache,
                         SkinImage*       image )
{
    /* remove from hash table */
    SkinImage**  pnode = cache->buckets + (image->hash & (NUM_BUCKETS-1));
    SkinImage*   node;

    for (;;) {
        node = *pnode;
        assert(node != NULL);
        if (node == NULL)  /* should not happen */
            break;
        if (node == image) {
            *pnode = node->link;
            break;
        }
        pnode = &node->link;
    }

    D( "skin_image_cache: remove '%s' (rot=%d), %d pixels\n",
       node->desc.path, node->desc.rotation, node->w*node->h );

    /* remove from mru list */
    image->prev->next = image->next;
    image->next->prev = image->prev;

    cache->total_pixels -= image->w*image->h;
    cache->total_images -= 1;
}


static SkinImage*
skin_image_cache_raise( SkinImageCache*  cache,
                        SkinImage*       image )
{
    if (image != cache->mru_head.next) {
        SkinImage*  prev = image->prev;
        SkinImage*  next = image->next;

        /* remove from mru list */
        prev->next = next;
        next->prev = prev;

        /* add to top */
        image->prev = &cache->mru_head;
        image->next = image->prev->next;
        image->prev->next = image;
        image->next->prev = image;
    }
    return image;
}


static void
skin_image_cache_flush( SkinImageCache*  cache )
{
    SkinImage*     image = cache->mru_head.prev;
    int            count = 0;

    D("skin_image_cache_flush: starting\n");
    while (cache->total_pixels > cache->max_pixels &&
           image != &cache->mru_head)
    {
        SkinImage*  prev = image->prev;

        if (image->ref_count == 0) {
            skin_image_cache_remove(cache, image);
            count += 1;
        }
        image = prev;
    }
    D("skin_image_cache_flush: finished, %d images flushed\n", count);
}


static SkinImage**
skin_image_lookup_p( SkinImageCache*   cache,
                     SkinImageDesc*    desc,
                     unsigned         *phash )
{
    unsigned     h     = skin_image_desc_hash(desc);
    unsigned     index = h & (NUM_BUCKETS-1);
    SkinImage**  pnode = &cache->buckets[index];
    for (;;) {
        SkinImage*  node = *pnode;
        if (node == NULL)
            break;
        if (node->hash == h && skin_image_desc_equal(desc, &node->desc))
            break;
        pnode = &node->link;
    }
    *phash = h;
    return  pnode;
}


static SkinImage*
skin_image_create( SkinImageDesc*  desc, unsigned  hash )
{
    SkinImage*  node;

    node = skin_image_alloc( desc, hash );
    if (node == NULL)
        return SKIN_IMAGE_NONE;

    if (desc->rotation == SKIN_ROTATION_0 &&
        desc->blend    == SKIN_BLEND_FULL)
    {
        if (skin_image_load(node) < 0) {
            skin_image_free(node);
            return SKIN_IMAGE_NONE;
        }
    }
    else
    {
        SkinImageDesc  desc0 = desc[0];
        SkinImage*     parent;

        desc0.rotation = SKIN_ROTATION_0;
        desc0.blend    = SKIN_BLEND_FULL;

        parent = skin_image_find( &desc0 );
        if (parent == SKIN_IMAGE_NONE)
            return SKIN_IMAGE_NONE;

        if (desc->rotation == SKIN_ROTATION_90 ||
            desc->rotation == SKIN_ROTATION_270)
        {
            node->w = parent->h;
            node->h = parent->w;
        } else {
            node->w = parent->w;
            node->h = parent->h;
        }

        node->pixels = rotate_image(parent->pixels,
                                    parent->w,
                                    parent->h,
                                    desc->rotation);

        skin_image_unref(&parent);

        if (node->pixels == NULL) {
            skin_image_free(node);
            return SKIN_IMAGE_NONE;
        }

        if (desc->blend != SKIN_BLEND_FULL) {
            blend_image(node->pixels,
                        node->pixels,
                        node->w,
                        node->h,
                        desc->blend);
        }

        node->surface = skin_surface_create_argb32_from(node->w,
                                                        node->h,
                                                        node->w * 4,
                                                        node->pixels);
        if (node->surface == NULL) {
            skin_image_free(node);
            return SKIN_IMAGE_NONE;
        }
    }
    return node;
}


static SkinImageCache   _image_cache[1];
static int              _image_cache_init;

SkinImage*
skin_image_find( SkinImageDesc*  desc )
{
    SkinImageCache*  cache = _image_cache;
    unsigned         hash;
    SkinImage**      pnode = skin_image_lookup_p( cache, desc, &hash );
    SkinImage*       node  = *pnode;

    if (!_image_cache_init) {
        _image_cache_init = 1;
        skin_image_cache_init(cache);
    }

    if (node) {
        node->ref_count += 1;
        return skin_image_cache_raise( cache, node );
    }
    node = skin_image_create( desc, hash );
    if (node == SKIN_IMAGE_NONE)
        return node;

    /* add to hash table */
    node->link = *pnode;
    *pnode     = node;

    /* add to mru list */
    skin_image_cache_raise( cache, node );

    D( "skin_image_cache: add '%s' (rot=%d), %d pixels\n",
       node->desc.path, node->desc.rotation, node->w*node->h );

    cache->total_pixels += node->w*node->h;
    if (cache->total_pixels > cache->max_pixels)
        skin_image_cache_flush( cache );

    return node;
}


SkinImage*
skin_image_find_simple( const char*  path )
{
    SkinImageDesc  desc;

    desc.path     = path;
    desc.rotation = SKIN_ROTATION_0;
    desc.blend    = SKIN_BLEND_FULL;

    return skin_image_find( &desc );
}


SkinImage*
skin_image_ref( SkinImage*  image )
{
    if (image && image != _no_image)
        image->ref_count += 1;

    return image;
}


void
skin_image_unref( SkinImage**  pimage )
{
    SkinImage*  image = *pimage;

    if (image) {
        if (image != _no_image && --image->ref_count == 0) {
            if ((image->flags & SKIN_IMAGE_CLONE) != 0) {
                skin_image_free(image);
            }
        }
        *pimage = NULL;
    }
}


SkinImage*
skin_image_rotate( SkinImage*  source, SkinRotation  rotation )
{
    SkinImageDesc  desc;
    SkinImage*     image;

    if (source == _no_image || source->desc.rotation == rotation)
        return source;

    desc          = source->desc;
    desc.rotation = rotation;
    image         = skin_image_find( &desc );
    skin_image_unref( &source );
    return image;
}


SkinImage*
skin_image_clone( SkinImage*  source )
{
    SkinImage*   image;

    if (source == NULL || source == _no_image)
        return SKIN_IMAGE_NONE;

    image = calloc(1, sizeof(*image));
    if (image == NULL)
        goto Fail;

    image->desc  = source->desc;
    image->hash  = source->hash;
    image->flags = SKIN_IMAGE_CLONE;
    image->w     = source->w;
    image->h     = source->h;
    image->pixels = rotate_image( source->pixels, source->w, source->h,
                                  SKIN_ROTATION_0 );
    if (image->pixels == NULL)
        goto Fail;

    image->surface = skin_surface_create_argb32_from(image->w,
                                                     image->h,
                                                     image->w * 4,
                                                     image->pixels);
    if (image->surface == NULL)
        goto Fail;

    return image;
Fail:
    if (image != NULL)
        skin_image_free(image);
    return SKIN_IMAGE_NONE;
}

SkinImage*
skin_image_clone_full( SkinImage*    source,
                       SkinRotation  rotation,
                       int           blend )
{
    SkinImageDesc   desc;
    SkinImage*      clone;

    if (source == NULL || source == SKIN_IMAGE_NONE)
        return SKIN_IMAGE_NONE;

    if (rotation == SKIN_ROTATION_0 &&
        blend    == SKIN_BLEND_FULL)
    {
        return skin_image_clone(source);
    }

    desc.path     = source->desc.path;
    desc.rotation = rotation;
    desc.blend    = blend;

    clone = skin_image_create( &desc, 0 );
    if (clone != SKIN_IMAGE_NONE)
        clone->flags |= SKIN_IMAGE_CLONE;

    return clone;
}

int
skin_image_w( SkinImage*  image )
{
    return  image ? image->w : 0;
}

int
skin_image_h( SkinImage*  image )
{
    return  image ? image->h : 0;
}

int
skin_image_org_w( SkinImage*  image )
{
    if (image) {
        if (image->desc.rotation == SKIN_ROTATION_90 ||
            image->desc.rotation == SKIN_ROTATION_270)
            return image->h;
        else
            return image->w;
    }
    return 0;
}

int
skin_image_org_h( SkinImage*  image )
{
    if (image) {
        if (image->desc.rotation == SKIN_ROTATION_90 ||
            image->desc.rotation == SKIN_ROTATION_270)
            return image->w;
        else
            return image->h;
    }
    return 0;
}

SkinSurface*
skin_image_surface( SkinImage*  image )
{
    return image ? image->surface : NULL;
}
