/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "GLcommon/PaletteTexture.h"
#include <stdio.h>



struct Color
{
  Color(unsigned char r, unsigned char g,unsigned char b, unsigned char a):red(r),green(g),blue(b),alpha(a){};
  unsigned char red;
  unsigned char green;
  unsigned char blue;
  unsigned char alpha;
};

void getPaletteInfo(GLenum internalFormat,unsigned int& indexSizeBits,unsigned int& colorSizeBytes,GLenum& colorFrmt) {

        colorFrmt = GL_RGB;
        switch(internalFormat)
    {
    case GL_PALETTE4_RGB8_OES:
        indexSizeBits = 4;
        colorSizeBytes = 3;
        break;

    case GL_PALETTE4_RGBA8_OES:
        indexSizeBits = 4;
        colorSizeBytes = 4;
        colorFrmt = GL_RGBA;
        break;

    case GL_PALETTE4_RGBA4_OES:
    case GL_PALETTE4_RGB5_A1_OES:
        colorFrmt = GL_RGBA;
        /* fall-through */
    case GL_PALETTE4_R5_G6_B5_OES:
        indexSizeBits = 4;
        colorSizeBytes = 2;
        break;

    case GL_PALETTE8_RGB8_OES:
        indexSizeBits = 8;
        colorSizeBytes = 3;
        break;

    case GL_PALETTE8_RGBA8_OES:
        indexSizeBits = 8;
        colorSizeBytes = 4;
        colorFrmt = GL_RGBA;
        break;

    case GL_PALETTE8_RGBA4_OES:
    case GL_PALETTE8_RGB5_A1_OES:
        colorFrmt = GL_RGBA;
        /* fall-through */
    case GL_PALETTE8_R5_G6_B5_OES:
        indexSizeBits = 8;
        colorSizeBytes = 2;
        break;
    }
}


Color paletteColor(const unsigned char* pallete,unsigned int index,GLenum format)
{
        short s;
        switch(format) {
        //RGB
    case GL_PALETTE4_RGB8_OES:
    case GL_PALETTE8_RGB8_OES:
            return Color(pallete[index],pallete[index+1],pallete[index+2],0);
    case GL_PALETTE8_R5_G6_B5_OES:
    case GL_PALETTE4_R5_G6_B5_OES:
            s = *((short *)(pallete+index));
            return Color((s >> 11)*255/31,((s >> 5) & 0x3f)*255/63 ,(s & 0x1f)*255/31,0);

        //RGBA
    case GL_PALETTE4_RGBA8_OES:
    case GL_PALETTE8_RGBA8_OES:
            return Color(pallete[index],pallete[index+1],pallete[index+2],pallete[index+3]);
    case GL_PALETTE4_RGBA4_OES:
    case GL_PALETTE8_RGBA4_OES:
            s = *((short *)(pallete+index));
            return Color(((s >> 12) & 0xf)*255/15,((s >> 8) & 0xf)*255/15,((s >> 4) & 0xf)*255/15 ,(s & 0xf)*255/15);
    case GL_PALETTE4_RGB5_A1_OES:
    case GL_PALETTE8_RGB5_A1_OES:
            s = *((short *)(pallete+index));
            return Color(((s >> 11) & 0x1f)*255/31,((s >> 6) & 0x1f)*255/31,((s >> 1) & 0x1f)*255/31 ,(s & 0x1) * 255);
        default:
            return Color(255,255,255,255);
    }
}

unsigned char* uncompressTexture(GLenum internalformat,GLenum& formatOut,GLsizei width,GLsizei height,GLsizei imageSize, const GLvoid* data,GLint level) {

    unsigned int indexSizeBits = 0;  //the size of the color index in the pallete
    unsigned int colorSizeBytes = 0; //the size of each color cell in the pallete

    getPaletteInfo(internalformat,indexSizeBits,colorSizeBytes,formatOut);
    if(!data)
    {
        return NULL;
    }

    const unsigned char* palette = static_cast<const unsigned char *>(data);

    //the pallete positioned in the begininng of the data
    // so we jump over it to get to the colos indices in the palette

    int nColors = 2 << (indexSizeBits -1); //2^indexSizeBits
    int paletteSizeBytes = nColors*colorSizeBytes;
    const unsigned char* imageIndices =  palette + paletteSizeBytes;

    //jumping to the the correct mipmap level
    for(int i=0;i<level;i++) {
        imageIndices+= (width*height*indexSizeBits)/8;
        width  = width  >> 1;
        height = height >> 1;
    }

    int colorSizeOut = (formatOut == GL_RGB? 3:4);
    int nPixels = width*height;
    unsigned char* pixelsOut = new unsigned char[nPixels*colorSizeOut];
    if(!pixelsOut) return NULL;

    int leftBytes = ((palette + imageSize) /* the end of data pointer*/
                      - imageIndices);
    int leftPixels = (leftBytes * 8 )/indexSizeBits;

    int maxIndices = (leftPixels < nPixels) ? leftPixels:nPixels;

    //filling the pixels array
    for(int i =0 ; i < maxIndices ; i++) {
        int paletteIndex = 0;
        int indexOut = i*colorSizeOut;
        if(indexSizeBits == 4) {
            paletteIndex = (i%2) == 0 ?
                           imageIndices[i/2] >> 4:  //upper bits
                           imageIndices[i/2] & 0xf; //lower bits
        } else {
            paletteIndex = imageIndices[i];
        }

        paletteIndex*=colorSizeBytes;
        Color c = paletteColor(palette,paletteIndex,internalformat);

        pixelsOut[indexOut] = c.red;
        pixelsOut[indexOut+1] = c.green;
        pixelsOut[indexOut+2] = c.blue;
        if(formatOut == GL_RGBA) {
            pixelsOut[indexOut+3] = c.alpha;
        }
    }
    return pixelsOut;
}

