/*
 * Copyright 2011 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkBlitRow.h"
#include "SkColorPriv.h"
#include "SkDither.h"

///////////////////////////////////////////////////////////////////////////////

static void S32_D4444_Opaque(uint16_t* SK_RESTRICT dst,
                             const SkPMColor* SK_RESTRICT src, int count,
                             U8CPU alpha, int /*x*/, int /*y*/) {
    SkASSERT(255 == alpha);

    if (count > 0) {
        do {
            SkPMColor c = *src++;
            SkPMColorAssert(c);
            SkASSERT(SkGetPackedA32(c) == 255);
            *dst++ = SkPixel32ToPixel4444(c);
        } while (--count != 0);
    }
}

static void S32_D4444_Blend(uint16_t* SK_RESTRICT dst,
                            const SkPMColor* SK_RESTRICT src, int count,
                            U8CPU alpha, int /*x*/, int /*y*/) {
    SkASSERT(255 > alpha);

    if (count > 0) {
        unsigned scale16 = SkAlpha255To256(alpha) >> 4;
        do {
            SkPMColor c = *src++;
            SkPMColorAssert(c);
            SkASSERT(SkGetPackedA32(c) == 255);

            uint32_t src_expand = SkExpand32_4444(c);
            uint32_t dst_expand = SkExpand_4444(*dst);
            dst_expand += (src_expand - dst_expand) * scale16 >> 4;
            *dst++ = SkCompact_4444(dst_expand);
        } while (--count != 0);
    }
}

static void S32A_D4444_Opaque(uint16_t* SK_RESTRICT dst,
                              const SkPMColor* SK_RESTRICT src, int count,
                              U8CPU alpha, int /*x*/, int /*y*/) {
    SkASSERT(255 == alpha);

    if (count > 0) {
        do {
            SkPMColor c = *src++;
            SkPMColorAssert(c);
//            if (__builtin_expect(c!=0, 1))
            if (c)
            {
                unsigned scale16 = SkAlpha255To256(255 - SkGetPackedA32(c)) >> 4;
                uint32_t src_expand = SkExpand_8888(c);
                uint32_t dst_expand = SkExpand_4444(*dst) * scale16;
                *dst = SkCompact_4444((src_expand + dst_expand) >> 4);
            }
            dst += 1;
        } while (--count != 0);
    }
}

static void S32A_D4444_Blend(uint16_t* SK_RESTRICT dst,
                             const SkPMColor* SK_RESTRICT src, int count,
                             U8CPU alpha, int /*x*/, int /*y*/) {
    SkASSERT(255 > alpha);
    
    if (count > 0) {
        int src_scale = SkAlpha255To256(alpha) >> 4;
        do {
            SkPMColor sc = *src++;
            SkPMColorAssert(sc);

            if (sc) {
                unsigned dst_scale = 16 - (SkGetPackedA32(sc) * src_scale >> 8);
                uint32_t src_expand = SkExpand32_4444(sc) * src_scale;
                uint32_t dst_expand = SkExpand_4444(*dst) * dst_scale;
                *dst = SkCompact_4444((src_expand + dst_expand) >> 4);
            }
            dst += 1;
        } while (--count != 0);
    }
}

/////////////////////////////////////////////////////////////////////////////
                               
static void S32_D4444_Opaque_Dither(uint16_t* SK_RESTRICT dst,
                                    const SkPMColor* SK_RESTRICT src,
                                    int count, U8CPU alpha, int x, int y) {
    SkASSERT(255 == alpha);
    
    if (count > 0) {
        DITHER_4444_SCAN(y);
        do {
            SkPMColor c = *src++;
            SkPMColorAssert(c);
            SkASSERT(SkGetPackedA32(c) == 255);

            unsigned dither = DITHER_VALUE(x);
            *dst++ = SkDitherARGB32To4444(c, dither);
            DITHER_INC_X(x);
        } while (--count != 0);
    }
}

static void S32_D4444_Blend_Dither(uint16_t* SK_RESTRICT dst,
                                   const SkPMColor* SK_RESTRICT src,
                                   int count, U8CPU alpha, int x, int y) {
    SkASSERT(255 > alpha);
    
    if (count > 0) {
        int scale16 = SkAlpha255To256(alpha) >> 4;
        DITHER_4444_SCAN(y);
        do {
            SkPMColor c = *src++;
            SkPMColorAssert(c);
            SkASSERT(SkGetPackedA32(c) == 255);

            uint32_t src_expand = SkExpand32_4444(c) * scale16;
            uint32_t dst_expand = SkExpand_4444(*dst) * (16 - scale16);
            
            c = SkCompact_8888(src_expand + dst_expand); // convert back to SkPMColor
            *dst++ = SkDitherARGB32To4444(c, DITHER_VALUE(x));
            DITHER_INC_X(x);
        } while (--count != 0);
    }
}

static void S32A_D4444_Opaque_Dither(uint16_t* SK_RESTRICT dst,
                                     const SkPMColor* SK_RESTRICT src,
                                     int count, U8CPU alpha, int x, int y) {
    SkASSERT(255 == alpha);
    
    if (count > 0) {
        DITHER_4444_SCAN(y);
        do {
            SkPMColor c = *src++;
            SkPMColorAssert(c);
            if (c) {
                unsigned a = SkGetPackedA32(c);                
                int d = SkAlphaMul(DITHER_VALUE(x), SkAlpha255To256(a));
                
                unsigned scale16 = SkAlpha255To256(255 - a) >> 4;
                uint32_t src_expand = SkExpand_8888(c);
                uint32_t dst_expand = SkExpand_4444(*dst) * scale16;
                // convert back to SkPMColor
                c = SkCompact_8888(src_expand + dst_expand);
                *dst = SkDitherARGB32To4444(c, d);
            }
            dst += 1;
            DITHER_INC_X(x);
        } while (--count != 0);
    }
}

// need DitherExpand888To4444(expand, dither)

static void S32A_D4444_Blend_Dither(uint16_t* SK_RESTRICT dst,
                                    const SkPMColor* SK_RESTRICT src,
                                    int count, U8CPU alpha, int x, int y) {
    SkASSERT(255 > alpha);
    
    if (count > 0) {
        int src_scale = SkAlpha255To256(alpha) >> 4;
        DITHER_4444_SCAN(y);
        do {
            SkPMColor c = *src++;
            SkPMColorAssert(c);
            if (c) {
                unsigned a = SkAlpha255To256(SkGetPackedA32(c));
                int d = SkAlphaMul(DITHER_VALUE(x), a);
                
                unsigned dst_scale = 16 - SkAlphaMul(src_scale, a);
                uint32_t src_expand = SkExpand32_4444(c) * src_scale;
                uint32_t dst_expand = SkExpand_4444(*dst) * dst_scale;
                // convert back to SkPMColor
                c = SkCompact_8888(src_expand + dst_expand);
                *dst = SkDitherARGB32To4444(c, d);
            }
            dst += 1;
            DITHER_INC_X(x);
        } while (--count != 0);
    }
}

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

static const SkBlitRow::Proc gProcs4444[] = {
    // no dither
    S32_D4444_Opaque,
    S32_D4444_Blend,
    
    S32A_D4444_Opaque,
    S32A_D4444_Blend,
    
    // dither
    S32_D4444_Opaque_Dither,
    S32_D4444_Blend_Dither,
    
    S32A_D4444_Opaque_Dither,
    S32A_D4444_Blend_Dither
};
    
SkBlitRow::Proc SkBlitRow_Factory_4444(unsigned flags);
SkBlitRow::Proc SkBlitRow_Factory_4444(unsigned flags)
{
    SkASSERT(flags < SK_ARRAY_COUNT(gProcs4444));
    
    return gProcs4444[flags];
}
    
    
