/*
 * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

#ifndef SPLASHSCREEN_GFX_IMPL_H
#define SPLASHSCREEN_GFX_IMPL_H

#include "splashscreen_gfx.h"

/* here come some very simple macros */

/* advance a pointer p by sizeof(type)*n bytes */
#define INCPN(type,p,n) ((p) = (type*)(p)+(n))

/* advance a pointer by sizeof(type) */
#define INCP(type,p) INCPN(type,(p),1)

/* store a typed value to pointed location */
#define PUT(type,p,v) (*(type*)(p) = (type)(v))

/* load a typed value from pointed location */
#define GET(type,p) (*(type*)p)

/* same as cond<0?-1:0 */
enum
{
    IFNEG_SHIFT_BITS = sizeof(int) * 8 - 1
};

#define IFNEG(cond) ((int)(cond)>>IFNEG_SHIFT_BITS)

/* same as cond<0?n1:n2 */
#define IFNEGPOS(cond,n1,n2) ((IFNEG(cond)&(n1))|((~IFNEG(cond))&(n2)))

/* value shifted left by n bits, negative n is allowed */
#define LSHIFT(value,n) IFNEGPOS((n),(value)>>-(n),(value)<<(n))

/* value shifted right by n bits, negative n is allowed */
#define RSHIFT(value,n) IFNEGPOS(n,(value)<<-(n),(value)>>(n))

/* converts a single i'th component to the specific format defined by format->shift[i] and format->mask[i] */
#define CONVCOMP(quad,format,i) \
    (LSHIFT((quad),(format)->shift[i])&(format)->mask[i])

/* extracts the component defined by format->shift[i] and format->mask[i] from a specific-format value */
#define UNCONVCOMP(value,format,i) \
    (RSHIFT((value)&(format)->mask[i],(format)->shift[i]))

/*  dithers the color using the dither matrices and colormap from format
    indices to dither matrices are passed as arguments */
INLINE unsigned
ditherColor(rgbquad_t value, ImageFormat * format, int row, int col)
{
    int blue = QUAD_BLUE(value);
    int green = QUAD_GREEN(value);
    int red = QUAD_RED(value);

    blue = format->dithers[0].colorTable[blue +
        format->dithers[0].matrix[col & DITHER_MASK][row & DITHER_MASK]];
    green = format->dithers[1].colorTable[green +
        format->dithers[1].matrix[col & DITHER_MASK][row & DITHER_MASK]];
    red = format->dithers[2].colorTable[red +
        format->dithers[2].matrix[col & DITHER_MASK][row & DITHER_MASK]];
    return red + green + blue;
}

/*      blend (lerp between) two rgb quads
        src and dst alpha is ignored
        the algorithm: src*alpha+dst*(1-alpha)=(src-dst)*alpha+dst, rb and g are done separately
        it's possible to verify that it's almost accurate indeed */

INLINE rgbquad_t
blendRGB(rgbquad_t dst, rgbquad_t src, rgbquad_t alpha)
{
    const rgbquad_t dstrb = dst & 0xFF00FF;
    const rgbquad_t dstg = dst & 0xFF00;
    const rgbquad_t srcrb = src & 0xFF00FF;
    const rgbquad_t srcg = src & 0xFF00;

    rgbquad_t drb = srcrb - dstrb;
    rgbquad_t dg = srcg - dstg;

    alpha += 1;

    drb *= alpha;
    dg *= alpha;
    drb >>= 8;
    dg >>= 8;

    return ((drb + dstrb) & 0xFF00FF) | ((dg + dstg) & 0xFF00);
}

/*      scales rgb quad by alpha. basically similar to what's above. src alpha is retained.
        used for premultiplying alpha

        btw: braindead MSVC6 generates _three_ mul instructions for this function */

INLINE rgbquad_t
premultiplyRGBA(rgbquad_t src)
{
    rgbquad_t srb = src & 0xFF00FF;
    rgbquad_t sg = src & 0xFF00;
    rgbquad_t alpha = src >> QUAD_ALPHA_SHIFT;

    alpha += 1;

    srb *= alpha;
    sg *= alpha;
    srb >>= 8;
    sg >>= 8;

    return (src & 0xFF000000) | (srb & 0xFF00FF) | (sg & 0xFF00);
}

/*      The functions below are inherently ineffective, but the performance seems to be
        more or less adequate for the case of splash screens. They can be optimized later
        if needed. The idea of optimization is to provide inlineable form of putRGBADither and
        getRGBA at least for certain most frequently used visuals. Something like this is
        done in Java 2D ("loops"). This would be possible with C++ templates, but making it
        clean for C would require ugly preprocessor tricks. Leaving it out for later.
*/

/*      convert a single pixel color value from rgbquad according to visual format
        and place it to pointed location
        ordered dithering used when necessary */
INLINE void
putRGBADither(rgbquad_t value, void *ptr, ImageFormat * format,
        int row, int col)
{
    if (format->premultiplied) {
        value = premultiplyRGBA(value);
    }
    if (format->dithers) {
        value = format->colorIndex[ditherColor(value, format, row, col)];
    }
    else {
        value = CONVCOMP(value, format, 0) | CONVCOMP(value, format, 1) |
            CONVCOMP(value, format, 2) | CONVCOMP(value, format, 3);
    }
    switch (format->byteOrder) {
    case BYTE_ORDER_LSBFIRST:
        switch (format->depthBytes) {   /* lack of *break*'s is intentional */
        case 4:
            PUT(byte_t, ptr, value & 0xff);
            value >>= 8;
            INCP(byte_t, ptr);
        case 3:
            PUT(byte_t, ptr, value & 0xff);
            value >>= 8;
            INCP(byte_t, ptr);
        case 2:
            PUT(byte_t, ptr, value & 0xff);
            value >>= 8;
            INCP(byte_t, ptr);
        case 1:
            PUT(byte_t, ptr, value & 0xff);
        }
        break;
    case BYTE_ORDER_MSBFIRST:
        switch (format->depthBytes) {   /* lack of *break*'s is intentional */
        case 4:
            PUT(byte_t, ptr, (value >> 24) & 0xff);
            INCP(byte_t, ptr);
        case 3:
            PUT(byte_t, ptr, (value >> 16) & 0xff);
            INCP(byte_t, ptr);
        case 2:
            PUT(byte_t, ptr, (value >> 8) & 0xff);
            INCP(byte_t, ptr);
        case 1:
            PUT(byte_t, ptr, value & 0xff);
        }
        break;
    case BYTE_ORDER_NATIVE:
        switch (format->depthBytes) {
        case 4:
            PUT(rgbquad_t, ptr, value);
            break;
        case 3:                /* not supported, LSB or MSB should always be specified */
            *(int *) 0 = 0;    /* crash */
            break;
        case 2:
            PUT(word_t, ptr, value);
            break;
        case 1:
            PUT(byte_t, ptr, value);
            break;
        }
    }
}

/* load a single pixel color value and un-convert it to rgbquad according to visual format */
INLINE rgbquad_t
getRGBA(void *ptr, ImageFormat * format)
{
    /*
       FIXME: color is not un-alpha-premultiplied on get
       this is not required by current code, but it makes the implementation inconsistent
       i.e. put(get) will not work right for alpha-premultiplied images */

    /* get the value basing on depth and byte order */
    rgbquad_t value = 0;

    switch (format->byteOrder) {
    case BYTE_ORDER_LSBFIRST:
        switch (format->depthBytes) {
        case 4:
            value |= GET(byte_t, ptr);
            value <<= 8;
            INCP(byte_t, ptr);
        case 3:
            value |= GET(byte_t, ptr);
            value <<= 8;
            INCP(byte_t, ptr);
        case 2:
            value |= GET(byte_t, ptr);
            value <<= 8;
            INCP(byte_t, ptr);
        case 1:
            value |= GET(byte_t, ptr);
        }
        break;
    case BYTE_ORDER_MSBFIRST:
        switch (format->depthBytes) {   /* lack of *break*'s is intentional */
        case 4:
            value |= (GET(byte_t, ptr) << 24);
            INCP(byte_t, ptr);
        case 3:
            value |= (GET(byte_t, ptr) << 16);
            INCP(byte_t, ptr);
        case 2:
            value |= (GET(byte_t, ptr) << 8);
            INCP(byte_t, ptr);
        case 1:
            value |= GET(byte_t, ptr);
        }
        break;
    case BYTE_ORDER_NATIVE:
        switch (format->depthBytes) {
        case 4:
            value = GET(rgbquad_t, ptr);
            break;
        case 3:                /* not supported, LSB or MSB should always be specified */
            *(int *) 0 = 0;
            break;
        case 2:
            value = (rgbquad_t) GET(word_t, ptr);
            break;
        case 1:
            value = (rgbquad_t) GET(byte_t, ptr);
            break;
        }
        break;
    }
    /* now un-convert the value */
    if (format->colorMap) {
        if (value == format->transparentColor)
            return 0;
        else
            return format->colorMap[value];
    }
    else {
        return UNCONVCOMP(value, format, 0) | UNCONVCOMP(value, format, 1) |
            UNCONVCOMP(value, format, 2) | UNCONVCOMP(value, format, 3) |
            format->fixedBits;
    }
}

/* fill the line with the specified color according to visual format */
INLINE void
fillLine(rgbquad_t color, void *pDst, int incDst, int n,
        ImageFormat * dstFormat, int row, int col)
{
    int i;

    for (i = 0; i < n; ++i) {
        putRGBADither(color, pDst, dstFormat, row, col++);
        INCPN(byte_t, pDst, incDst);
    }
}

/* find the shift for specified mask, also verify the mask is valid */
INLINE int
getMaskShift(rgbquad_t mask, int *pShift, int *pnumBits)
{
    int shift = 0, numBits = 0;

    /* check the mask is not empty */
    if (!mask)
        return 0;
    /* calculate the shift */
    while ((mask & 1) == 0) {
        ++shift;
        mask >>= 1;
    }
    /* check the mask is contigious */
    if ((mask & (mask + 1)) != 0)
        return 0;
    /* calculate the number of bits */
    do {
        ++numBits;
        mask >>= 1;
    } while ((mask & 1) != 0);
    *pShift = shift;
    *pnumBits = numBits;
    return 1;
}

#endif
