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

#include "SkMasks.h"
#include "SkTypes.h"

/*
 *
 * Used to convert 1-7 bit color components into 8-bit color components
 *
 */
const static uint8_t n_bit_to_8_bit_lookup_table[] = {
    // 1 bit
    0, 255,
    // 2 bits
    0, 85, 170, 255,
    // 3 bits
    0, 36, 73, 109, 146, 182, 219, 255,
    // 4 bits
    0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255,
    // 5 bits
    0, 8, 16, 25, 33, 41, 49, 58, 66, 74, 82, 90, 99, 107, 115, 123, 132, 140,
    148, 156, 165, 173, 181, 189, 197, 206, 214, 222, 230, 239, 247, 255,
    // 6 bits
    0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 45, 49, 53, 57, 61, 65, 69, 73,
    77, 81, 85, 89, 93, 97, 101, 105, 109, 113, 117, 121, 125, 130, 134, 138,
    142, 146, 150, 154, 158, 162, 166, 170, 174, 178, 182, 186, 190, 194, 198,
    202, 206, 210, 215, 219, 223, 227, 231, 235, 239, 243, 247, 251, 255,
    // 7 bits
    0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38,
    40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76,
    78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110,
    112, 114, 116, 118, 120, 122, 124, 126, 129, 131, 133, 135, 137, 139, 141,
    143, 145, 147, 149, 151, 153, 155, 157, 159, 161, 163, 165, 167, 169, 171,
    173, 175, 177, 179, 181, 183, 185, 187, 189, 191, 193, 195, 197, 199, 201,
    203, 205, 207, 209, 211, 213, 215, 217, 219, 221, 223, 225, 227, 229, 231,
    233, 235, 237, 239, 241, 243, 245, 247, 249, 251, 253, 255
};

/*
 *
 * Convert an n bit component to an 8-bit component
 *
 */
static uint8_t convert_to_8(uint32_t component, uint32_t n) {
    if (0 == n) {
        return 0;
    } else if (8 > n) {
        return n_bit_to_8_bit_lookup_table[(1 << n) - 2 + component];
    } else {
        SkASSERT(8 == n);
        return component;
    }
}

static uint8_t get_comp(uint32_t pixel, uint32_t mask, uint32_t shift,
                        uint32_t size) {
    return convert_to_8((pixel & mask) >> shift, size);
}

/*
 *
 * Get a color component
 *
 */
uint8_t SkMasks::getRed(uint32_t pixel) {
    return get_comp(pixel, fRed.mask, fRed.shift, fRed.size);
}
uint8_t SkMasks::getGreen(uint32_t pixel) {
    return get_comp(pixel, fGreen.mask, fGreen.shift, fGreen.size);
}
uint8_t SkMasks::getBlue(uint32_t pixel) {
    return get_comp(pixel, fBlue.mask, fBlue.shift, fBlue.size);
}
uint8_t SkMasks::getAlpha(uint32_t pixel) {
    return get_comp(pixel, fAlpha.mask, fAlpha.shift, fAlpha.size);
}

/*
 *
 * Process an input mask to obtain the necessary information
 *
 */
const SkMasks::MaskInfo process_mask(uint32_t mask, uint32_t bpp) {
    // Trim the masks to the allowed number of bits
    if (bpp < 32) {
        mask &= (1 << bpp) - 1;
    }

    // Determine properties of the mask
    uint32_t tempMask = mask;
    uint32_t shift = 0;
    uint32_t size = 0;
    if (tempMask != 0) {
        // Count trailing zeros on masks
        for (; (tempMask & 1) == 0; tempMask >>= 1) {
            shift++;
        }
        // Count the size of the mask
        for (; tempMask & 1; tempMask >>= 1) {
            size++;
        }
        // Check that the mask is continuous
        if (tempMask != 0) {
            SkDebugf("Warning: Bit masks is not continuous.\n");
        }
        // Truncate masks greater than 8 bits
        if (size > 8) {
            shift += size - 8;
            size = 8;
        }
    }

    // Save the calculated values
    const SkMasks::MaskInfo info = { mask, shift, size };
    return info;
}

/*
 *
 * Create the masks object
 *
 */
SkMasks* SkMasks::CreateMasks(InputMasks masks, uint32_t bitsPerPixel) {
    // Trim the input masks according to bitsPerPixel
    if (bitsPerPixel < 32) {
        masks.red &= (1 << bitsPerPixel) - 1;
        masks.green &= (1 << bitsPerPixel) - 1;
        masks.blue &= (1 << bitsPerPixel) - 1;
        masks.alpha &= (1 << bitsPerPixel) - 1;
    }

    // Check that masks do not overlap
    if (((masks.red & masks.green) | (masks.red & masks.blue) |
            (masks.red & masks.alpha) | (masks.green & masks.blue) |
            (masks.green & masks.alpha) | (masks.blue & masks.alpha)) != 0) {
        return NULL;
    }

    // Collect information about the masks
    const MaskInfo red = process_mask(masks.red, bitsPerPixel);
    const MaskInfo green = process_mask(masks.green, bitsPerPixel);
    const MaskInfo blue = process_mask(masks.blue, bitsPerPixel);
    const MaskInfo alpha = process_mask(masks.alpha, bitsPerPixel);

    return SkNEW_ARGS(SkMasks, (red, green, blue, alpha));
}


SkMasks::SkMasks(const MaskInfo red, const MaskInfo green,
                 const MaskInfo blue, const MaskInfo alpha)
    : fRed(red)
    , fGreen(green)
    , fBlue(blue)
    , fAlpha(alpha)
{}
