/*

 * Copyright (c) 2012-2017 The Khronos Group Inc.
 *
 * 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 "test.h"
#include "test_bmp.h"

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

struct GrfmtReader;
typedef unsigned char uchar;

typedef void (*GrfmtReleaseReader)(struct GrfmtReader* reader);
typedef struct GrfmtReader* (*GrfmtReadHeader)(const uchar* data, int size, int* width, int* height, int* iscolor);
typedef int (*GrfmtReadData)(struct GrfmtReader* reader, uchar* data, int step, int color);

typedef struct GrfmtReader
{
    GrfmtReleaseReader release;
    GrfmtReadData read;
}
GrfmtReader;

typedef struct PaletteEntry
{
    uchar b, g, r, a;
}
PaletteEntry;

typedef enum BmpCompression
{
    BMP_RGB = 0,
    BMP_RLE8 = 1,
    BMP_RLE4 = 2,
    BMP_BITFIELDS = 3
}
BmpCompression;

typedef struct GrfmtBmpReader
{
    GrfmtReader base;
    PaletteEntry m_palette[256];
    const uchar* m_data;
    int m_datasize;
    int m_offset;
    int m_width;
    int m_height;
    int m_bpp;
    int m_origin;
    BmpCompression m_rle_code;
}
GrfmtBmpReader;


static void releaseBmpReader(struct GrfmtReader* reader)
{
    if(reader)
        ct_free_mem(reader);
}

#define GET_DWORD(p) ((p) += 4, ((p)[-4] | ((p)[-3]<<8) | ((p)[-2]<<16) | ((p)[-1]<<24)))

static int isColorPalette(const PaletteEntry* pal, int bpp)
{
    int j, clrused = 1 << bpp;
    for( j = 0; j < clrused; j++ )
        if( pal[j].b != pal[j].g || pal[j].b != pal[j].r )
            return 1;
    return 0;
}


#define  SCALE  14
#define  cR  (int)(0.299*(1 << SCALE) + 0.5)
#define  cG  (int)(0.587*(1 << SCALE) + 0.5)
#define  cB  ((1 << SCALE) - cR - cG)

static void cvtRGBToGray( const uchar* src, uchar* gray, int n, int scn, int blue_idx )
{
    int i;
    for( i = 0; i < n; i++, src += scn )
    {
        gray[i] = (uchar)((src[blue_idx]*cB + src[1]*cG + src[blue_idx^2]*cR + (1 << (SCALE-1))) >> SCALE);
    }
}

static void cvtRGBToRGB( const uchar* src, uchar* dst, int n,
                         int scn, int sblue_idx, int dcn, int dblue_idx )
{
    int i;
    for( i = 0; i < n; i++, src += scn, dst += dcn )
    {
        dst[dblue_idx] = src[sblue_idx];
        dst[1] = src[1];
        dst[dblue_idx^2] = src[sblue_idx^2];
        if( dcn == 4 )
            dst[3] = scn < 4 ? 255 : src[3];
    }
}

static void fillColorRow8( uchar* data, const uchar* indices, int n,
                           const PaletteEntry* palette, int dcn, int dblue_idx )
{
    int i;
    for( i = 0; i < n; i++, data += dcn )
    {
        const PaletteEntry* p = palette + indices[i];
        data[dblue_idx] = p->b;
        data[1] = p->g;
        data[dblue_idx^2] = p->r;
        if( dcn == 4 )
            data[3] = 255;
    }
}


static void fillGrayRow8( uchar* data, const uchar* indices, int n, const uchar* palette )
{
    int i;
    for( i = 0; i < n; i++ )
    {
        data[i] = palette[indices[i]];
    }
}


static void fillColorRow4( uchar* data, const uchar* indices, int n,
                           const PaletteEntry* palette, int dcn, int dblue_idx )
{
    int i = 0;
    for( ; i <= n - 2; i += 2, data += dcn*2 )
    {
        int idx = *indices++;
        const PaletteEntry* p0 = palette + (idx >> 4);
        const PaletteEntry* p1 = palette + (idx & 15);
        data[dblue_idx] = p0->b;
        data[1] = p0->g;
        data[dblue_idx^2] = p0->r;
        data[dcn + dblue_idx] = p1->b;
        data[dcn + 1] = p1->g;
        data[dcn + (dblue_idx^2)] = p1->r;
        if( dcn == 4 )
            data[3] = data[7] = 255;
    }

    if( i < n )
    {
        const PaletteEntry* p0 = palette + (indices[0] >> 4);
        data[dblue_idx] = p0->b;
        data[1] = p0->g;
        data[dblue_idx^2] = p0->r;
        if( dcn == 4 )
            data[3] = 255;
    }
}


static void fillGrayRow4( uchar* data, const uchar* indices, int n, const uchar* palette )
{
    int i = 0;
    for( ; i <= n - 2; i += 2 )
    {
        int idx = *indices++;
        data[i] = palette[idx >> 4];
        data[i+1] = palette[idx & 15];
    }
    if( i < n )
        data[i] = palette[indices[0] >> 4];
}


static void fillColorRow1( uchar* data, const uchar* indices, int n,
                           const PaletteEntry* palette, int dcn, int dblue_idx )
{
    int i = 0, mask = 0, idx = 0;
    for( i = 0; i < n; i++, data += dcn, mask >>= 1 )
    {
        const PaletteEntry* p;
        if( mask == 0 )
        {
            idx = *indices++;
            mask = 128;
        }
        p = palette + ((idx & mask) != 0);
        data[dblue_idx] = p->b;
        data[1] = p->g;
        data[dblue_idx^2] = p->r;
        data[3] = 255;
    }
}


static void fillGrayRow1( uchar* data, const uchar* indices, int n, const uchar* palette )
{
    int i = 0, mask = 0, idx = 0;
    for( i = 0; i < n; i++, mask >>= 1 )
    {
        if( mask == 0 )
        {
            idx = *indices++;
            mask = 128;
        }
        data[i] = palette[(idx & mask) != 0];
    }
}

static int readBmpData(struct GrfmtReader* _reader, uchar* data, int step, int dcn )
{
    GrfmtBmpReader* reader = (GrfmtBmpReader*)_reader;
    uchar  gray_palette[256];
    int result = 0;
    int color = dcn > 1;
    int y, src_step, width, height, bpp;
    const uchar* p;
    const PaletteEntry* palette = 0;

    if( !reader || !reader->m_data || reader->m_offset <= 0 )
        return -1;

    width = reader->m_width;
    height = reader->m_height;
    bpp = reader->m_bpp;
    palette = &reader->m_palette[0];

    src_step = ((width*(bpp != 15 ? bpp : 16) + 7)/8 + 3) & -4;
    p = reader->m_data + reader->m_offset;

    if( reader->m_offset + src_step*height > reader->m_datasize )
        return -1;

    if( reader->m_origin > 0 )
    {
        data += (height - 1)*step;
        step = -step;
    }

    if( color == 0 && bpp <= 8 )
    {
        cvtRGBToGray(&palette[0].b, &gray_palette[0], (1 << bpp), 4, 0);
    }

    switch( bpp )
    {
    /************************* 1 BPP ************************/
    case 1:
        for( y = 0; y < height; y++, data += step, p += src_step )
        {
            if( color )
                fillColorRow1( data, p, width, palette, dcn, 2 );
            else
                fillGrayRow1( data, p, width, gray_palette );
        }
        result = 0;
        break;

    /************************* 4 BPP ************************/
    case 4:
        for( y = 0; y < height; y++, data += step, p += src_step )
        {
            if( color )
                fillColorRow4( data, p, width, palette, dcn, 2 );
            else
                fillGrayRow4( data, p, width, gray_palette );
        }
        result = 0;
        break;

    /************************* 8 BPP ************************/
    case 8:
        for( y = 0; y < height; y++, data += step, p += src_step )
        {
            if( color )
                fillColorRow8( data, p, width, palette, dcn, 2 );
            else
                fillGrayRow8( data, p, width, gray_palette );
        }
        result = 0;
        break;
    /************************* 24 BPP ************************/
    case 24:
        for( y = 0; y < height; y++, data += step, p += src_step )
        {
            if( color )
                cvtRGBToRGB( p, data, width, 3, 0, dcn, 2 );
            else
                cvtRGBToGray( p, data, width, 3, 0 );
        }
        result = 0;
        break;
    /************************* 32 BPP ************************/
    case 32:
        for( y = 0; y < height; y++, data += step, p += src_step )
        {
            if( color )
                cvtRGBToRGB( p, data, width, 4, 0, dcn, 2 );
            else
                cvtRGBToGray( p, data, width, 4, 0 );
        }
        result = 0;
        break;
    default:
        assert(0);
    }

    return result;
}


static struct GrfmtReader* readBmpHeader(const uchar* data, int datasize, int* _width, int* _height, int* _iscolor)
{
    GrfmtBmpReader* reader = 0;
    int result = 0;
    int iscolor = 0;
    int width = 0, height = 0, bpp = 0;
    BmpCompression rle_code = BMP_RGB;
    PaletteEntry palette[256];
    int offset, size;
    int j, clrused = 0;
    const uchar* p = data + 10;

    if( !data || datasize < 56 || !_width || !_height || !_iscolor || data[0] != 'B' || data[1] != 'M' )
        return 0;

    offset = GET_DWORD(p);
    size = GET_DWORD(p);

    ct_memset(&palette[0], 0, sizeof(palette));

    if( size >= 36 )
    {
        if( (int)((p - data) + size) >= datasize )
            return 0;

        width = GET_DWORD(p);
        height = GET_DWORD(p);
        bpp = GET_DWORD(p) >> 16;
        rle_code = (BmpCompression)GET_DWORD(p);
        p += 12;
        clrused = GET_DWORD(p);
        p += size - 36;

        if( width > 0 && height != 0 &&
           (((bpp == 1 || bpp == 4 || bpp == 8 ||
              bpp == 24 || bpp == 32 ) && rle_code == BMP_RGB) ||
            (bpp == 16 && (rle_code == BMP_RGB || rle_code == BMP_BITFIELDS)) ||
            (bpp == 4 && rle_code == BMP_RLE4) ||
            (bpp == 8 && rle_code == BMP_RLE8)))
        {
            iscolor = 1;
            result = 1;

            if( bpp <= 8 )
            {
                clrused = clrused == 0 ? (1 << bpp) : clrused;
                memcpy(&palette[0], p, clrused*4);
                p += clrused*4;
                iscolor = isColorPalette( palette, clrused );
            }
            else if( bpp == 16 && rle_code == BMP_BITFIELDS )
            {
                int redmask = GET_DWORD(p);
                int greenmask = GET_DWORD(p);
                int bluemask = GET_DWORD(p);

                if( bluemask == 0x1f && greenmask == 0x3e0 && redmask == 0x7c00 )
                    bpp = 15;
                else if( bluemask == 0x1f && greenmask == 0x7e0 && redmask == 0xf800 )
                    ;
                else
                    result = 0;
            }
            else if( bpp == 16 && rle_code == BMP_RGB )
                bpp = 15;
        }
    }
    else if( size == 12 )
    {
        width  = GET_DWORD(p);
        height = GET_DWORD(p);
        bpp    = GET_DWORD(p) >> 16;
        rle_code = BMP_RGB;

        if( width > 0 && height != 0 &&
           (bpp == 1 || bpp == 4 || bpp == 8 || bpp == 24 || bpp == 32 ))
        {
            if( bpp <= 8 )
            {
                clrused = 1 << bpp;
                for( j = 0; j < clrused; j++, p += 3 )
                {
                    palette[j].b = p[0];
                    palette[j].g = p[1];
                    palette[j].r = p[2];
                    palette[j].a = 255;
                }
                iscolor = isColorPalette( palette, clrused );
            }
            result = 1;
        }
    }

    if( result == 0 || (bpp == 15 || bpp == 16) || (rle_code != BMP_RGB && rle_code != BMP_BITFIELDS) )
        return 0;

    reader = (GrfmtBmpReader*)ct_alloc_mem(sizeof(*reader));
    if( !reader )
        return 0;
    ct_memset(reader, 0, sizeof(*reader));
    reader->base.release = releaseBmpReader;
    reader->base.read = readBmpData;

    reader->m_bpp = bpp;
    reader->m_width = width;
    reader->m_height = height;
    reader->m_origin = height > 0 ? 1 : 0;
    reader->m_offset = offset;
    reader->m_rle_code = rle_code;

    reader->m_data = data;
    reader->m_datasize = datasize;
    reader->m_offset = offset;

    if( _width )
        *_width = width;
    if( _height )
        *_height = height;
    if( _iscolor )
        *_iscolor = iscolor;

    memcpy(&reader->m_palette[0], &palette[0], sizeof(palette));
    return (GrfmtReader*)reader;
}

#define PUT_DWORD(p, val) \
    (((p)[0] = (uchar)(val)), \
    ((p)[1] = (uchar)((val) >> 8)), \
    ((p)[2] = (uchar)((val) >> 16)), \
    ((p)[3] = (uchar)((val) >> 24)), \
     (p) += 4)

//////////////////////////////////////////////////////////////////////////////////////////
static int writeBMP( const char* filename, const uchar* img, int step, int width, int height, int channels0 )
{
    int channels = channels0 == 4 ? 3 : channels0;
    int width3 = width*channels;
    int i, y, fileStep = (width3 + 3) & -4;

    int  bitmapHeaderSize = 40;
    int  paletteSize = channels > 1 ? 0 : 1024;
    int  headerSize = 14 /* fileheader */ + bitmapHeaderSize + paletteSize;
    int  fileSize = fileStep*height + headerSize;
    uchar* buf = 0, *p = 0;

    FILE* f = fopen(filename, "wb");
    if(!f)
        return -1;

    buf = p = (uchar*)ct_alloc_mem(fileSize);
    p[0] = 'B';
    p[1] = 'M';
    p += 2;
    PUT_DWORD(p, fileSize);
    PUT_DWORD(p, 0);
    PUT_DWORD(p, headerSize);
    PUT_DWORD(p, bitmapHeaderSize);
    PUT_DWORD(p, width);
    PUT_DWORD(p, height);
    PUT_DWORD(p, 1 | (channels << 19));
    PUT_DWORD(p, BMP_RGB);
    ct_memset(p, 0, 20);
    p += 20;

    if( channels == 1 )
    {
        for( i = 0; i < 256; i++, p += 4 )
        {
            p[0] = p[1] = p[2] = (uchar)i;
            p[3] = 255;
        }
    }

    for( y = height - 1; y >= 0; y--, p += fileStep )
    {
        if( channels0 == 1 )
            memcpy(p, img + step*y, width);
        else
        {
            const uchar* imgrow = img + step*y;
            uchar* dst = p;
            for( i = 0; i < width; i++, imgrow += channels0, dst += 3 )
            {
                dst[0] = imgrow[2];
                dst[1] = imgrow[1];
                dst[2] = imgrow[0];
            }
        }
        if( fileStep > width3 )
            ct_memset(p + width3, 0, fileStep - width3);
    }

    fwrite(buf, 1, fileSize, f);
    fclose(f);
    ct_free_mem(buf);
    return 0;
}

CT_Image ct_read_bmp(const unsigned char* data, int datasize, int dcn)
{
    int w = 0, h = 0, iscolor = 0;
    GrfmtReader* bmpreader = readBmpHeader(data, (int)datasize, &w, &h, &iscolor);
    int ok = 0;
    CT_Image image = 0;

    if( dcn <= 0 )
        dcn = iscolor ? 3 : 1;

    if( bmpreader )
    {
        vx_uint32 width  = w;
        vx_uint32 height = h;
        vx_df_image format = dcn == 1 ? VX_DF_IMAGE_U8 : dcn == 3 ? VX_DF_IMAGE_RGB : VX_DF_IMAGE_RGBX;

        image = ct_allocate_image(width, height, format);

        if( image )
            ok = bmpreader->read(bmpreader, image->data.y, (int)ct_stride_bytes(image), dcn) >= 0;
        bmpreader->release(bmpreader);
    }

    if( ok )
        return image;

    //ct_release_image(&image);
    return 0;
}


int ct_write_bmp(const char* filename, CT_Image image)
{
    if( image )
    {
        CT_Image wrt_image;
        if (image->format == VX_DF_IMAGE_U1)
        {
            wrt_image = ct_allocate_image(image->width, image->height, VX_DF_IMAGE_U8);
            U1_ct_image_to_U8_ct_image(image, wrt_image);
        }
        else
        {
            wrt_image = image;
        }
        int channels = ct_channels(wrt_image->format);
        return writeBMP(filename, wrt_image->data.y, (int)ct_stride_bytes(wrt_image),
                        (int)wrt_image->width, (int)wrt_image->height, channels);
    }
    return -1;
}
