#include "board.h"
#include "libejpgl.h"

#include "images/jpeg/QVGA_RGB/DSC05253.JPG.h"
#include "images/jpeg/QVGA_RGB/Luck_de_nuit.jpg.h"
#include "images/jpeg/QVGA_RGB/paris_la_nuit.jpg.h"
#include "images/jpeg/QVGA_RGB/mer01.JPG.h"
#include "images/jpeg/QVGA_RGB/DSC05243.JPG.h"
#include "images/jpeg/QVGA_RGB/p1010649vk5.JPG.h"

#include <stdio.h>
#include <stdint.h>
#include <string.h>

#define STRING_RESULT "Time %u (ms)"

static uint32_t _dwTimeBegin ;
static uint32_t _dwTimeEnd ;
static uint32_t _dwLastLength ;
static uint8_t* _pucLastIndex ;
static uint8_t* _pucIndex ;
static uint8_t _szResult[30] ;

#define IMAGE_SIZE_QVGA    (240*320*3)
#define IMAGE_SIZE_VGA     (480*640*3)

static uint8_t* _pucImageSrc ;
static uint8_t* _pucImageDst ;
static uint8_t _aucLine[2048] ;

static const uint8_t* _ppucImages[]=
{
    _aucJPG_DSC05253_data,
    _aucJPG_Luck_de_nuit_data,
    _aucJPG_paris_la_nuit_data,
    _aucJPG_MER01_data,
//    _aucJPG_DSC05243_data,
    _aucJPG_p1010649vk5_data
} ;

void SysTick_Handler( void )
{
    TimeTick_Increment() ;
}

static uint32_t ejgpl_test( uint8_t* pucData, uint32_t dwHeight, uint32_t dwWidth )
{
    return 0 ;
}

#if defined sam3s_ek
static void _jpeg_benchmark_ek( const uint8_t* pucJPEG )
{
    LCD_SetCursor( 0, 0 ) ;
    LCD_WriteRAM_Prepare() ;

    if ( ejpg_decompress( (uint8_t*)_aucJPG_DSC05253_data, aucLine, 320, 240, ijg_cbk ) == 0 )
    {
    }
}
#endif // defined sam3s_ek

#if defined sam3s_pirrd
static void _jpeg_benchmark_pirrd( const uint8_t* pucJPEG )
{
    LCD_SetCursor( 0, 0 ) ;
    LCD_WriteRAM_Prepare() ;

    if ( ejpg_decompress( (uint8_t*)_aucJPG_DSC05253_data, aucLine, 320, 240, ijg_cbk ) == 0 )
    {
    }
}
#endif // defined sam3s_pirrd

extern int main( void )
{
    uint32_t dw ;

    // Disable watchdog
    WDT_Disable( WDT ) ;

    // configure PSRAM if we are using ATSAM3S-PIRRD
#if defined sam3s_pirrd
    BOARD_ConfigurePsram() ;
    _pucImageSrc=BOARD_PSRAM_BASE ;
    _pucImageDst=(uint8_t*)BOARD_PSRAM_BASE+IMAGE_SIZE_QVGA ;
#endif // sam3s_pirrd

    printf( "JPEG benchmarks\n\r" ) ;

    // Configure systick for 1 ms.
    if ( TimeTick_Configure( BOARD_MCK ) != 0 )
    {
        printf( "-F- Systick configuration error\n\r" ) ;
    }

    // Initialize LCD
    LCDD_Initialize() ;

    // Turn on LCD
    LCDD_On() ;

    _dwTimeBegin=GetTickCount() ;
    LCDD_Fill( COLOR_NAVY ) ;
    _dwTimeEnd=GetTickCount() ;
    snprintf( (char*)_szResult, sizeof( _szResult ), "0-"STRING_RESULT, _dwTimeEnd-_dwTimeBegin+1 ) ;
    LCDD_DrawRectangleWithFill( 0, 0, BOARD_LCD_WIDTH, 20, COLOR_WHITE ) ;
    LCDD_DrawString( 0, 2, (const uint8_t*)_szResult, COLOR_BLACK ) ;
    Wait( 1000 ) ;

    for ( dw=0 ; dw < (sizeof( _ppucImages )/sizeof( _ppucImages[0] )) ; dw++ )
    {
        _pucIndex=_pucImageSrc ;
#if defined sam3s_ek
        _jpeg_benchmark_ek( _ppucImages[dw] ) ;
#endif // defined sam3s_ek
#if defined sam3s_pirrd
        _jpeg_benchmark_pirrd( _ppucImages[dw] ) ;
#endif // defined sam3s_pirrd
    }

    return 0 ;
}
