/*
 * File Name: image_dither_unittest.cpp
 */

/*
 * This file is part of uds-plugin-images.
 *
 * uds-plugin-images is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * uds-plugin-images 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 for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * Copyright (C) 2008 iRex Technologies B.V.
 * All rights reserved.
 */

#include <cassert>
#include <iostream>
#include "image_dither_unittest.h"

using namespace std;
using namespace images;

TestImageDither::TestImageDither (void)
{
    g_type_init ();
}

TestImageDither::~TestImageDither (void)
{
}

void TestImageDither::set_image(const std::string & filepath)
{
    img_path = filepath;
}

void TestImageDither::test (void)
{
    // Load the image.
    GdkPixbuf * pixbuf = gdk_pixbuf_new_from_file (img_path.c_str (), 0);

    // Set all fields of attrs_src.
    BitmapAttributes attrs_src, attrs_dst, attrs_tmp;

    attrs_src.width = gdk_pixbuf_get_width (pixbuf);
    attrs_src.height = gdk_pixbuf_get_height (pixbuf);
    attrs_src.rowstride = gdk_pixbuf_get_rowstride (pixbuf);
    attrs_src.data = gdk_pixbuf_get_pixels (pixbuf);
    attrs_src.bytes_per_pixel = gdk_pixbuf_get_n_channels (pixbuf);

    // Convert the image data to be in 8bits.
    ImageDither dither;
    dither.dither_to_8bits (&attrs_src, &attrs_dst);

    // Convert the image data to be in 24bits for saving.
    convert_8bits_to_24bits (&attrs_dst, &attrs_tmp);

    // Save to image file to verify.
    save_24bits_to_file (&attrs_tmp);

    // Free the memory.
    g_object_unref (pixbuf);
    delete [] attrs_dst.data;
    // delete [] attrs_tmp.data;
}

void TestImageDither::convert_8bits_to_24bits (
                          const BitmapAttributes * attrs_src,
                          BitmapAttributes * attrs_dst)
{
    assert (attrs_src);
    assert (attrs_dst);
    assert (attrs_src->data);
    assert (attrs_src->bytes_per_pixel == 1);
    assert (attrs_src->rowstride >=
          (attrs_src->width * attrs_src->bytes_per_pixel));

    attrs_dst->width = attrs_src->width;
    attrs_dst->height = attrs_src->height;
    attrs_dst->rowstride = images::ImageDither::get_rowstride (
                                         attrs_dst->width, 3, 4);
    attrs_dst->bytes_per_pixel = 3;
    attrs_dst->data = _convert_8bits_to_24bits (attrs_src->data,
                          attrs_src->width,
                          attrs_src->height);
}

unsigned char *
TestImageDither::_convert_8bits_to_24bits (const unsigned char *data,
                                           int w, int h)
{
    int rowstride_src = images::ImageDither::get_rowstride (w, 1, 4);

    // Get the memory.
    int rowstride_dst = images::ImageDither::get_rowstride (w, 3, 4);
    unsigned char * dst = new unsigned char[rowstride_dst * h];

    // Walk throuth the whole pixels buffer.
    unsigned char *p_src, *p_dst;
    for (int y = 0; y < h; y++)
    {
        p_src = (unsigned char *) (data + y * rowstride_src);
        p_dst = dst + y * rowstride_dst;

        for (int x = 0; x < w; x++)
        {
            p_dst[0] = *p_src;
            p_dst[1] = *p_src;
            p_dst[2] = *p_src;

            p_src++;
            p_dst += 3;
        }
    }

    return dst;
}

void TestImageDither::save_24bits_to_file (const BitmapAttributes * attrs)
{
    std::string filepath = img_path;
    filepath.append (".new");
    
    GdkPixbuf * pixbuf = gdk_pixbuf_new_from_data (attrs->data,
                     GDK_COLORSPACE_RGB,
                     false,
                     8,
                     attrs->width,
                     attrs->height,
                     attrs->rowstride, 0, 0);

    gdk_pixbuf_save (pixbuf, filepath.c_str(), "jpeg", NULL, NULL);

    g_object_unref (pixbuf);
}


int main ()
{
   const char* imgpath_list[] = {
   "/data/wa/uds/trunk/sample/Rome1.JPG",
   "/data/wa/uds/trunk/sample/Vatican2.JPG",
   "/data/wa/uds/trunk/sample/Rome/Rome1.JPG",
   "/data/wa/uds/trunk/sample/Rome/Rome2.JPG",
   "/data/wa/uds/trunk/sample/alpha/Btn_200_27_transparent_blackborder.png",
   "/data/wa/uds/trunk/sample/alpha/Btn_310_27_black.png",
   "/data/wa/uds/trunk/sample/alpha/Btn_200_27_black.png",
   "/data/wa/uds/trunk/sample/alpha/Btn_310_27_transparent_blackborder.png",
   "/data/wa/uds/trunk/sample/alpha/Btn_150_27_transparent_blackborder.png",
   "/data/wa/uds/trunk/sample/alpha/Btn_150_27_black.png",
   "/data/wa/uds/trunk/sample/alpha/Btn_640_44_black.png",
   "/data/wa/uds/trunk/sample/alpha/Btn_640_44_grey.png",
   "/data/wa/uds/trunk/sample/alpha/Btn_130_27_transparent_blackborder.png",
   "/data/wa/uds/trunk/sample/alpha/Btn_130_27_black.png",
   "/data/wa/uds/trunk/sample/Pisa1.JPG",
   "/data/wa/uds/trunk/sample/openoffice/maximize.bmp",
   "/data/wa/uds/trunk/sample/openoffice/report.bmp",
   "/data/wa/uds/trunk/sample/openoffice/cancel_up.bmp",
   "/data/wa/uds/trunk/sample/openoffice/euro_3.bmp",
   "/data/wa/uds/trunk/sample/openoffice/up.bmp",
   "/data/wa/uds/trunk/sample/openoffice/end.bmp",
   "/data/wa/uds/trunk/sample/openoffice/okay_up.bmp",
   "/data/wa/uds/trunk/sample/openoffice/euro_2.bmp",
   "/data/wa/uds/trunk/sample/openoffice/down.bmp",
   "/data/wa/uds/trunk/sample/openoffice/Import_4.bmp",
   "/data/wa/uds/trunk/sample/openoffice/Import_1.bmp",
   "/data/wa/uds/trunk/sample/openoffice/XML-Import_2-1.bmp",
   "/data/wa/uds/trunk/sample/openoffice/MS-Import_2-1.bmp",
   "/data/wa/uds/trunk/sample/openoffice/minimize.bmp",
   "/data/wa/uds/trunk/sample/openoffice/MS-Import_2-3.bmp",
   "/data/wa/uds/trunk/sample/openoffice/cancel_down.bmp",
   "/data/wa/uds/trunk/sample/openoffice/XML-Import_2-3.bmp",
   "/data/wa/uds/trunk/sample/openoffice/euro_1.bmp",
   "/data/wa/uds/trunk/sample/openoffice/XML-Import_2-4.bmp",
   "/data/wa/uds/trunk/sample/openoffice/okay_down.bmp",
   "/data/wa/uds/trunk/sample/openoffice/XML-Import_2-2.bmp",
   "/data/wa/uds/trunk/sample/openoffice/MS-Import_2-2.bmp",
   "/data/wa/uds/trunk/sample/openoffice/Import_3.bmp",
   "/data/wa/uds/trunk/sample/Florence3.JPG",
   "/data/wa/uds/trunk/sample/Florence/Florence1.JPG",
   "/data/wa/uds/trunk/sample/Florence/Florence3.JPG",
   "/data/wa/uds/trunk/sample/Florence/Florence4.JPG",
   "/data/wa/uds/trunk/sample/Florence/Florence2.JPG",
   "/data/wa/uds/trunk/sample/Venice3.JPG",
   "/data/wa/uds/trunk/sample/Screenshot.png",
   "/data/wa/uds/trunk/sample/Venice1.JPG",
   "/data/wa/uds/trunk/sample/Venice4.JPG",
   "/data/wa/uds/trunk/sample/OURS/OURS2.JPG",
   "/data/wa/uds/trunk/sample/OURS/OURS3.JPG",
   "/data/wa/uds/trunk/sample/OURS/OURS4.JPG",
   "/data/wa/uds/trunk/sample/OURS/OURS5.JPG",
   "/data/wa/uds/trunk/sample/OURS/OURS1.JPG",
   "/data/wa/uds/trunk/sample/Florence4.JPG",
   "/data/wa/uds/trunk/sample/Venice6.JPG",
   "/data/wa/uds/trunk/sample/Florence2.JPG",
   "/data/wa/uds/trunk/sample/Vatican/Vatican2.JPG",
   "/data/wa/uds/trunk/sample/Vatican/Vatican1.JPG",
   "/data/wa/uds/trunk/sample/Venice2.JPG",
   "/data/wa/uds/trunk/sample/Rome2.JPG",
   "/data/wa/uds/trunk/sample/Venice5.JPG",
   "/data/wa/uds/trunk/sample/Florence.jpg",
   "/data/wa/uds/trunk/sample/消化系统示意图.JPG",
   "/data/wa/uds/trunk/sample/Venice/Venice3.JPG",
   "/data/wa/uds/trunk/sample/Venice/Venice1.JPG",
   "/data/wa/uds/trunk/sample/Venice/Venice4.JPG",
   "/data/wa/uds/trunk/sample/Venice/Venice6.JPG",
   "/data/wa/uds/trunk/sample/Venice/Venice2.JPG",
   "/data/wa/uds/trunk/sample/Venice/Venice5.JPG",
   "/data/wa/uds/trunk/sample/Vatican1.JPG",
   "/data/wa/uds/trunk/sample/PISA/Pisa1.JPG",
   "/data/wa/uds/trunk/sample/gif/flowers.gif",
   "/data/wa/uds/trunk/sample/gif/sky.gif",
   "/data/wa/uds/trunk/sample/gif/flower.gif",
   "/data/wa/uds/trunk/sample/gif/apples.gif",
   "/data/wa/uds/trunk/sample/gif/bigapple.gif"
   };

    TestImageDither test;
    std::string filepath;

    int n_images = sizeof(imgpath_list) / sizeof(imgpath_list[0]);
    for (int i = 0; i < n_images; i++)
    {
        filepath = imgpath_list[i];
        test.set_image(filepath);
        test.test();
    }

    return 0;
}

