]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - glsdk/omapdrmtest.git/commitdiff
omx cam: add test app
authorHervé Fache <h-fache@ti.com>
Thu, 30 Aug 2012 08:09:37 +0000 (10:09 +0200)
committerNikhil Devshatwar <a0132237@ti.com>
Wed, 22 May 2013 09:44:13 +0000 (15:14 +0530)
Signed-off-by: Hervé Fache <h-fache@ti.com>
13 files changed:
.gitignore
Makefile.am
configure.ac
omx_cam/Makefile.am [new file with mode: 0644]
omx_cam/OMXVisionCam.cpp [new file with mode: 0644]
omx_cam/OMXVisionCam.h [new file with mode: 0644]
omx_cam/OMXVisionCam_Gamma_Tbl.h [new file with mode: 0644]
omx_cam/OMXVisionCam_WB_patch.h [new file with mode: 0644]
omx_cam/VisionCam.h [new file with mode: 0644]
omx_cam/VisionCamSimpleTest.cpp [new file with mode: 0644]
omx_cam/autolock.h [new file with mode: 0644]
omx_cam/output.cpp [new file with mode: 0644]
omx_cam/output.h [new file with mode: 0644]

index 2c981ae02d708bbf9fefa4eeb2c116df7b5fbaea..eb5134fdcb62f733681ff3831ef12709fcab34bd 100644 (file)
@@ -30,6 +30,10 @@ depcomp
 dmabuftest
 fliptest
 viddec3test
 dmabuftest
 fliptest
 viddec3test
+omx_cam/omx_cam_test
+
+# cam test outputs:
+/output_*
 
 tags
 TAGS
 
 tags
 TAGS
index b47e6e9669533ebae84084841bc5c8d20659a5d4..a51373b89eb41846ff08afd883d7f6a94c4459d3 100644 (file)
@@ -15,7 +15,7 @@
 #  this program.  If not, see <http://www.gnu.org/licenses/>.
 #  
 
 #  this program.  If not, see <http://www.gnu.org/licenses/>.
 #  
 
-SUBDIRS = util
+SUBDIRS = util omx_cam
 bin_PROGRAMS = fliptest
 
 if ENABLE_V4L2_DMABUF
 bin_PROGRAMS = fliptest
 
 if ENABLE_V4L2_DMABUF
index 4432cb4fcddc3a560bca2766a5f62160343bff07..a87480907e535fddc67ae66f273899516a5ef7d3 100644 (file)
@@ -30,6 +30,7 @@ m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
 
 # Initialize libtool
 AC_PROG_LIBTOOL
 
 # Initialize libtool
 AC_PROG_LIBTOOL
+AC_PROG_CXX
 
 # Obtain compiler/linker options for depedencies
 PKG_CHECK_MODULES(DRM, libdrm libdrm_omap)
 
 # Obtain compiler/linker options for depedencies
 PKG_CHECK_MODULES(DRM, libdrm libdrm_omap)
@@ -84,6 +85,16 @@ else
 fi
 AM_CONDITIONAL(ENABLE_DCE, [test "x$HAVE_DCE" = xyes])
 
 fi
 AM_CONDITIONAL(ENABLE_DCE, [test "x$HAVE_DCE" = xyes])
 
+# Check for libdomx..
+PKG_CHECK_MODULES(DOMX, libdomx, [HAVE_DOMX=yes], [HAVE_DOMX=no])
+if test "x$HAVE_DOMX" = "xyes"; then
+       AC_DEFINE(HAVE_DOMX, 1, [Have DOMX support])
+       AC_MSG_NOTICE([Detected libdomx, building omx camera test])
+else
+       AC_MSG_WARN([No libdomx support detected, disabling omx camera test])
+fi
+AM_CONDITIONAL(ENABLE_DOMX, [test "x$HAVE_DOMX" = xyes])
+
 dnl ===========================================================================
 dnl check compiler flags
 AC_DEFUN([LIBDRM_CC_TRY_FLAG], [
 dnl ===========================================================================
 dnl check compiler flags
 AC_DEFUN([LIBDRM_CC_TRY_FLAG], [
@@ -144,5 +155,5 @@ WARN_CFLAGS="$libdrm_cv_warn_cflags"
 AC_SUBST(WARN_CFLAGS)
 
 
 AC_SUBST(WARN_CFLAGS)
 
 
-AC_CONFIG_FILES([Makefile util/Makefile])
+AC_CONFIG_FILES([Makefile omx_cam/Makefile util/Makefile])
 AC_OUTPUT
 AC_OUTPUT
diff --git a/omx_cam/Makefile.am b/omx_cam/Makefile.am
new file mode 100644 (file)
index 0000000..333432b
--- /dev/null
@@ -0,0 +1,17 @@
+AM_CFLAGS = $(DRM_CFLAGS) $(DRM_OMAP_CFLAGS) $(DOMX_CFLAGS) \
+       -I../util \
+       $(NULL)
+
+AM_CXXFLAGS = $(AM_CFLAGS)
+
+if ENABLE_DOMX
+bin_PROGRAMS = omx_cam_test
+
+omx_cam_test_SOURCES = \
+       output.cpp \
+       OMXVisionCam.cpp \
+       VisionCamSimpleTest.cpp \
+       $(NULL)
+
+omx_cam_test_LDADD = ../util/libutil.la @DOMX_LIBS@
+endif
diff --git a/omx_cam/OMXVisionCam.cpp b/omx_cam/OMXVisionCam.cpp
new file mode 100644 (file)
index 0000000..7e64d7f
--- /dev/null
@@ -0,0 +1,3617 @@
+/* Copyright (C) 2010 Texas Instruments, Inc. All rights reserved. */
+
+#include <autolock.h>
+#include <output.h>
+#include <OMXVisionCam.h>
+
+#undef VCAM_SET_FORMAT_ROTATION
+#define USE_WB_GAIN_PATCH // enable the hardcoded WB gain get/set apis
+
+#ifdef USE_WB_GAIN_PATCH
+    #include "OMXVisionCam_WB_patch.h"
+#endif
+
+//#define _USE_GAMMA_RESET_HC_ // enable the hard coded reset system for gamma tables
+
+#include "OMXVisionCam_Gamma_Tbl.h"
+
+#define HERE {printf("=======> OMX - %d <=======", __LINE__);fflush(stdout);}
+
+#ifdef USE_WB_GAIN_PATCH
+    #define RED 0
+    #define GREEN_RED 1
+    #define GREEN_BLUE 2
+    #define BLUE 3
+
+    #define CALCULATE_WB_GAINS_OFFSET(type,in,out) out = (type *)(in + 4 + in[4] + in[8])
+#endif // USE_WB_GAIN_PATCH
+
+#define GAMMA_TABLE_SIZE 1024*sizeof(uint16_t)
+
+#define OMX_CHECK(error, function)  {\
+    error = function;\
+    if (error != OMX_ErrorNone) {\
+        ERROR("OMX Error 0x%08x in "#function" on line # %u", error, __LINE__);\
+    }\
+}
+
+#define OMX_CONVERT_RETURN_IF_ERROR(error, function) {\
+    error = function;\
+    if (error != OMX_ErrorNone) {\
+        ERROR("OMX Error 0x%08x in "#function" on line # %u", error, __LINE__);\
+        return ConvertError(error);\
+    }\
+}
+
+#define OMX_STRUCT_INIT(str, type, pVersion)  {\
+    memset(&str, 0, sizeof(type));\
+    str.nSize = sizeof(type);\
+    memcpy(&str.nVersion, pVersion, sizeof(OMX_VERSIONTYPE));\
+    str.nPortIndex = OMX_ALL;\
+}
+
+#define OMX_STRUCT_INIT_PTR(ptr, type, pVersion) {\
+    memset(ptr, 0, sizeof(type));\
+    ptr->nSize = sizeof(type);\
+    memcpy(&ptr->nVersion, pVersion, sizeof(OMX_VERSIONTYPE));\
+    ptr->nPortIndex = OMX_ALL;\
+}
+
+#define LOOP_PORTS( port, cnt ) \
+        for(    cnt = ( VCAM_PORT_ALL == port ? VCAM_PORT_PREVIEW : port ); \
+                cnt < ( VCAM_PORT_ALL == port ? VCAM_PORT_MAX : port + 1 ); \
+                cnt++ \
+            )
+
+void* FocusThreadLauncher(void *arg)
+{
+    OMXVisionCam *pCam = reinterpret_cast<OMXVisionCam *>(arg);
+    pCam->waitForFocus();
+    return 0;
+}
+
+void* PreemptionThreadLauncher( void *arg )
+{
+    OMXVisionCam *pCam = reinterpret_cast<OMXVisionCam *>(arg);
+    pCam->PreemptionService();
+    return 0;
+}
+
+void* FrameThreadFunc(void* user) {
+  OMXVisionCam* pCam = static_cast<OMXVisionCam*>(user);
+  OMX_IN OMX_BUFFERHEADERTYPE* pBuffHeader;
+  do {
+    if (pCam->mFrameCbData.frames.empty()){
+      pthread_mutex_lock(&pCam->mFrameCbData.mutex);
+    } else {
+      pBuffHeader = pCam->mFrameCbData.frames.front();
+      pCam->mFrameCbData.frames.pop_front();
+      if (pBuffHeader != NULL) {
+        pCam->frameReceivedSrvc(pBuffHeader);
+      }
+    }
+  } while (pBuffHeader != NULL);
+
+  return NULL;
+}
+
+static void PrintOMXState(OMX_STATETYPE state)
+{
+    const char *state_names[] = {
+        "OMX_StateInvalid",
+        "OMX_StateLoaded",
+        "OMX_StateIdle",
+        "OMX_StateExecuting",
+        "OMX_StatePause",
+        "OMX_StateWaitForResources"
+    };
+    if (state < (sizeof(state_names) / sizeof(const char*))) {
+        MSG("OMX-CAMERA is in state %s", state_names[state]);
+    }
+}
+
+OMX_U32 frameRates[] = {1, 5, 15, 24, 30, 60};
+
+
+/* Constructor - Open the Shared Library, containing the Camera Adapter and
+* gen an instance of the Adapter.
+*/
+OMXVisionCam::OMXVisionCam()
+{
+    m_callback = NULL;
+    m_focuscallback = NULL;
+    pthread_mutex_init(&mFrameBufferLock, NULL);
+    pthread_mutex_init(&mUserRequestLock, NULL);
+    memset(&mCurGreContext, 0, sizeof(mCurGreContext));
+}
+
+int OMXVisionCam::init(void *cookie)
+{
+    mFlushInProcess = false;
+    OMX_ERRORTYPE omxError = OMX_ErrorNone;
+    int greError = 0;
+
+#if TIME_PROFILE
+    PopulateTimeProfiler();
+#endif // TIME_PROFILE
+
+    MSG("OMXVisionCam::OMXVisionCam");
+    MSG("OMXVisionCam compiled: %s, %s", __DATE__, __TIME__ );
+    mLocalVersion = new OMX_VERSIONTYPE();
+    m_callback = NULL;
+    m_focuscallback = NULL;
+
+    m_cookie = cookie; // save the cookie value;
+
+    mLocalVersion->s.nVersionMajor = 1;
+    mLocalVersion->s.nVersionMinor = 1;
+    mLocalVersion->s.nRevision = 0 ;
+    mLocalVersion->s.nStep =  0;
+
+    sem_init(&mGreLocalSem, 0, 1); // set the max count
+    sem_wait(&mGreLocalSem); // pre-decrement the current count otherwise the first wait will pass early
+    sem_init(&mGreFocusSem, 0, 1); // set the max count
+    sem_wait(&mGreFocusSem); // pre-decrement the current count otherwise the first wait will pass early
+
+    // Initialize the Vision Core
+    MSG("Calling OMX_Init()");
+    OMX_CONVERT_RETURN_IF_ERROR(omxError, OMX_Init());
+
+    OMX_CALLBACKTYPE omxCallbacks;
+    omxCallbacks.EventHandler    = OMXVisionCam::EventHandler;
+    omxCallbacks.EmptyBufferDone = OMXVisionCam::EmptyBufferDone;
+    omxCallbacks.FillBufferDone  = OMXVisionCam::FillBufferDone;
+
+    memset( &(mCurGreContext), 0, sizeof( VCAM_ComponentContext ) );
+
+    mCurGreContext.mPortsInUse[VCAM_PORT_ALL] = OMX_ALL;
+    mCurGreContext.mPortsInUse[VCAM_PORT_PREVIEW] = VCAM_CAMERA_PORT_VIDEO_OUT_PREVIEW;
+    mCurGreContext.mPortsInUse[VCAM_PORT_VIDEO]   = VCAM_CAMERA_PORT_VIDEO_OUT_VIDEO;
+
+    for( int i = VCAM_PORT_PREVIEW; i < VCAM_PORT_MAX; i++ )
+    {
+        mBuffersInUse[i].mBuffers = NULL;
+        mBuffersInUse[i].mNumberBuffers = 0;
+        mCurGreContext.mCameraPortParams[i].mColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
+        mCurGreContext.mCameraPortParams[i].mWidth = QVGA_WIDTH;
+        mCurGreContext.mCameraPortParams[i].mHeight = QVGA_HEIGHT;
+        mCurGreContext.mCameraPortParams[i].mFrameRate = INITIAL_FRAMERATE;
+        for(uint32_t buf = 0; buf < VCAM_NUM_BUFFERS; buf++ )
+            mCurGreContext.mCameraPortParams[i].mBufferHeader[buf] = NULL;
+        mFrameDescriptors[i] = NULL;
+    }
+
+    mCurGreContext.mHandleComp = NULL;
+
+    MSG("Calling OMX_GetHandle()");
+    OMX_CONVERT_RETURN_IF_ERROR(omxError,OMX_GetHandle(&( mCurGreContext.mHandleComp ),
+                                         (OMX_STRING)"OMX.TI.DUCATI1.VIDEO.CAMERA",
+                                         this ,
+                                         &omxCallbacks));
+    GetDucatiVersion();
+
+    OMX_CONVERT_RETURN_IF_ERROR(omxError,OMX_SendCommand(mCurGreContext.mHandleComp,
+                                                         OMX_CommandPortDisable,
+                                                         OMX_ALL,
+                                                         NULL));
+
+
+// #if defined(BLAZE) || defined(SDP) || defined(BLAZE_TABLET)
+    {
+        OMX_U32 pr = 4;
+
+        memcpy( &mVisionCamPriority.nVersion, mLocalVersion, sizeof(OMX_VERSIONTYPE));
+        mVisionCamPriority.nGroupID = CAMERA_GROUP_ID;
+        mVisionCamPriority.nGroupPriority = pr;
+        mVisionCamPriority.nSize = sizeof(OMX_PRIORITYMGMTTYPE);
+
+        omxError = OMX_SetParameter(mCurGreContext.mHandleComp, OMX_IndexParamPriorityMgmt ,&mVisionCamPriority);
+    }
+// #else
+//     ERROR("No Priority Management is enabled on this platform!");
+// #endif
+
+    pthread_mutex_lock(&mFrameCbData.mutex);
+    pthread_create(&mFrameThread, NULL, FrameThreadFunc, this);
+    mUseFramePackaging = false;
+
+    m_frameNum = 0;
+    mPreemptionState = VCAM_PREEMPT_INACTIVE;
+    mFaceDetectionEnabled = false;
+    mReturnToExecuting = false;
+#ifdef _USE_GAMMA_RESET_HC_
+    mGammaResetPolulated = false;
+#endif // _USE_GAMMA_RESET_HC_
+
+    return greError;
+}
+
+int OMXVisionCam::deinit()
+{
+    int greError = 0;
+    OMX_ERRORTYPE omxError = OMX_ErrorNone;
+
+    // Free the handle for the Camera component
+    if (mCurGreContext.mHandleComp)
+    {
+        // free the handle
+        MSG("Calling OMX_FreeHandle(0x%08x)", (unsigned)(mCurGreContext.mHandleComp));
+        omxError = OMX_FreeHandle(mCurGreContext.mHandleComp);
+        greError = ConvertError(omxError);
+        mCurGreContext.mHandleComp = 0;
+        if( 0 != greError )
+        {
+            ERROR("ERROR: error freeing OMX handle.OMX_FreeHandle() returned 0x%x", omxError);
+        }
+
+        // Deinitialize the OMX Core
+        MSG("Calling OMX_Deinit()");
+        omxError = OMX_Deinit();
+        greError = ConvertError(omxError);
+        if( 0 != greError )
+        {
+            ERROR("ERROR: error in OMX_Deinit.OMX err: 0x%x", omxError);
+        }
+    }
+
+    mFrameCbData.frames.push_back(NULL);
+    pthread_mutex_unlock(&mFrameCbData.mutex);
+    pthread_join(mFrameThread, NULL);
+
+#if TIME_PROFILE
+    for(int i = 0; i < VCAM_TIME_TARGET_MAX; i++)
+        if( mTimeProfiler[i] )      // dump and clear
+            delete mTimeProfiler[i];
+#endif
+
+    delete mLocalVersion;
+
+    sem_destroy(&mGreLocalSem);
+    sem_destroy(&mGreFocusSem);
+
+    return greError;
+}
+
+/* Destructor - free all recources used by Vision Cam and from us */
+OMXVisionCam::~OMXVisionCam()
+{
+    pthread_mutex_destroy(&mFrameBufferLock);
+    pthread_mutex_destroy(&mUserRequestLock);
+    MSG("OMX Vision Cam is destroyed!");
+}
+
+/**
+* This is used to get esier the state of component.
+*/
+inline OMX_STATETYPE OMXVisionCam::getComponentState()
+{
+    OMX_STATETYPE state = OMX_StateInvalid;
+
+    if( mCurGreContext.mHandleComp )
+    {
+        OMX_GetState( mCurGreContext.mHandleComp, &state );
+    }
+    PrintOMXState(state);
+    return state;
+}
+
+/**
+* Initialisation of OMX_PARAM_PORTDEFINITIONTYPE
+* needed for various configurations
+*/
+inline OMX_ERRORTYPE OMXVisionCam::initPortCheck( OMX_PARAM_PORTDEFINITIONTYPE * portCheck , OMX_U32 portIndex )
+{
+    OMX_ERRORTYPE omxError = OMX_ErrorNone;
+    OMX_STRUCT_INIT_PTR(portCheck, OMX_PARAM_PORTDEFINITIONTYPE, mLocalVersion)
+
+    if( VCAM_PORT_ALL < portIndex && VCAM_PORT_MAX > portIndex )
+    {
+        portCheck->nPortIndex = mCurGreContext.mPortsInUse[portIndex];
+        omxError = OMX_GetParameter(mCurGreContext.mHandleComp,
+                                    OMX_IndexParamPortDefinition,
+                                    portCheck);
+        MSG("PORT CHECK[%u], E:%d P:%d B#:%u %ux%u C:%d",
+                  (uint32_t)portCheck->nPortIndex,
+                  portCheck->bEnabled,
+                  portCheck->bPopulated,
+                  (uint32_t)portCheck->nBufferCountActual,
+                  (uint32_t)portCheck->format.video.nFrameWidth,
+                  (uint32_t)portCheck->format.video.nFrameHeight,
+                  portCheck->format.video.eColorFormat);
+
+    }
+    else
+        omxError = OMX_ErrorBadParameter;
+
+    if( omxError != OMX_ErrorNone )
+    {
+        ERROR("OMX_GetParameter - 0x%x in initPortCheck(%lu)",
+                  omxError, mCurGreContext.mPortsInUse[portIndex]);
+    }
+    return omxError;
+}
+/**
+   @brief Method to convert from OMX_ERRORTYPE to GesturError_e
+   @param error Any of the standard OMX error codes defined in the OpenMAX 1.x Specification.
+   @return int
+ */
+int OMXVisionCam::ConvertError(OMX_ERRORTYPE error)
+{
+    int status = 0;
+    switch(error)
+    {
+        case OMX_ErrorNone:
+            status = 0;
+            break;
+        case OMX_ErrorBadParameter:
+            status = -EINVAL;
+            break;
+        case OMX_ErrorIncorrectStateOperation:
+            status = -EBADE;
+            break;
+        case OMX_ErrorHardware:
+            status = -EIO;
+            break;
+        default:
+            status = -ESTALE; /* Something stupid */
+            break;
+    }
+    if (error != OMX_ErrorNone) {
+        ERROR("Converting OMX Error 0x%08x to int %d", error, status);
+    }
+    return status;
+}
+
+int OMXVisionCam::getLutValue( int searchVal, ValueTypeOrigin origin, const int lut[][2], int lutSize)
+{
+    int idxToGet = (origin == VCAM_VALUE_TYPE ? OMX_VALUE_TYPE : VCAM_VALUE_TYPE );
+    for( int i = 0; i < lutSize; i++ )
+    {
+        if( lut[i][origin] == searchVal )
+            return lut[i][idxToGet];
+    }
+
+    return -EINVAL;
+}
+
+void OMXVisionCam::GetDucatiVersion()
+{
+    if( mCurGreContext.mHandleComp )
+    {
+        OMX_VERSIONTYPE compVersion;
+        OMX_VERSIONTYPE specVersion;
+        char compName[128];
+        OMX_UUIDTYPE compUUID[128];
+        OMX_ERRORTYPE omxError = OMX_ErrorNone;
+        MSG("Querying Component Version!");
+        omxError = OMX_GetComponentVersion(mCurGreContext.mHandleComp,
+                                           compName,
+                                           &compVersion,
+                                           &specVersion,
+                                           compUUID);
+        if (omxError == OMX_ErrorNone)
+        {
+            MSG("\tComponent Name:    [%s]",   compName);
+            MSG("\tComponent Version: [%u]",   (unsigned int)compVersion.nVersion);
+            MSG("\tSpec Version:      [%u]",   (unsigned int)specVersion.nVersion);
+            MSG("\tComponent UUID:    [%s]", (char*)compUUID);
+        }
+    }
+}
+
+int OMXVisionCam::transitToState(OMX_STATETYPE targetState, serviceFunc transitionService, void * data )
+{
+    int greError = 0;
+    OMX_ERRORTYPE omxError = OMX_ErrorNone;
+    sem_t sem; // this semaphore does not need to be global
+
+    if( OMX_StateInvalid == targetState )
+        return -EINVAL;
+
+    sem_init(&sem, 0, 1);
+    sem_wait(&sem); // predecrement so that the later wait will actually block
+
+    omxError = RegisterForEvent( mCurGreContext.mHandleComp,
+                                    OMX_EventCmdComplete,
+                                    OMX_CommandStateSet,
+                                    targetState,
+                                    &sem,
+                                    -1 // Infinite timeout
+                                );
+
+    if( OMX_ErrorNone == omxError )
+    {
+        omxError = OMX_SendCommand( mCurGreContext.mHandleComp ,
+                                                   OMX_CommandStateSet,
+                                                   targetState,
+                                                   NULL );
+        switch( omxError )
+        {
+            case OMX_ErrorNone:
+            {
+                if( transitionService )
+                {
+                    greError = transitionService( this, data );
+                }
+                break;
+            }
+
+            case OMX_ErrorIncorrectStateTransition:
+            {
+                greError = -EINVAL;
+                break;
+            }
+
+            case OMX_ErrorInsufficientResources:
+            {
+                if( OMX_StateIdle == targetState )
+                {
+                    mPreemptionState = VCAM_PREEMPT_WAIT_TO_START;
+                    greError = PreemptionService();
+                }
+                break;
+            }
+
+            case OMX_ErrorSameState:
+                break;
+
+            default:
+                greError = ConvertError(omxError);
+                break;
+        }
+
+        if( greError != 0 || OMX_ErrorSameState == omxError )
+        {
+            // unregister the event
+            EventHandler( mCurGreContext.mHandleComp,
+                          this,
+                          (OMX_EVENTTYPE)OMX_EventCmdComplete,
+                          (OMX_U32)OMX_CommandStateSet,
+                          (OMX_U32)targetState,
+                          NULL
+                        );
+        }
+        else //( 0 == greError )
+        {
+            MSG("Waiting for state transition. State requested: %d", (int)targetState);
+            sem_wait(&sem);
+            MSG("Camera is now in state %d", (int)targetState);
+        }
+    }
+
+    sem_destroy(&sem);
+
+    return greError;
+}
+
+int OMXVisionCam::portEnableDisable( OMX_COMMANDTYPE enCmd, serviceFunc enablementService, VisionCamPort_e port )
+{
+    int greError = 0;
+    OMX_ERRORTYPE omxError = OMX_ErrorNone;
+
+    OMX_PARAM_PORTDEFINITIONTYPE portCheck;
+    VCAM_PortParameters * portData = NULL;
+
+    mCurGreContext.mCameraPortParams[VCAM_PORT_ALL].mIsActive = true;
+
+    int32_t p;
+    LOOP_PORTS( port , p )
+    {
+        initPortCheck(&portCheck, p);
+        portData = &mCurGreContext.mCameraPortParams[p];
+
+        // check to see if the port is already enabled/disabled and that we wanted that state
+        if( (OMX_TRUE == portCheck.bEnabled) && (enCmd == OMX_CommandPortEnable) )
+        {
+            portData->mIsActive = true;
+            continue;
+        }
+
+        if( (OMX_FALSE == portCheck.bEnabled) && (enCmd == OMX_CommandPortDisable) )
+        {
+            portData->mIsActive = false;
+            continue;
+        }
+
+        // we wanted to transition from one state to the other
+
+        // ports with no buffers can't be enabled or disabled.
+        if( portData->mNumBufs == 0 )
+            continue;
+
+        // we have buffers, so enable/disable the port!
+        MSG("Registering for port enable/disable event");
+        omxError = RegisterForEvent(    mCurGreContext.mHandleComp,
+                                        OMX_EventCmdComplete,
+                                        enCmd,
+                                        mCurGreContext.mPortsInUse[p],
+                                        &mGreLocalSem,
+                                        -1 /*Infinite timeout */
+                                    );
+
+        if( OMX_ErrorNone == omxError )
+        {
+            omxError = OMX_SendCommand( mCurGreContext.mHandleComp,
+                                        enCmd,
+                                        mCurGreContext.mPortsInUse[p],
+                                        NULL
+                                        );
+        }
+
+        if( enablementService && OMX_ErrorNone == omxError )
+        {
+            greError = enablementService( this, (void*)(&p) );
+        }
+
+        if( OMX_ErrorNone == omxError && 0 == greError )
+        {
+            sem_wait(&mGreLocalSem);
+        }
+        else
+        {
+            // unregister event
+            EventHandler( mCurGreContext.mHandleComp,
+                        this,
+                        (OMX_EVENTTYPE)OMX_EventCmdComplete,
+                        (OMX_U32)enCmd,
+                        (OMX_U32)mCurGreContext.mPortsInUse[p],
+                        NULL
+                        );
+        }
+
+        initPortCheck(&portCheck, p);
+
+        if( OMX_TRUE == portCheck.bEnabled )
+        {
+            portData->mIsActive = true;
+            mFramePackage.mExpectedFrames[p] = true;
+        }
+        else
+        {
+            portData->mIsActive = false;
+            mFramePackage.mExpectedFrames[p] = false;
+        }
+    }
+
+    mCurGreContext.mCameraPortParams[VCAM_PORT_ALL].mIsActive = true;
+    int32_t p2;
+    LOOP_PORTS(VCAM_PORT_ALL, p2)
+    {
+        if( mCurGreContext.mCameraPortParams[p2].mIsActive == false )
+        {
+            mCurGreContext.mCameraPortParams[VCAM_PORT_ALL].mIsActive = false;
+            break;
+        }
+    }
+
+    return greError;
+}
+
+int OMXVisionCam::fillPortBuffers( VisionCamPort_e port )
+{
+    int greError = 0;
+    OMX_ERRORTYPE omxError = OMX_ErrorNone;
+    VCAM_PortParameters *portData = NULL;
+
+    portData = &mCurGreContext.mCameraPortParams[port];
+    if (portData->mIsActive == true) {
+
+        for( int index = 0; index < portData->mNumBufs; index++ )
+        {
+            if( portData && portData->mBufferHeader[index] )
+            {
+                MSG("FILL BUFF HDR[%d]:%p PORT:%u", index, portData->mBufferHeader[index], (uint32_t)mCurGreContext.mPortsInUse[port]);
+                omxError = OMX_FillThisBuffer(mCurGreContext.mHandleComp,
+                                              (OMX_BUFFERHEADERTYPE*)( portData->mBufferHeader[index]));
+                if (omxError != OMX_ErrorNone)
+                {
+                    ERROR("OMX_FillThisBuffer() returned error  0x%x", omxError );
+                    greError = ConvertError(omxError);
+                    break;
+                }
+            }
+            else
+            {
+                greError = -ENOMEM;
+            }
+        }
+    }
+    else
+    {
+        greError = -EBADE;
+    }
+    if (omxError != OMX_ErrorNone)
+    {
+        greError = ConvertError(omxError);
+    }
+
+    return greError;
+}
+
+int OMXVisionCam::freePortBuffers( VisionCamPort_e port )
+{
+    int greError = 0;
+    OMX_ERRORTYPE omxError = OMX_ErrorNone;
+    VCAM_PortParameters *portData = NULL;
+
+    AutoLock lock(&mFrameBufferLock);
+
+    int32_t p;
+    LOOP_PORTS( port , p )
+    {
+        portData = &mCurGreContext.mCameraPortParams[p];
+        for( int buff = 0; buff < portData->mNumBufs; buff++ )
+        {
+            omxError = OMX_FreeBuffer( mCurGreContext.mHandleComp,
+                                        mCurGreContext.mPortsInUse[p],
+                                        portData->mBufferHeader[buff]
+                                      );
+            portData->mBufferHeader[buff] = NULL;
+            if (omxError != OMX_ErrorNone)
+            {
+                ERROR("OMX_FreeBuffer() returned error  0x%x", omxError );
+                greError = ConvertError(omxError);
+                break;
+            }
+        }
+    }
+
+    return greError;
+}
+
+int OMXVisionCam::populatePort( VisionCamPort_e port )
+{
+    int greError = 0;
+    OMX_ERRORTYPE omxError = OMX_ErrorNone;
+    VCAM_PortParameters * data = NULL;
+
+    int32_t p;
+    LOOP_PORTS( port , p )
+    {
+        OMX_TI_PARAM_USEBUFFERDESCRIPTOR desc;
+        OMX_STRUCT_INIT(desc, OMX_TI_PARAM_USEBUFFERDESCRIPTOR, mLocalVersion);
+        // No idea
+        desc.nPortIndex = mCurGreContext.mPortsInUse[p];
+        // For 2D buffer
+        desc.bEnabled = OMX_FALSE;
+        omxError = OMX_SetParameter(mCurGreContext.mHandleComp, (OMX_INDEXTYPE) OMX_TI_IndexUseDmaBuffers, &desc);
+        MSG("Configuring port %u for DMAbuf handles (err=0x%08x)", p, omxError);
+        data = &mCurGreContext.mCameraPortParams[p];
+
+        for( int indBuff = 0; indBuff < data->mNumBufs; indBuff++ )
+        {
+            OMX_BUFFERHEADERTYPE *pBufferHdr;
+            OMX_U8 *buffer = NULL;
+
+            // Pass array of file descriptors
+            buffer = (OMX_U8*)mBuffersInUse[p].mBuffers[indBuff].fd;
+            MSG("VCAM: Using FDs %d and %d", ((int*) buffer)[0], ((int*) buffer)[1]);
+            omxError = OMX_UseBuffer( mCurGreContext.mHandleComp,
+                                        &pBufferHdr,
+                                        mCurGreContext.mPortsInUse[p],
+                                        0,
+                                        data->mBufSize,
+                                        buffer );
+
+            if( OMX_ErrorNone != omxError )
+            {
+                ERROR("VCAM: ERROR: OMX_UseBuffer() returned 0x%x ( %d )", omxError, omxError);
+                greError = ConvertError(omxError);
+                break;
+            }
+
+            pBufferHdr->pAppPrivate = (OMX_PTR)&mBuffersInUse[p].mBuffers[indBuff];
+            MSG("pAppPrivate=%p mBuffers[indBuff]=%p", pBufferHdr->pAppPrivate, &mBuffersInUse[p].mBuffers[indBuff]);
+            pBufferHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
+            memcpy( &(pBufferHdr->nVersion), mLocalVersion, sizeof( OMX_VERSIONTYPE ) );
+
+            data->mBufferHeader[indBuff] = pBufferHdr;
+
+            if( NULL == mFrameDescriptors[p][indBuff]->mFrameBuff )
+                    mFrameDescriptors[p][indBuff]->mFrameBuff = pBufferHdr->pAppPrivate;
+        }
+    }
+
+    return greError;
+}
+
+int OMXVisionCam::useBuffers(BufferMeta* meta, uint32_t numImages, VisionCamPort_e port )
+{
+    int greError = 0;
+
+    if ( numImages == 0  || port <= VCAM_PORT_ALL || port >= VCAM_PORT_MAX)
+    {
+        ERROR("Invalid parameters to useBuffers()");
+        return -EINVAL;
+    }
+
+    // alloc the array for frame descriptors
+    if( !mFrameDescriptors[port] )
+    {
+        mFrameDescriptors[port] = new VisionCamFrame* [numImages];
+        if( NULL == mFrameDescriptors[port] )
+        {
+            greError = -ENOMEM;
+        }
+
+        for( uint32_t i = 0; i < numImages && 0 == greError; i++ )
+        {
+            mFrameDescriptors[port][i] = new VisionCamFrame();
+
+            if( mFrameDescriptors[port][i] )
+            {
+                mFrameDescriptors[port][i]->clear();
+            }
+            else
+            {
+                while( i )
+                    delete mFrameDescriptors[port][--i];
+
+                delete [] mFrameDescriptors[port];
+                mFrameDescriptors[port] = NULL;
+
+                greError = -ENOMEM;
+            }
+        }
+    }
+
+    if( 0 == greError )
+    {
+        VCAM_PortParameters * data = &mCurGreContext.mCameraPortParams[port];
+
+        mBuffersInUse[port].mBuffers = meta;
+        mBuffersInUse[port].mNumberBuffers = (unsigned)numImages;
+
+        data->mNumBufs = mBuffersInUse[port].mNumberBuffers;
+        data->mStride = mBuffersInUse[port].mBuffers[0].buffer->pitches[0];
+
+        if( OMX_StateIdle != getComponentState() )
+        {
+            greError = transitToState( OMX_StateIdle );
+        }
+    }
+
+    return greError;
+}
+
+int OMXVisionCam::flushBuffers( VisionCamPort_e port)
+{
+    int greError = 0;
+    OMX_ERRORTYPE omxError = OMX_ErrorNone;
+
+    if( OMX_StateExecuting != getComponentState() )
+    {
+        return greError;
+    }
+
+    int32_t p;
+    LOOP_PORTS( port , p )
+    {
+        sem_t sem;
+        sem_init(&sem, 0, 1);
+        sem_wait(&sem); // predecrement so that the next wait won't fire ahead of time.
+        omxError = RegisterForEvent(mCurGreContext.mHandleComp,
+                                    OMX_EventCmdComplete,
+                                    OMX_CommandFlush,
+                                    mCurGreContext.mPortsInUse[p],
+                                    &sem,
+                                    -1 /*Infinite timeout*/
+                                    );
+
+        if( OMX_ErrorNone == omxError )
+        {
+            omxError = OMX_SendCommand( mCurGreContext.mHandleComp,
+                                        OMX_CommandFlush,
+                                        mCurGreContext.mPortsInUse[p],
+                                        NULL );
+        }
+
+        if( OMX_ErrorNone == omxError )
+        {
+            sem_wait(&sem);
+        }
+
+        sem_destroy(&sem);
+    }
+    return greError;
+}
+
+/* Send command to Camera */
+int OMXVisionCam::sendCommand( VisionCamCmd_e cmdId, void *param, uint32_t size, VisionCamPort_e port)
+{
+    int greError = 0;
+    OMX_ERRORTYPE omxError = OMX_ErrorNone;
+
+    AutoLock lock(&mUserRequestLock);
+
+    MSG("SEND CMD: 0x%04x, %p, %zu, %d", cmdId, param, size, port);
+
+    switch (cmdId)
+    {
+        case VCAM_CMD_PREVIEW_START:
+        {
+            greError = startPreview(port);
+            break;
+        }
+
+        case VCAM_CMD_PREVIEW_STOP:
+        {
+            if( OMX_StateExecuting == getComponentState() )
+                greError = stopPreview(port);
+            else
+                greError = -EBADE;
+            break;
+        }
+
+        case VCAM_EXTRA_DATA_START:
+        {
+            int i, EDataType;
+            for( i = 0; i < VCAM_EXTRA_DATA_TYPE_MAX; i++ )
+            {
+                if( ExtraDataTypeLUT[ i ][ 0 ]  == *( (int*)param ) )
+                {
+                    EDataType = ExtraDataTypeLUT[ i ][ 1 ];
+                    break;
+                }
+            }
+            if( i == VCAM_EXTRA_DATA_TYPE_MAX )
+            {
+                greError = -EINVAL;
+                break;
+            }
+
+            OMX_CONFIG_EXTRADATATYPE xData;
+            OMX_STRUCT_INIT(xData, OMX_CONFIG_EXTRADATATYPE, mLocalVersion);
+#if defined(TUNA) || defined(MAGURO)
+            xData.eCameraView       = OMX_2D_Prv;
+#endif
+            if( OMX_ExtraDataNone == EDataType )
+            {
+              for( int i = 1; i < VCAM_EXTRA_DATA_TYPE_MAX; i++ )
+              {// stop extra data transfer for all types of data
+                  if( 0 == greError )
+                  {
+                    xData.eExtraDataType = (OMX_EXT_EXTRADATATYPE)ExtraDataTypeLUT[i][1];
+                    xData.bEnable = OMX_FALSE;
+                    int32_t p;
+                    LOOP_PORTS( port, p )
+                    {
+                        xData.nPortIndex = p;
+                        omxError = OMX_SetConfig( mCurGreContext.mHandleComp, ( OMX_INDEXTYPE )OMX_IndexConfigOtherExtraDataControl, &xData);
+                    }
+                  }
+              }
+            }
+            else
+            {
+                if( 0 == greError )
+                {
+                    xData.eExtraDataType = ( OMX_EXT_EXTRADATATYPE )EDataType;
+                    xData.bEnable = OMX_TRUE;
+
+                    omxError = OMX_SetConfig( mCurGreContext.mHandleComp, ( OMX_INDEXTYPE )OMX_IndexConfigOtherExtraDataControl, &xData);
+                }
+            }
+            break;
+        }
+
+        case VCAM_EXTRA_DATA_STOP:
+        {
+            int i, EDataType;
+            for( i = 0; i < VCAM_EXTRA_DATA_TYPE_MAX; i++ )
+            {
+                if( ExtraDataTypeLUT[ i ][ 0 ]  == *( (int*)param ) )
+                {
+                    EDataType = ExtraDataTypeLUT[ i ][ 1 ];
+                    break;
+                }
+            }
+            if( i == VCAM_EXTRA_DATA_TYPE_MAX )
+            {
+                greError = -EINVAL;
+                break;
+            }
+
+            OMX_CONFIG_EXTRADATATYPE xData;
+            OMX_STRUCT_INIT(xData, OMX_CONFIG_EXTRADATATYPE, mLocalVersion);
+#if defined(TUNA) || defined(MAGURO)
+            xData.eCameraView       = OMX_2D_Prv;
+#endif
+            if( OMX_ExtraDataNone == EDataType )
+            {
+                  for( int i = 1; i < VCAM_EXTRA_DATA_TYPE_MAX; i++ )
+                  {
+    //                   greError = OMX_GetConfig( mCurGreContext.mHandleComp, ( OMX_INDEXTYPE )OMX_IndexConfigOtherExtraDataControl, &xData);
+                      if( 0 == greError )
+                      {
+                          xData.eExtraDataType = (OMX_EXT_EXTRADATATYPE)ExtraDataTypeLUT[i][1];
+                          xData.bEnable = OMX_FALSE;
+                          int32_t p;
+                          LOOP_PORTS(port, p)
+                          {
+                                xData.nPortIndex = p;
+                                omxError = OMX_SetConfig( mCurGreContext.mHandleComp, ( OMX_INDEXTYPE )OMX_IndexConfigOtherExtraDataControl, &xData);
+                          }
+                      }
+                  }
+            }
+            else
+            {
+                if( 0 == greError )
+                {
+                    xData.eExtraDataType = ( OMX_EXT_EXTRADATATYPE )EDataType;
+//                     greError = OMX_GetConfig( mCurGreContext.mHandleComp, ( OMX_INDEXTYPE )OMX_IndexConfigOtherExtraDataControl, &xData);
+
+                    xData.bEnable = OMX_FALSE;
+
+                    omxError = OMX_SetConfig( mCurGreContext.mHandleComp, ( OMX_INDEXTYPE )OMX_IndexConfigOtherExtraDataControl, &xData);
+                }
+            }
+            break;
+        }
+
+        case VCAM_CMD_LOCK_AE:
+        case VCAM_CMD_LOCK_AWB:
+        {
+            OMX_INDEXTYPE index;
+            OMX_IMAGE_CONFIG_LOCKTYPE lockCfg;
+            OMX_STRUCT_INIT(lockCfg, OMX_IMAGE_CONFIG_LOCKTYPE, mLocalVersion);
+            if (VCAM_CMD_LOCK_AE == cmdId)
+            {
+                index = (OMX_INDEXTYPE)OMX_IndexConfigImageExposureLock;
+            }
+            else if (VCAM_CMD_LOCK_AWB == cmdId)
+            {
+                index = (OMX_INDEXTYPE)OMX_IndexConfigImageWhiteBalanceLock;
+            }
+            else
+            {
+                greError = -EINVAL;
+                break;
+            }
+            OMX_GetConfig(mCurGreContext.mHandleComp, index, &lockCfg);
+            lockCfg.bLock = *((OMX_BOOL*)param);
+            OMX_SetConfig(mCurGreContext.mHandleComp, index, &lockCfg);
+            break;
+        }
+#if TIME_PROFILE
+        case VCAM_DUMP_TIMES:
+        {
+            for( int i = 0; i < VCAM_TIME_TARGET_MAX; i++ )
+                if( mTimeProfiler[i] )
+                    mTimeProfiler[i]->dump();
+            break;
+        }
+#endif // TIME_PROFILE
+        case VCAM_CMD_FACE_DETECTION:
+        {
+            mFaceDetectionEnabled = *((bool*)(param));
+            enableFaceDetect(port);
+            break;
+        }
+#if ( defined(DUCATI_1_5) || defined(DUCATI_2_0) ) && defined(OMX_CAMERA_SUPPORTS_MANUAL_CONTROLS)
+        case VCAM_CMD_FREEZE_AWB_PARAMS:
+        {
+            OMX_TI_CONFIG_FREEZE_AWB wbFreeze;
+            OMX_STRUCT_INIT( wbFreeze, OMX_TI_CONFIG_FREEZE_AWB, mLocalVersion);
+            wbFreeze.nTimeDelay = *((uint32_t*)param);
+
+            omxError = OMX_SetConfig( mCurGreContext.mHandleComp, (OMX_INDEXTYPE)OMX_TI_IndexConfigFreezeAWB, &wbFreeze );
+            break;
+        }
+
+        case VCAM_CMD_FREEZE_AGC_PARAMS:
+        {
+            OMX_TI_CONFIG_FREEZE_AE aeFreeze;
+            OMX_STRUCT_INIT( aeFreeze, OMX_TI_CONFIG_FREEZE_AE, mLocalVersion);
+            aeFreeze.nTimeDelay = *((uint32_t*)param);
+
+            omxError = OMX_SetConfig( mCurGreContext.mHandleComp, (OMX_INDEXTYPE)OMX_TI_IndexConfigFreezeAutoExp, &aeFreeze );
+            break;
+        }
+#endif
+        case VCAM_CMD_SET_CLIENT_NOTIFICATION_CALLBACK:
+        {
+            mClientNotifier.mNotificationCallback = (VisionCamClientNotifier::VisionCamClientNotifierCallback)(param);
+            break;
+        }
+
+        case VCAM_CMD_PACK_FRAMES:
+        {
+            mUseFramePackaging = *((bool*)param);
+            break;
+        }
+
+        default:
+        {
+            ERROR("Impossible command id requested: %d", cmdId);
+            ERROR("see VisionCamParam_e for possible command ids");
+            greError = -EINVAL;
+        }
+    }
+
+    if (greError == 0)
+        greError = ConvertError(omxError);
+
+    if (greError != 0)
+    {
+        ERROR("OMXVisionCam::sendCommand() exits with error %d for command id %d", greError, cmdId);
+    }
+
+    return greError;
+}
+
+/*
+*  APIs to configure Vision Cam
+*/
+int OMXVisionCam::setParameter( VisionCamParam_e paramId, void* param, uint32_t size, VisionCamPort_e port)
+{
+    int greError = 0;
+    OMX_ERRORTYPE omxError = OMX_ErrorNone;
+
+    AutoLock lock(&mUserRequestLock);
+
+    if (param == NULL || size == 0 || port >= VCAM_PORT_MAX)
+    {
+        ERROR("NULL param pointer passed to %s()",__func__);
+        return -EINVAL;
+    }
+    else
+    {
+        MSG("SET PARAM: 0x%04x, %p, %zu (0x%08x), %d", paramId, param, size, (size==4?*(uint32_t *)param:0), port);
+    }
+
+    if (getComponentState() == OMX_StateInvalid)
+        return -EBADE;
+
+    switch( paramId )
+    {
+        case VCAM_PARAM_HEIGHT:
+        {
+            int32_t p;
+            LOOP_PORTS( port , p )
+                mCurGreContext.mCameraPortParams[p].mHeight = *((OMX_U32*)param);
+            break;
+        }
+
+        case VCAM_PARAM_WIDTH:
+        {
+            int32_t p;
+            LOOP_PORTS( port , p )
+                    mCurGreContext.mCameraPortParams[p].mWidth = *((OMX_U32*)param);
+            break;
+        }
+
+
+        case VCAM_PARAM_COLOR_SPACE_FOURCC:
+        {
+            uint32_t color = *((uint32_t*)param);
+            switch (color) {
+                case FOURCC('U','Y','V','Y'):
+                case FOURCC('Y','U','Y','V'):
+                    mCurGreContext.mCameraPortParams[port].mColorFormat =
+                        OMX_COLOR_FormatCbYCrY;
+                    break;
+                case FOURCC('N','V','1','2'):
+                    mCurGreContext.mCameraPortParams[port].mColorFormat =
+                        OMX_COLOR_FormatYUV420SemiPlanar;
+                    break;
+                default:
+                    greError = -EINVAL;
+            }
+            if (greError == 0) {
+                int32_t p;
+                LOOP_PORTS(port , p) {
+                    OMX_PARAM_PORTDEFINITIONTYPE portCheck;
+                    omxError = initPortCheck( &portCheck, p );
+                    portCheck.format.video.eColorFormat =
+                        mCurGreContext.mCameraPortParams[port].mColorFormat;
+                    omxError = OMX_SetParameter(mCurGreContext.mHandleComp,
+                        OMX_IndexParamPortDefinition, &portCheck);
+                }
+            }
+            break;
+        }
+
+        case VCAM_PARAM_DO_AUTOFOCUS:
+        {
+            if (OMX_StateExecuting == getComponentState())
+            {
+                greError = startAutoFocus( *((VisionCamFocusMode*)param) );
+            }
+            else
+            {
+                greError = ConvertError(OMX_ErrorIncorrectStateOperation);
+            }
+            break;
+        }
+
+        case VCAM_PARAM_DO_MANUALFOCUS:
+        {
+            if (OMX_StateExecuting == getComponentState())
+            {
+                mManualFocusDistance = *((uint32_t*)param);
+                greError = startAutoFocus( VCAM_FOCUS_CONTROL_ON );
+            }
+            else
+            {
+                greError = ConvertError(OMX_ErrorIncorrectStateOperation);
+            }
+            break;
+        }
+
+        case VCAM_PARAM_BRIGHTNESS:
+        {
+            OMX_CONFIG_BRIGHTNESSTYPE brightness;
+            brightness.nSize = sizeof(OMX_CONFIG_BRIGHTNESSTYPE);
+            brightness.nBrightness = *((int*)param);
+            memcpy( &brightness.nVersion, mLocalVersion, sizeof(mLocalVersion) );
+
+            int32_t p = port;
+//            LOOP_PORTS( port , p )
+            {
+                brightness.nPortIndex = mCurGreContext.mPortsInUse[p];
+                omxError = OMX_SetConfig( mCurGreContext.mHandleComp, OMX_IndexConfigCommonBrightness, &brightness);
+            }
+            break;
+        }
+
+        case VCAM_PARAM_CONTRAST:
+        {
+            OMX_CONFIG_CONTRASTTYPE contrast;
+            contrast.nSize = sizeof( OMX_CONFIG_CONTRASTTYPE );
+            contrast.nContrast = *((int*)param);
+            memcpy( &contrast.nVersion, mLocalVersion, sizeof(mLocalVersion) );
+
+            int32_t p = port;
+//            LOOP_PORTS( port , p )
+            {
+                contrast.nPortIndex = mCurGreContext.mPortsInUse[p];
+                omxError = OMX_SetConfig( mCurGreContext.mHandleComp, OMX_IndexConfigCommonContrast, &contrast);
+            }
+            break;
+        }
+
+        case VCAM_PARAM_SHARPNESS:
+        {
+            OMX_IMAGE_CONFIG_PROCESSINGLEVELTYPE procSharpness;
+            procSharpness.nSize = sizeof( OMX_IMAGE_CONFIG_PROCESSINGLEVELTYPE );
+            procSharpness.nLevel = *((int*)param);
+            memcpy( &procSharpness.nVersion, mLocalVersion, sizeof(mLocalVersion) );
+
+            if( procSharpness.nLevel == 0 )
+                procSharpness.bAuto = OMX_TRUE;
+            else
+                procSharpness.bAuto = OMX_FALSE;
+
+            int32_t p = port;
+//            LOOP_PORTS( port , p )
+            {
+                procSharpness.nPortIndex = mCurGreContext.mPortsInUse[p];
+                omxError = OMX_SetConfig( mCurGreContext.mHandleComp, (OMX_INDEXTYPE)OMX_IndexConfigSharpeningLevel, &procSharpness);
+            }
+            break;
+        }
+
+        case VCAM_PARAM_SATURATION:
+        {
+            OMX_CONFIG_SATURATIONTYPE saturation;
+            saturation.nSize = sizeof(OMX_CONFIG_SATURATIONTYPE);
+            saturation.nSaturation = *((int*)param);
+            memcpy( &saturation.nVersion, mLocalVersion, sizeof(mLocalVersion) );
+
+            int32_t p = port;
+//            LOOP_PORTS( port , p )
+            {
+                saturation.nPortIndex = mCurGreContext.mPortsInUse[p];
+                omxError = OMX_SetConfig( mCurGreContext.mHandleComp,
+                                          OMX_IndexConfigCommonSaturation,
+                                          &saturation
+                                        );
+            }
+            break;
+        }
+
+        case VCAM_PARAM_FPS_FIXED:
+        {
+            bool enableAgain[VCAM_PORT_MAX];
+
+            int32_t p;
+            LOOP_PORTS(VCAM_PORT_ALL , p)
+                enableAgain[p] = mCurGreContext.mCameraPortParams[p].mIsActive;
+
+            stopPreview(VCAM_PORT_ALL);
+            int32_t i;
+            LOOP_PORTS(VCAM_PORT_ALL , i)
+            {
+                mCurGreContext.mCameraPortParams[i].mFrameRate = (*((int*)param));
+                if( enableAgain[i] )
+                    startPreview( (VisionCamPort_e)i );
+            }
+
+            break;
+        }
+
+        case VCAM_PARAM_FPS_VAR:
+        {
+            VisionCamVarFramerateType varFrate;
+            memcpy( &varFrate , param , sizeof( VisionCamVarFramerateType ) );
+
+            bool enableAgain[VCAM_PORT_MAX];
+
+            int32_t p;
+            LOOP_PORTS( VCAM_PORT_ALL , p )
+            {
+                enableAgain[p] = mCurGreContext.mCameraPortParams[p].mIsActive;
+            }
+
+            stopPreview(VCAM_PORT_ALL);
+
+            if( varFrate.mMin != 0 )
+            {
+              // @todo implement when needed OMX interface is present
+                varFrate = varFrate;
+            }
+
+            int32_t i;
+            LOOP_PORTS( VCAM_PORT_ALL , i )
+            {
+                mCurGreContext.mCameraPortParams[i].mFrameRate = varFrate.mMax;
+                if( enableAgain[i] )
+                    startPreview( (VisionCamPort_e)i );
+            }
+            break;
+        }
+
+        case VCAM_PARAM_FLICKER:
+        {
+            OMX_CONFIG_FLICKERCANCELTYPE flicker;
+            flicker.nSize = sizeof( OMX_CONFIG_FLICKERCANCELTYPE );
+            memcpy( &flicker.nVersion, mLocalVersion, sizeof(mLocalVersion) );
+            flicker.eFlickerCancel = *(OMX_COMMONFLICKERCANCELTYPE *)param;
+
+            int32_t p = port;
+//            LOOP_PORTS( VCAM_PORT_ALL , p )
+            {
+                flicker.nPortIndex = mCurGreContext.mPortsInUse[p];
+                omxError = OMX_SetConfig( mCurGreContext.mHandleComp, (OMX_INDEXTYPE)OMX_IndexConfigFlickerCancel, &flicker );
+            }
+            break;
+        }
+
+        case VCAM_PARAM_CROP:
+        {
+            OMX_CONFIG_RECTTYPE crop;
+            crop.nSize = sizeof( OMX_CONFIG_RECTTYPE );
+            crop.nLeft = ((VisionCamRectType*)param)->mLeft;
+            crop.nTop = ((VisionCamRectType*)param)->mTop;
+            crop.nWidth = ((VisionCamRectType*)param)->mWidth;
+            crop.nHeight = ((VisionCamRectType*)param)->mHeight;
+            memcpy( &crop.nVersion,  mLocalVersion, sizeof(mLocalVersion) );
+
+            int32_t p = port;
+//            LOOP_PORTS( port , p )
+            {
+                crop.nPortIndex = mCurGreContext.mPortsInUse[p];
+                omxError = OMX_SetConfig( mCurGreContext.mHandleComp, OMX_IndexConfigCommonOutputCrop, &crop );
+            }
+            break;
+        }
+
+        case VCAM_PARAM_STEREO_INFO:
+        {
+            VisionCamStereoInfo *info = (VisionCamStereoInfo *)param;
+            OMX_TI_FRAMELAYOUTTYPE frameLayout;
+            OMX_STRUCT_INIT(frameLayout, OMX_TI_FRAMELAYOUTTYPE, mLocalVersion);
+            OMX_TI_CONFIG_CONVERGENCETYPE acParams;
+            OMX_STRUCT_INIT(acParams, OMX_TI_CONFIG_CONVERGENCETYPE, mLocalVersion);
+            if ( info && size == sizeof(VisionCamStereoInfo))
+            {
+                int32_t p = port;
+//                LOOP_PORTS( port , p )
+                {
+                    frameLayout.nPortIndex = mCurGreContext.mPortsInUse[p];
+                    MSG("Stereo Info: Layout %u, SubSampling: %u", info->layout, info->subsampling);
+
+                    frameLayout.eFrameLayout = (OMX_TI_STEREOFRAMELAYOUTTYPE)getLutValue( (int)info->layout, VCAM_VALUE_TYPE,
+                                                                                            StereoLayoutLUT, ARR_SIZE(StereoLayoutLUT)
+                                                                                        );
+                    if (info->layout == VCAM_STEREO_LAYOUT_TOPBOTTOM)
+                        frameLayout.eFrameLayout = OMX_TI_StereoFrameLayoutTopBottom;
+                    else if (info->layout == VCAM_STEREO_LAYOUT_LEFTRIGHT)
+                        frameLayout.eFrameLayout = OMX_TI_StereoFrameLayoutLeftRight;
+                    frameLayout.nSubsampleRatio = info->subsampling << 7; // in Q15.7 format
+                    omxError = OMX_SetParameter( mCurGreContext.mHandleComp,
+                                                 (OMX_INDEXTYPE)OMX_TI_IndexParamStereoFrmLayout,
+                                                 &frameLayout
+                                                );
+
+                    if( OMX_ErrorNone == omxError )
+                    {
+                        acParams.nPortIndex = mCurGreContext.mPortsInUse[p];
+
+                        acParams.nManualConverence = 0;
+                        acParams.eACMode = OMX_TI_AutoConvergenceModeDisable;
+
+                        omxError = OMX_SetConfig( mCurGreContext.mHandleComp,
+                                                  (OMX_INDEXTYPE)OMX_TI_IndexConfigAutoConvergence,
+                                                  &acParams
+                                                 );
+                        if( OMX_ErrorNone != omxError )
+                        {
+                            ERROR("ERROR OMXVisionCam: Failed to disable auto convergence.");
+                        }
+                    }
+                    else
+                    {
+                        ERROR("ERROR OMXVisionCam: Failed to set stero layout");
+                    }
+                }
+            }
+            else
+            {
+                ERROR("ERROR OMXVisionCam: attempt to set param with id VCAM_PARAM_STEREO_INFO with an invalid args");
+                greError = -EINVAL;
+            }
+            break;
+        }
+
+        case VCAM_PARAM_CAP_MODE:
+        {
+            if (param != NULL)
+            {
+                VisionCamCaptureMode mode = *(VisionCamCaptureMode *)param;
+
+                OMX_CONFIG_CAMOPERATINGMODETYPE opMode;
+                opMode.nSize = sizeof( OMX_CONFIG_CAMOPERATINGMODETYPE );
+                memcpy( &opMode.nVersion, mLocalVersion, sizeof(mLocalVersion) );
+
+                opMode.eCamOperatingMode = (OMX_CAMOPERATINGMODETYPE)getLutValue(mode, VCAM_VALUE_TYPE, CaptureModeLUT, ARR_SIZE(CaptureModeLUT) );
+
+                MSG("Requested VisionCamCaptureMode %d", mode);
+                MSG("Requested OMX_CAMOPERATINGMODETYPE %d", opMode.eCamOperatingMode);
+
+                bool enableAgain[VCAM_PORT_MAX];
+
+                int32_t p;// mark and stop all working ports
+                LOOP_PORTS( VCAM_PORT_ALL , p )
+                {
+                    enableAgain[p] = mCurGreContext.mCameraPortParams[p].mIsActive;
+                    if( mCurGreContext.mCameraPortParams[p].mIsActive )
+                        portEnableDisable(OMX_CommandPortDisable, freePortBuffersSrvc, (VisionCamPort_e)p );
+                }
+
+                int32_t oldstate = getComponentState();
+                for(int32_t st = oldstate - 1; st >= OMX_StateLoaded; st--)
+                {
+                    if( OMX_StatePause == oldstate  && OMX_StateExecuting == st )
+                        continue;
+
+                    transitToState( (OMX_STATETYPE)st );
+                }
+
+                if( OMX_StateLoaded == getComponentState() || OMX_StateWaitForResources == getComponentState() )
+                {
+                    omxError = OMX_SetParameter( mCurGreContext.mHandleComp,
+                                                 (OMX_INDEXTYPE)OMX_IndexCameraOperatingMode,
+                                                 &opMode );
+
+                    greError = ConvertError(omxError);
+                }
+
+                for(int32_t st = (1 + getComponentState()); st <= oldstate; st++)
+                {
+                    if( OMX_StatePause == oldstate && OMX_StateExecuting == st)
+                        continue;
+
+                    transitToState( (OMX_STATETYPE)st );
+                }
+
+                int32_t por;
+                LOOP_PORTS( VCAM_PORT_ALL , por )
+                    if( enableAgain[por])
+                    {
+                        portEnableDisable(OMX_CommandPortEnable, populatePortSrvc, (VisionCamPort_e)por);
+                        fillPortBuffers((VisionCamPort_e)por);
+                    }
+            }
+            else
+                greError = -EINVAL;
+            break;
+        }
+
+        case VCAM_PARAM_SENSOR_SELECT:
+        {
+            if (param != NULL)
+            {
+                OMX_CONFIG_SENSORSELECTTYPE sensor;
+                OMX_STRUCT_INIT(sensor, OMX_CONFIG_SENSORSELECTTYPE, mLocalVersion);
+                sensor.nPortIndex = mCurGreContext.mPortsInUse[VCAM_PORT_ALL];
+                sensor.eSensor = *((OMX_SENSORSELECT*)param);
+                MSG("Selecting sensor index = %u", sensor.eSensor);
+                omxError = OMX_SetConfig( mCurGreContext.mHandleComp, (OMX_INDEXTYPE)OMX_TI_IndexConfigSensorSelect, &sensor);
+            }
+            else
+                greError = -EINVAL;
+            break;
+        }
+
+        case VCAM_PARAM_EXPOSURE_COMPENSATION:
+        {
+            OMX_CONFIG_EXPOSUREVALUETYPE expValues;
+            OMX_STRUCT_INIT(expValues, OMX_CONFIG_EXPOSUREVALUETYPE, mLocalVersion);
+
+            memcpy( &expValues.nVersion , mLocalVersion , sizeof( *mLocalVersion ) );
+            omxError = OMX_GetConfig( mCurGreContext.mHandleComp , OMX_IndexConfigCommonExposureValue , &expValues );
+
+            if( OMX_ErrorNone == omxError )
+            {
+                int compVal = *((int*)param);
+                expValues.xEVCompensation = ( compVal * ( 1 << 16 ) )  / 10;
+
+                int32_t p = port;
+//                LOOP_PORTS( port , p )
+                {
+                    expValues.nPortIndex = mCurGreContext.mPortsInUse[p];
+                    omxError = OMX_SetConfig( mCurGreContext.mHandleComp , OMX_IndexConfigCommonExposureValue , &expValues );
+                }
+            }
+            break;
+        }
+
+        case VCAM_PARAM_RESOLUTION:
+        {
+            if( param != NULL )
+            {
+                int res;
+
+                if( *((int*)param) < 0 || *((int*)param) >= VCAM_RESOL_MAX )
+                {
+                   greError = -EINVAL;
+                   break;
+                }
+
+                int32_t p = port;
+                LOOP_PORTS( port , p )
+                {
+                    res = *((int*)param);
+                    if( 0 == greError )
+                        if( mCurGreContext.mCameraPortParams[p].mIsActive )
+                            greError = -EBADE;
+
+                    if( 0 == greError )
+                    {
+                            if( VCAM_PORT_VIDEO == p
+                                && ( VisionCamResolutions[res].mWidth > VisionCamResolutions[VCAM_RES_VGA].mWidth
+                                || VisionCamResolutions[res].mHeight > VisionCamResolutions[VCAM_RES_VGA].mHeight ) )
+                            {
+                                res = VCAM_RES_VGA;
+                            }
+
+                        mCurGreContext.mCameraPortParams[p].mWidth = VisionCamResolutions[res].mWidth;
+                        mCurGreContext.mCameraPortParams[p].mHeight = VisionCamResolutions[res].mHeight;
+                    }
+                }
+            }
+            else
+                greError = -EINVAL;
+
+            break;
+        }
+
+        case VCAM_PARAM_MANUAL_EXPOSURE:
+        {
+            OMX_CONFIG_EXPOSUREVALUETYPE expValues;
+            OMX_STRUCT_INIT(expValues, OMX_CONFIG_EXPOSUREVALUETYPE, mLocalVersion);
+            int32_t p = port;
+
+//            LOOP_PORTS( port , p )
+            {
+                expValues.nPortIndex = mCurGreContext.mPortsInUse[p];
+                omxError = OMX_GetConfig( mCurGreContext.mHandleComp , OMX_IndexConfigCommonExposureValue , &expValues );
+
+                if( OMX_ErrorNone == omxError )
+                {
+                    if( *(OMX_U32*)param )
+                    {
+                        expValues.nShutterSpeedMsec = *(OMX_U32*)param;
+                        expValues.bAutoShutterSpeed = OMX_FALSE;
+                    }
+                    else
+                        expValues.bAutoShutterSpeed = OMX_TRUE;
+
+                    omxError = OMX_SetConfig( mCurGreContext.mHandleComp , OMX_IndexConfigCommonExposureValue , &expValues );
+                }
+            }
+            break;
+        }
+
+        case VCAM_PARAM_EXPOSURE_ISO:
+        {
+            OMX_CONFIG_EXPOSUREVALUETYPE expValues;
+            OMX_STRUCT_INIT(expValues, OMX_CONFIG_EXPOSUREVALUETYPE, mLocalVersion);
+            int32_t p = port;
+//            LOOP_PORTS( port , p )
+            {
+
+                expValues.nPortIndex = mCurGreContext.mPortsInUse[p];
+                omxError = OMX_GetConfig(mCurGreContext.mHandleComp, OMX_IndexConfigCommonExposureValue, &expValues);
+                if( OMX_ErrorNone == omxError )
+                {
+                    if( *(OMX_U32*)param )
+                    {
+                        expValues.nSensitivity = *(OMX_U32*)param;
+                        expValues.bAutoSensitivity = OMX_FALSE;
+                    }
+                    else
+                        expValues.bAutoSensitivity = OMX_TRUE;
+
+                    omxError = OMX_SetConfig( mCurGreContext.mHandleComp , OMX_IndexConfigCommonExposureValue , &expValues );
+                }
+            }
+            break;
+        }
+
+        case VCAM_PARAM_AWB_MODE:
+        {
+            OMX_CONFIG_WHITEBALCONTROLTYPE wb;
+            OMX_STRUCT_INIT(wb, OMX_CONFIG_WHITEBALCONTROLTYPE, mLocalVersion);
+
+            int32_t p = port;
+//            LOOP_PORTS( port , p )
+            {
+                wb.nPortIndex = mCurGreContext.mPortsInUse[p];
+                wb.eWhiteBalControl = *(OMX_WHITEBALCONTROLTYPE *)param;
+                omxError = OMX_SetConfig( mCurGreContext.mHandleComp,
+                                        OMX_IndexConfigCommonWhiteBalance,
+                                        &wb);
+            }
+            break;
+        }
+
+        case VCAM_PARAM_COLOR_TEMP:
+        {
+            OMX_CONFIG_WHITEBALCONTROLTYPE wb;
+            OMX_STRUCT_INIT(wb, OMX_CONFIG_WHITEBALCONTROLTYPE, mLocalVersion);
+
+            if( 0 == *(int*)param )
+                wb.eWhiteBalControl = OMX_WhiteBalControlAuto;
+            else
+                wb.eWhiteBalControl = OMX_WhiteBalControlOff; // @todo change to manual when proper OMX headers arrive
+
+            int32_t p = port;
+//            LOOP_PORTS( port , p )
+            {
+                wb.nPortIndex = mCurGreContext.mPortsInUse[p];
+                omxError = OMX_SetConfig( mCurGreContext.mHandleComp,
+                                     OMX_IndexConfigCommonWhiteBalance,
+                                     &wb );
+            }
+            break;
+        }
+
+        case VCAM_PARAM_WB_COLOR_GAINS:
+        {
+#ifdef USE_WB_GAIN_PATCH
+            VisionCamWhiteBalGains wbGains = *((VisionCamWhiteBalGains*)param);
+            uint16_t * tmp;
+            CALCULATE_WB_GAINS_OFFSET(uint16_t,mWBbuffer,tmp);
+
+            tmp[ RED ] = wbGains.mRed;
+            tmp[ GREEN_RED ] = wbGains.mGreen_r;
+            tmp[ GREEN_BLUE ] = wbGains.mGreen_b;
+            tmp[ BLUE ] = wbGains.mBlue;
+
+            OMX_TI_CONFIG_SHAREDBUFFER skipBuffer;
+            skipBuffer.nSize = sizeof( OMX_TI_CONFIG_SHAREDBUFFER );
+            memcpy( &skipBuffer.nVersion , mLocalVersion , sizeof(mLocalVersion) );
+
+            if( wbGains.mRed >= COLOR_GAIN_MIN &&  wbGains.mRed <= COLOR_GAIN_MAX
+                && wbGains.mGreen_b >= COLOR_GAIN_MIN && wbGains.mGreen_b <= COLOR_GAIN_MAX
+                && wbGains.mGreen_r >= COLOR_GAIN_MIN && wbGains.mGreen_r <= COLOR_GAIN_MAX
+                && wbGains.mBlue >= COLOR_GAIN_MIN && wbGains.mBlue <= COLOR_GAIN_MAX )
+            {
+                skipBuffer.pSharedBuff = (OMX_U8*)mWBbuffer;
+                skipBuffer.nSharedBuffSize = sizeof(mWBbuffer);
+            }
+            else if( !wbGains.mRed && !wbGains.mGreen_b && !wbGains.mGreen_r && !wbGains.mBlue )
+            {   /// all gains are zero => auto mode
+                skipBuffer.pSharedBuff = (OMX_U8*)mWBresetBuffer;
+                skipBuffer.nSharedBuffSize = sizeof(mWBresetBuffer);
+            }
+            else
+            {
+                greError = -EINVAL;
+                break;
+            }
+
+            int32_t p = port;
+//            LOOP_PORTS(port, p)
+            {
+                skipBuffer.nPortIndex = p;
+                omxError = OMX_SetConfig( mCurGreContext.mHandleComp,
+                                        (OMX_INDEXTYPE) OMX_TI_IndexConfigAAAskipBuffer,
+                                        &skipBuffer );
+            }
+#endif // USE_WB_GAIN_PATCH
+            break;
+        }
+
+        case VCAM_PARAM_GAMMA_TBLS:
+        {
+            VisionCamGammaTableType *gammaTbl = (VisionCamGammaTableType*)(param);
+            OMX_TI_CONFIG_SHAREDBUFFER skipBuffer;
+            OMX_STRUCT_INIT(skipBuffer, OMX_TI_CONFIG_SHAREDBUFFER, mLocalVersion);
+
+            uint32_t* base = (uint32_t *)(mGammaTablesBuf + 12); // 12 bytes offset for first table
+            uint16_t *redTbl      = (uint16_t*)(base[0] + (uint32_t)&base[2]);
+            uint16_t *blueTbl     = (uint16_t*)(base[1] + (uint32_t)&base[2]);
+            uint16_t *greenTbl    = (uint16_t*)(base[2] + (uint32_t)&base[2]);
+
+#ifdef _USE_GAMMA_RESET_HC_
+            if( !mGammaResetPolulated )
+            {
+                skipBuffer.pSharedBuff = (OMX_U8*)mGammaResetTablesBuf;
+                skipBuffer.nSharedBuffSize = sizeof(mGammaResetTablesBuf);
+                omxError = OMX_GetConfig( mCurGreContext.mHandleComp,
+                                    (OMX_INDEXTYPE) OMX_TI_IndexConfigAAAskipBuffer,
+                                    &skipBuffer );
+
+                if( OMX_ErrorNone == omxError )
+                    mGammaResetPolulated = true;
+            }
+#endif // _USE_GAMMA_RESET_HC_
+
+            if( gammaTbl->mRedTable && gammaTbl->mGreenTable && gammaTbl->mBlueTable )
+            {
+                if( gammaTbl->mRedTable != redTbl )
+                {
+                    memcpy(redTbl, gammaTbl->mRedTable, GAMMA_TABLE_SIZE );
+                }
+
+                if( gammaTbl->mGreenTable != greenTbl )
+                {
+                    memcpy(greenTbl, gammaTbl->mGreenTable, GAMMA_TABLE_SIZE );
+                }
+
+                if( gammaTbl->mBlueTable != blueTbl )
+                {
+                    memcpy(blueTbl, gammaTbl->mBlueTable, GAMMA_TABLE_SIZE );
+                }
+
+                skipBuffer.pSharedBuff = (OMX_U8*)mGammaTablesBuf;
+                skipBuffer.nSharedBuffSize = sizeof(mGammaTablesBuf)/sizeof(mGammaTablesBuf[0]);
+            }
+            else
+            {
+#ifdef _USE_GAMMA_RESET_HC_
+                if( mGammaResetPolulated )
+                {
+                    skipBuffer.pSharedBuff = (OMX_U8*)mGammaResetTablesBuf;
+                    skipBuffer.nSharedBuffSize = sizeof(mGammaResetTablesBuf)/sizeof(mGammaResetTablesBuf[0]);
+                }
+                else
+                {
+                    ERROR("No data present in reset Gamma Tables. Leaving Gamma unchanged!!!");
+                }
+#else
+                skipBuffer.pSharedBuff = (OMX_U8*)mGammaResetTablesBuf;
+                skipBuffer.nSharedBuffSize = sizeof(mGammaResetTablesBuf)/sizeof(mGammaResetTablesBuf[0]);
+#endif // _USE_GAMMA_RESET_HC_
+            }
+
+            omxError = OMX_SetConfig( mCurGreContext.mHandleComp,
+                                    (OMX_INDEXTYPE) OMX_TI_IndexConfigAAAskipBuffer,
+                                    &skipBuffer );
+
+            break;
+        }
+
+#if defined(VCAM_SET_FORMAT_ROTATION)
+        case VCAM_PARAM_ROTATION:
+        {
+            int32_t p;
+            LOOP_PORTS( port , p )
+            {
+                mCurGreContext.mCameraPortParams[p].mRotation = *((OMX_S32 *)param);
+            }
+            break;
+        }
+#else
+        case VCAM_PARAM_ROTATION:
+        {
+            OMX_CONFIG_ROTATIONTYPE rotation;
+            OMX_STRUCT_INIT(rotation, OMX_CONFIG_ROTATIONTYPE, mLocalVersion);
+            rotation.nRotation = *((OMX_S32*)param);
+
+            int32_t p;
+            LOOP_PORTS( port , p )
+            {
+                rotation.nPortIndex = mCurGreContext.mPortsInUse[p];
+                OMX_CHECK(omxError, OMX_SetConfig(mCurGreContext.mHandleComp,
+                                                  OMX_IndexConfigCommonRotate,
+                                                  &rotation));
+                MSG("Setting Rotation to %ld (size: %u)", rotation.nRotation, sizeof(rotation));
+            }
+            break;
+        }
+#endif
+        case VCAM_PARAM_MIRROR:
+        {
+            int i;
+            OMX_CONFIG_MIRRORTYPE mirror;
+            OMX_STRUCT_INIT(mirror, OMX_CONFIG_MIRRORTYPE, mLocalVersion);
+
+            for( i = 0; i < VCAM_MIRROR_MAX; i++ )
+            {
+                if( MirrorTypeLUT[i][0] == *((VisionCamMirrorType*)param) )
+                {
+                  mirror.eMirror = (OMX_MIRRORTYPE) MirrorTypeLUT[i][1];
+                  break;
+                }
+            }
+
+            if( i < VCAM_MIRROR_MAX )
+            {
+                int32_t p;
+                LOOP_PORTS( port , p )
+                {
+                    mirror.nPortIndex = mCurGreContext.mPortsInUse[p];
+                    omxError = OMX_SetConfig( mCurGreContext.mHandleComp,
+                                            OMX_IndexConfigCommonMirror,
+                                            &mirror );
+                }
+            }
+            else
+                greError = -EINVAL;
+            break;
+        }
+
+#if ( defined(DUCATI_1_5) || defined(DUCATI_2_0) ) && defined(OMX_CAMERA_SUPPORTS_MANUAL_CONTROLS)
+        case VCAM_PARAM_AWB_MIN_DELAY_TIME:
+        {
+            uint32_t timeDelay = *((uint32_t*)param);
+            if( timeDelay > AE_Delay_Time_Max )
+            {
+                greError = -EINVAL;
+            }
+            else
+            {
+                OMX_TI_CONFIG_AE_DELAY aeDelay;
+                OMX_STRUCT_INIT( aeDelay, OMX_TI_CONFIG_AE_DELAY, mLocalVersion );
+                aeDelay.nDelayTime = timeDelay;
+
+                int32_t p = port;
+//                LOOP_PORTS( port , p )
+                {
+                    aeDelay.nPortIndex = p;
+                    omxError = OMX_SetConfig( mCurGreContext.mHandleComp,
+                                                ( OMX_INDEXTYPE )OMX_TI_IndexConfigAutoExpMinDelayTime,
+                                                &aeDelay
+                                            );
+                }
+            }
+            break;
+        }
+#endif
+#if ( defined(DUCATI_1_5) || defined(DUCATI_2_0) ) && defined(OMX_CAMERA_SUPPORTS_GESTURES)
+        case VCAM_PARAM_GESTURES_INFO:
+        {
+            VisionCamGestureInfo *info = (VisionCamGestureInfo*)param;
+            if( info->mGestureType >= VCAM_GESTURE_EVENT_MAX || info->mGestureType < VCAM_GESTURE_EVENT_INVALID )
+            {
+                greError= -EINVAL;
+            }
+
+            if( info->mRegionsNum >= VCAM_Max_Gesture_Per_Frame )
+            {
+                greError= -EINVAL;
+            }
+
+            if( 0 == greError )
+            {
+                OMX_TI_CONFIG_GESTURES_INFO gestInfo;
+                OMX_STRUCT_INIT( gestInfo, OMX_TI_CONFIG_GESTURES_INFO , mLocalVersion );
+
+                gestInfo.nTimeStamp = info->timeStamp;
+                gestInfo.nNumDetectedGestures = info->mRegionsNum;
+                gestInfo.eType = (OMX_TI_GESTURES_TYPE)getLutValue( info->mGestureType, VCAM_VALUE_TYPE,
+                                                                    GestureTypeLUT, ARR_SIZE(GestureTypeLUT)
+                                                                    );
+
+                for(uint32_t i = 0; i < info->mRegionsNum ; i++ )
+                {
+                      OMX_STRUCT_INIT(gestInfo.nGestureAreas[i], OMX_CONFIG_OBJECT_RECT_TYPE , mLocalVersion );
+                      gestInfo.nGestureAreas[i].eType = (OMX_TI_OBJECT_TYPE)getLutValue( (int)(info->mRegions[i].mObjType), VCAM_VALUE_TYPE,
+                                                                                         ObjectTypeLUT, ARR_SIZE(ObjectTypeLUT)
+                                                                                        );
+
+                      gestInfo.nGestureAreas[i].nTop = info->mRegions[i].mTop;
+                      gestInfo.nGestureAreas[i].nLeft = info->mRegions[i].mLeft;
+                      gestInfo.nGestureAreas[i].nWidth = info->mRegions[i].mWidth;
+                      gestInfo.nGestureAreas[i].nHeight = info->mRegions[i].mHeight;
+                }
+
+                if( OMX_TI_GESTURE_NO_GESTURE != gestInfo.eType)
+                {
+                    int32_t p = port;
+//                    LOOP_PORTS( port , p )
+                    {
+                        gestInfo.nPortIndex = mCurGreContext.mPortsInUse[p];
+                        omxError = OMX_SetConfig( mCurGreContext.mHandleComp,
+                                                (OMX_INDEXTYPE)OMX_TI_IndexConfigDetectedGesturesInfo,
+                                                &gestInfo
+                                              );
+                    }
+                }
+                else
+                    greError = -EINVAL;
+            }
+
+            break;
+        }
+#endif
+#if ( defined(DUCATI_1_5) || defined(DUCATI_2_0) ) && defined(OMX_CAMERA_SUPPORTS_MANUAL_CONTROLS)
+        case VCAM_PARAM_AGC_MIN_DELAY_TIME:
+        {
+            int32_t delay = *((int32_t*)param);
+            OMX_TI_CONFIG_AE_DELAY agcDelTime;
+            OMX_STRUCT_INIT( agcDelTime, OMX_TI_CONFIG_AE_DELAY, mLocalVersion );
+            agcDelTime.nDelayTime = delay;
+
+            int32_t p = port;
+//            LOOP_PORTS( port , p )
+            {
+                agcDelTime.nPortIndex = p;
+                omxError = OMX_SetConfig( mCurGreContext.mHandleComp,
+                                        (OMX_INDEXTYPE)OMX_TI_IndexConfigAutoExpMinDelayTime,
+                                        &agcDelTime );
+            }
+            break;
+        }
+
+        case VCAM_PARAM_AGC_LOW_TH:
+        {
+            int32_t lowTH = *((int32_t*)param);
+            OMX_TI_CONFIG_AE_THRESHOLD ae;
+
+            OMX_STRUCT_INIT( ae, OMX_TI_CONFIG_AE_THRESHOLD, mLocalVersion );
+
+            int32_t p = port;
+//            LOOP_PORTS( port , p )
+            {
+                ae.nPortIndex = p;
+                omxError = OMX_GetConfig( mCurGreContext.mHandleComp, (OMX_INDEXTYPE)OMX_TI_IndexConfigAutoExpThreshold, &ae );
+
+                if( OMX_ErrorNone == omxError )
+                {
+                    ae.uMinTH = lowTH;
+                    omxError = OMX_SetConfig( mCurGreContext.mHandleComp, (OMX_INDEXTYPE)OMX_TI_IndexConfigAutoExpThreshold, &ae );
+                }
+            }
+            break;
+        }
+        case VCAM_PARAM_AGC_HIGH_TH:
+        {
+            int32_t highTH = *((int32_t*)param);
+
+            OMX_TI_CONFIG_AE_THRESHOLD ae;
+            OMX_STRUCT_INIT( ae, OMX_TI_CONFIG_AE_THRESHOLD, mLocalVersion );
+
+            int32_t p = port;
+//            LOOP_PORTS( port , p )
+            {
+                ae.nPortIndex = p;
+                omxError = OMX_GetConfig( mCurGreContext.mHandleComp, (OMX_INDEXTYPE)OMX_TI_IndexConfigAutoExpThreshold, &ae );
+
+                if( OMX_ErrorNone == omxError )
+                {
+                    ae.uMaxTH = highTH;
+                    omxError = OMX_SetConfig( mCurGreContext.mHandleComp, (OMX_INDEXTYPE)OMX_TI_IndexConfigAutoExpThreshold, &ae );
+                }
+            }
+            break;
+        }
+#endif
+        case VCAM_PARAM_NAME:
+            // do nothing as this is not supported but it should not fail either
+            break;
+        default:
+        {
+            ERROR("Impossible parameter id requested: %d", paramId);
+            ERROR("see VisionCamParam_e for possible parameter ids");
+            greError = -ENOSYS;
+            if(paramId < VCAM_PARAM_MIN || paramId > VCAM_PARAM_MAX)
+                greError = -EINVAL;
+        }
+    }
+
+    if( OMX_ErrorNone != omxError )
+    {
+        greError = ConvertError(omxError);
+    }
+
+    if( greError != 0 )
+    {
+        ERROR("setParameter() exits with error 0x%x (dec: %d) [OMX:0x%08x] for param id 0x%x",
+                greError, greError, omxError, paramId);
+    }
+
+    return greError;
+}
+
+/*
+*  APIs to get configured Vision Cam parameters
+*/
+int OMXVisionCam::getParameter( VisionCamParam_e paramId, void* param, uint32_t size, VisionCamPort_e port)
+{
+    int greError = 0;
+    OMX_ERRORTYPE omxError = OMX_ErrorNone;
+
+    AutoLock lock(&mUserRequestLock);
+
+    if (param == NULL || size == 0 || port >= VCAM_PORT_MAX)
+    {
+        ERROR("NULL param pointer passed to %s", __func__);
+        return -EINVAL;
+    }
+    else
+    {
+        MSG("GET PARAM: 0x%04x, %p, %u (0x%08x)", paramId, param, size, (size==4?*(uint32_t *)param:0));
+    }
+
+    if( VCAM_PORT_ALL == port)
+    {
+        ERROR("%s called on port ALL. Please specifu a port!", __func__);
+        return -EINVAL;
+    }
+    switch( paramId )
+    {
+        case VCAM_PARAM_HEIGHT:
+        {
+            OMX_PARAM_PORTDEFINITIONTYPE portCheck;
+            omxError = initPortCheck( &portCheck , port );
+
+            if( OMX_ErrorNone == omxError )
+            {
+                *(int*)param = portCheck.format.video.nFrameHeight;
+            }
+            break;
+        }
+
+        case VCAM_PARAM_WIDTH:
+        {
+            OMX_PARAM_PORTDEFINITIONTYPE portCheck;
+            omxError = initPortCheck( &portCheck , port );
+
+            if( OMX_ErrorNone == omxError )
+            {
+                *(int*)param = portCheck.format.video.nFrameWidth;
+            }
+            break;
+        }
+
+        case VCAM_PARAM_COLOR_SPACE_FOURCC:
+        {
+            OMX_PARAM_PORTDEFINITIONTYPE portCheck;
+            omxError = initPortCheck(&portCheck, port);
+
+            switch (portCheck.format.video.eColorFormat) {
+                case OMX_COLOR_FormatCbYCrY:
+                    *((int*)param) = FOURCC('Y','U','Y','V');
+                    break;
+                case OMX_COLOR_FormatYUV420SemiPlanar:
+                    *((int*)param) = FOURCC('N','V','1','2');
+                    break;
+                default:
+                    greError = -EINVAL;
+            }
+            break;
+        }
+
+        case VCAM_PARAM_DO_AUTOFOCUS:
+        {
+            int i = 0;
+            OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE focus;
+            OMX_STRUCT_INIT(focus, OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE, mLocalVersion);
+
+            omxError = OMX_GetConfig(mCurGreContext.mHandleComp, OMX_IndexConfigFocusControl, &focus);
+            if( OMX_ErrorNone == omxError )
+            {
+                for( i = 0; i < VCAM_FOCUS_CONTROL_MAX; i++ )
+                {
+                    if ( FocusModeLUT[ i ][ 1 ] == focus.eFocusControl )
+                    {
+                        *(int*)param = FocusModeLUT[ i ][ 0 ];
+                        break;
+                    }
+                }
+                if( VCAM_FOCUS_CONTROL_MAX == i )
+                    greError = -EINVAL;
+            }
+
+            break;
+        }
+
+        case VCAM_PARAM_DO_MANUALFOCUS:
+        {
+            OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE focus;
+            OMX_STRUCT_INIT(focus, OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE, mLocalVersion);
+
+            omxError = OMX_GetConfig(mCurGreContext.mHandleComp, OMX_IndexConfigFocusControl, &focus);
+            if( OMX_ErrorNone == omxError )
+            {
+                (*(int*)param) = focus.nFocusSteps;
+            }
+            break;
+        }
+
+        case VCAM_PARAM_BRIGHTNESS:
+        {
+            OMX_CONFIG_BRIGHTNESSTYPE brightness;
+            OMX_STRUCT_INIT(brightness, OMX_CONFIG_BRIGHTNESSTYPE, mLocalVersion );
+
+            omxError = OMX_GetConfig( mCurGreContext.mHandleComp, OMX_IndexConfigCommonBrightness, &brightness);
+            if( OMX_ErrorNone == omxError )
+            {
+                *((uint32_t*)param) = brightness.nBrightness;
+            }
+            break;
+        }
+
+        case VCAM_PARAM_CONTRAST:
+        {
+            OMX_CONFIG_CONTRASTTYPE contrast;
+            OMX_STRUCT_INIT(contrast, OMX_CONFIG_CONTRASTTYPE, mLocalVersion );
+
+            omxError = OMX_GetConfig( mCurGreContext.mHandleComp, OMX_IndexConfigCommonContrast, &contrast);
+            if( OMX_ErrorNone == omxError )
+            {
+                *((int*)param) = contrast.nContrast;
+            }
+            break;
+        }
+
+        case VCAM_PARAM_SHARPNESS:
+        {
+            OMX_IMAGE_CONFIG_PROCESSINGLEVELTYPE procSharpness;
+            OMX_STRUCT_INIT( procSharpness, OMX_IMAGE_CONFIG_PROCESSINGLEVELTYPE, mLocalVersion );
+
+            omxError = OMX_GetConfig( mCurGreContext.mHandleComp, (OMX_INDEXTYPE)OMX_IndexConfigSharpeningLevel, &procSharpness);
+
+            if( OMX_ErrorNone == omxError )
+            {
+                if( OMX_TRUE == procSharpness.bAuto )
+                    *((int*)param) = 0;
+                else
+                    *((int*)param) = procSharpness.nLevel;
+            }
+            break;
+        }
+
+        case VCAM_PARAM_SATURATION:
+        {
+            OMX_CONFIG_SATURATIONTYPE saturation;
+            OMX_STRUCT_INIT(saturation, OMX_CONFIG_SATURATIONTYPE, mLocalVersion);
+            omxError = OMX_GetConfig( mCurGreContext.mHandleComp, OMX_IndexConfigCommonSaturation, &saturation);
+
+            if( OMX_ErrorNone == omxError )
+            {
+                *((int*)param) = saturation.nSaturation;
+            }
+            break;
+        }
+
+        case VCAM_PARAM_FPS_FIXED:
+        {
+            OMX_PARAM_PORTDEFINITIONTYPE portCheck;
+            omxError = initPortCheck( &portCheck , port );
+
+            if( OMX_ErrorNone == omxError )
+            {
+                *((uint32_t*)param) = portCheck.format.video.xFramerate >> 16;
+            }
+            break;
+        }
+
+        case VCAM_PARAM_FPS_VAR:
+        {
+            ERROR("No Getting Api for this Parameter %d", paramId);
+            break;
+        }
+
+        case VCAM_PARAM_FLICKER:
+        {
+            OMX_CONFIG_FLICKERCANCELTYPE flicker;
+            OMX_STRUCT_INIT( flicker, OMX_CONFIG_FLICKERCANCELTYPE, mLocalVersion );
+            omxError = OMX_GetConfig( mCurGreContext.mHandleComp, (OMX_INDEXTYPE)OMX_IndexConfigFlickerCancel, &flicker );
+
+            if( OMX_ErrorNone == omxError )
+            {
+                *((int*)param) = flicker.eFlickerCancel;
+            }
+            break;
+        }
+
+        case VCAM_PARAM_CROP:
+        {
+            OMX_CONFIG_RECTTYPE crop;
+            OMX_STRUCT_INIT(crop, OMX_CONFIG_RECTTYPE, mLocalVersion);
+
+            omxError = OMX_GetConfig( mCurGreContext.mHandleComp, OMX_IndexConfigCommonOutputCrop, &crop );
+
+            if( OMX_ErrorNone == omxError )
+            {
+                ((VisionCamRectType*)param)->mLeft = crop.nLeft;
+                ((VisionCamRectType*)param)->mTop = crop.nTop;
+                ((VisionCamRectType*)param)->mWidth = crop.nWidth;
+                ((VisionCamRectType*)param)->mHeight = crop.nHeight;
+            }
+          break;
+        }
+
+        case VCAM_PARAM_CAP_MODE:
+        {
+            if (param != NULL)
+            {
+                int i = 0;
+                OMX_CONFIG_CAMOPERATINGMODETYPE opMode;
+                opMode.nSize = sizeof(OMX_CONFIG_CAMOPERATINGMODETYPE);
+                memcpy(&opMode .nVersion, mLocalVersion , sizeof(OMX_VERSIONTYPE));
+
+                omxError = OMX_GetParameter( mCurGreContext.mHandleComp, (OMX_INDEXTYPE)OMX_IndexCameraOperatingMode, &opMode );
+
+                if( OMX_ErrorNone == omxError )
+                {
+                    for (i = 0; i < VCAM_CAP_MODE_MAX; i++)
+                    {
+                        if (CaptureModeLUT[i][1] == opMode.eCamOperatingMode)
+                        {
+                            memcpy( param, &CaptureModeLUT[i][0], sizeof(int) );
+                            break;
+                        }
+                    }
+
+                    if( VCAM_CAP_MODE_MAX == CaptureModeLUT[i][0])
+                    {
+                        greError = -EINVAL;
+                        break;
+                    }
+                }
+            }
+            break;
+        }
+
+        case VCAM_PARAM_SENSOR_SELECT:
+        {
+            OMX_CONFIG_SENSORSELECTTYPE sensor;
+            OMX_STRUCT_INIT(sensor, OMX_CONFIG_SENSORSELECTTYPE, mLocalVersion);
+
+            omxError = OMX_GetConfig( mCurGreContext.mHandleComp, (OMX_INDEXTYPE)OMX_TI_IndexConfigSensorSelect, &sensor);
+
+            if( OMX_ErrorNone == omxError)
+            {
+                *((int*)param) = sensor.eSensor;
+            }
+            break;
+        }
+
+        case VCAM_PARAM_EXPOSURE_COMPENSATION:
+        {
+            OMX_CONFIG_EXPOSUREVALUETYPE expValues;
+            OMX_STRUCT_INIT( expValues, OMX_CONFIG_EXPOSUREVALUETYPE, mLocalVersion );
+            omxError = OMX_GetConfig( mCurGreContext.mHandleComp , OMX_IndexConfigCommonExposureValue , &expValues );
+
+            if( OMX_ErrorNone == omxError )
+            {
+                expValues.xEVCompensation *= 10;
+                int compVal = expValues.xEVCompensation / (1 << 16);
+                *((int*)param) = compVal;
+            }
+            break;
+        }
+
+        case VCAM_PARAM_RESOLUTION:
+        {
+            int i = VCAM_RESOL_MAX;
+            unsigned int width, height;
+            OMX_PARAM_PORTDEFINITIONTYPE portCheck;
+            omxError = initPortCheck( &portCheck , port );
+
+            if( OMX_ErrorNone == omxError )
+            {
+                width = portCheck.format.video.nFrameWidth;
+                height = portCheck.format.video.nFrameHeight;
+                for( i = 0; i < VCAM_RESOL_MAX; i++)
+                {
+                    if( VisionCamResolutions[i].mWidth == width
+                        && VisionCamResolutions[i].mHeight == height)
+                    {
+                        *((int*)param) = i;
+                        break;
+                    }
+                }
+                if( VCAM_RESOL_MAX == i )
+                {
+                    greError = -EINVAL;
+                }
+            }
+            break;
+        }
+
+        case VCAM_PARAM_2DBUFFER_DIM:
+        {
+            OMX_CONFIG_RECTTYPE frame;
+            OMX_STRUCT_INIT(frame, OMX_CONFIG_RECTTYPE, mLocalVersion);
+            VisionCamResType *pRes = (VisionCamResType *)param;
+
+            frame.nPortIndex = mCurGreContext.mPortsInUse[port];
+            if (pRes && size == sizeof(VisionCamResType))
+            {
+                // Set the port definition to update width and height first.
+                omxError = setPortDef( port );
+
+                if( OMX_ErrorNone == omxError )
+                {
+                    omxError = OMX_GetParameter(mCurGreContext.mHandleComp,
+                                                (OMX_INDEXTYPE)OMX_TI_IndexParam2DBufferAllocDimension,
+                                                &frame);
+                }
+
+                if (OMX_ErrorNone == omxError)
+                {
+                    pRes->mWidth = frame.nWidth;
+                    pRes->mHeight = frame.nHeight;
+                }
+                else
+                {
+                    ERROR("Failed to query the 2D Buffer Dimensions! (err=0x%08x)", omxError);
+                    memset(pRes, 0, sizeof(VisionCamResType));
+                    // omxError will convert to greError
+                }
+            }
+            else
+                greError = -EINVAL;
+            break;
+        }
+
+        case VCAM_PARAM_MANUAL_EXPOSURE:
+        {
+            OMX_CONFIG_EXPOSUREVALUETYPE expValues;
+            OMX_STRUCT_INIT(expValues, OMX_CONFIG_EXPOSUREVALUETYPE, mLocalVersion);
+
+            omxError = OMX_GetConfig( mCurGreContext.mHandleComp , OMX_IndexConfigCommonExposureValue , &expValues );
+
+            if( OMX_ErrorNone == omxError )
+            {
+                if( OMX_TRUE == expValues.bAutoShutterSpeed )
+                {
+                    *(OMX_U32*)param = 0;
+                }
+                else
+                {
+                    *(OMX_U32*)param = expValues.nShutterSpeedMsec;
+                }
+            }
+            break;
+        }
+
+        case VCAM_PARAM_EXPOSURE_ISO:
+        {
+            OMX_CONFIG_EXPOSUREVALUETYPE expValues;
+            OMX_STRUCT_INIT( expValues, OMX_CONFIG_EXPOSUREVALUETYPE, mLocalVersion );
+
+            omxError = OMX_GetConfig( mCurGreContext.mHandleComp , OMX_IndexConfigCommonExposureValue , &expValues );
+
+            if( OMX_ErrorNone == omxError )
+            {
+                if( OMX_TRUE == expValues.bAutoSensitivity )
+                {
+                    *(uint32_t*)param = 0;
+                }
+                else
+                    *(uint32_t*)param = expValues.nSensitivity;
+            }
+            break;
+        }
+
+        case VCAM_PARAM_AWB_MODE:
+        {
+            OMX_CONFIG_WHITEBALCONTROLTYPE wb;
+            OMX_STRUCT_INIT(wb, OMX_CONFIG_WHITEBALCONTROLTYPE, mLocalVersion );
+
+            omxError = OMX_GetConfig( mCurGreContext.mHandleComp,
+                                 OMX_IndexConfigCommonWhiteBalance,
+                                 &wb);
+
+            if( OMX_ErrorNone == omxError )
+            {
+                *(int *)param = (int)wb.eWhiteBalControl;
+            }
+            break;
+        }
+
+        case VCAM_PARAM_COLOR_TEMP:
+        {
+            ERROR("No Getting Api for this Parameter %d", paramId);
+            break;
+        }
+        case VCAM_PARAM_WB_COLOR_GAINS:
+        {
+#ifdef USE_WB_GAIN_PATCH
+            OMX_TI_CONFIG_SHAREDBUFFER skipBuffer;
+
+            skipBuffer.nSize = sizeof( OMX_TI_CONFIG_SHAREDBUFFER );
+            memcpy( &skipBuffer.nVersion , mLocalVersion , sizeof(mLocalVersion) );
+            skipBuffer.pSharedBuff = (OMX_U8*)mWBbuffer;
+            skipBuffer.nSharedBuffSize = sizeof(mWBbuffer);
+
+            omxError = OMX_GetConfig( mCurGreContext.mHandleComp,
+                                    (OMX_INDEXTYPE) OMX_TI_IndexConfigAAAskipBuffer,
+                                    &skipBuffer );
+
+            if( OMX_ErrorNone == omxError )
+            {
+                VisionCamWhiteBalGains wbGains;
+                uint16_t * tmp;
+                CALCULATE_WB_GAINS_OFFSET(uint16_t, mWBbuffer, tmp );
+
+                wbGains.mRed = tmp[ RED ];
+                wbGains.mGreen_r = tmp[ GREEN_RED ];
+                wbGains.mGreen_b = tmp[ GREEN_BLUE ];
+                wbGains.mBlue = tmp[ BLUE ];
+
+                *((VisionCamWhiteBalGains*)param) = wbGains;
+            }
+#endif // USE_WB_GAIN_PATCH
+            break;
+        }
+
+        case VCAM_PARAM_GAMMA_TBLS:
+        {
+
+            VisionCamGammaTableType *gammaTbl = (VisionCamGammaTableType*)param;
+            OMX_TI_CONFIG_SHAREDBUFFER skipBuffer;
+            skipBuffer.nSize = sizeof( OMX_TI_CONFIG_SHAREDBUFFER );
+            memcpy( &skipBuffer.nVersion , mLocalVersion , sizeof(mLocalVersion) );
+
+            skipBuffer.pSharedBuff = (OMX_U8*)mGammaTablesBuf;
+            skipBuffer.nSharedBuffSize = sizeof(mGammaTablesBuf);
+
+            omxError = OMX_GetConfig( mCurGreContext.mHandleComp,
+                                (OMX_INDEXTYPE) OMX_TI_IndexConfigAAAskipBuffer,
+                                &skipBuffer );
+
+            if( OMX_ErrorNone == omxError )
+            {
+                gammaTbl->mTableSize     = GAMMA_TABLE_SIZE;
+
+                uint32_t* base = (uint32_t *)(mGammaTablesBuf + 12); // 12 bytes offset for red table
+                gammaTbl->mRedTable      = (uint16_t*)(base[0] + (uint32_t)&base[2]);
+                gammaTbl->mBlueTable     = (uint16_t*)(base[1] + (uint32_t)&base[2]);
+                gammaTbl->mGreenTable    = (uint16_t*)(base[2] + (uint32_t)&base[2]);
+            }
+            break;
+        }
+
+        case VCAM_PARAM_ROTATION:
+        {
+            OMX_CONFIG_ROTATIONTYPE rotation;
+            OMX_STRUCT_INIT(rotation, OMX_CONFIG_ROTATIONTYPE, mLocalVersion);
+            omxError = OMX_GetConfig(mCurGreContext.mHandleComp,
+                                     OMX_IndexConfigCommonRotate,
+                                     &rotation);
+            if (OMX_ErrorNone == omxError)
+                *((OMX_S32*)param) = rotation.nRotation;
+            break;
+        }
+
+        case VCAM_PARAM_MIRROR:
+        {
+            if( VCAM_PORT_ALL == port )
+            {
+                greError = -EINVAL;
+            }
+            else
+            {
+                int i;
+                OMX_CONFIG_MIRRORTYPE mirror;
+                mirror.nSize = sizeof( OMX_CONFIG_MIRRORTYPE );
+                mirror.nPortIndex = mCurGreContext.mPortsInUse[port];
+                memcpy( &mirror.nVersion, mLocalVersion, sizeof(mLocalVersion));
+
+                omxError = OMX_GetConfig( mCurGreContext.mHandleComp,
+                                        OMX_IndexConfigCommonMirror,
+                                        &mirror );
+
+                if( OMX_ErrorNone == omxError )
+                {
+                    for( i = 0; i < VCAM_MIRROR_MAX; i++ )
+                    {
+                        if( MirrorTypeLUT[i][1] == mirror.eMirror )
+                        {
+                          *((VisionCamMirrorType*)param) = (VisionCamMirrorType) MirrorTypeLUT[i][0];
+                          break;
+                        }
+                    }
+
+                if( i >= VCAM_MIRROR_MAX )
+                    greError = -EINVAL;
+                }
+            }
+            break;
+        }
+
+#if ( defined(DUCATI_1_5) || defined(DUCATI_2_0) ) && defined(OMX_CAMERA_SUPPORTS_MANUAL_CONTROLS)
+        case VCAM_PARAM_AWB_MIN_DELAY_TIME:
+        {
+            uint32_t *timeDelay = (uint32_t*)param;
+            OMX_TI_CONFIG_AE_DELAY aeDelay;
+            OMX_STRUCT_INIT( aeDelay, OMX_TI_CONFIG_AE_DELAY, mLocalVersion );
+
+            omxError = OMX_GetConfig( mCurGreContext.mHandleComp,
+                                    ( OMX_INDEXTYPE )OMX_TI_IndexConfigAutoExpMinDelayTime,
+                                    &aeDelay
+                                  );
+            if( OMX_ErrorNone == omxError )
+            {
+                *timeDelay = aeDelay.nDelayTime;
+            }
+            break;
+        }
+#endif
+#if ( defined(DUCATI_1_5) || defined(DUCATI_2_0) ) && defined(OMX_CAMERA_SUPPORTS_GESTURES)
+        case VCAM_PARAM_GESTURES_INFO:
+        {
+            VisionCamGestureInfo *info = (VisionCamGestureInfo *)param;
+            OMX_TI_CONFIG_GESTURES_INFO gestInfo;
+            int ret = 0;
+
+            OMX_STRUCT_INIT( gestInfo, OMX_TI_CONFIG_GESTURES_INFO , mLocalVersion );
+
+            omxError = OMX_GetConfig( mCurGreContext.mHandleComp,
+                                    (OMX_INDEXTYPE)OMX_TI_IndexConfigDetectedGesturesInfo,
+                                    &gestInfo
+                                  );
+
+            if( OMX_ErrorNone != omxError )
+                break;
+
+            ret = (VisionCamGestureEvent_e)getLutValue( gestInfo.eType, OMX_VALUE_TYPE,
+                                                        GestureTypeLUT, ARR_SIZE(GestureTypeLUT)
+                                                        );
+
+            if( -EINVAL == (int)ret )
+            {
+                greError = -EINVAL;
+            }
+            else
+            {
+                info->mGestureType = (VisionCamGestureEvent_e)ret;
+                info->mRegionsNum = gestInfo.nNumDetectedGestures;
+                if( info->mRegionsNum >= VCAM_Max_Gesture_Per_Frame )
+                {
+                    greError= -EINVAL;
+                    break;
+                }
+
+            #ifdef __cplusplus
+                info->mRegions = new VisionCamObjectRectType[ info->mRegionsNum ];
+            #else
+                if( NULL == info->mRegions )
+                {
+                    ERROR("Please allocate the mRegions buffer");
+                    ERROR("Check for necessery size in mRegionsNum");
+
+                    greError= STATUS_NO_RESOURCES;
+                    break;
+                }
+            #endif
+
+                for(uint32_t i = 0; i < info->mRegionsNum; i++ )
+                {
+                    info->mRegions[i].mObjType= (VisionCamObjectType)getLutValue(
+                                                                                    (int)(gestInfo.nGestureAreas[i].eType),
+                                                                                    OMX_VALUE_TYPE,
+                                                                                    ObjectTypeLUT,
+                                                                                    ARR_SIZE(ObjectTypeLUT)
+                                                                                );
+
+                    gestInfo.nGestureAreas[i].nTop = info->mRegions[i].mTop;
+                    gestInfo.nGestureAreas[i].nLeft = info->mRegions[i].mLeft;
+                    gestInfo.nGestureAreas[i].nWidth = info->mRegions[i].mWidth;
+                    gestInfo.nGestureAreas[i].nHeight = info->mRegions[i].mHeight;
+                }
+
+                info->timeStamp = gestInfo.nTimeStamp;
+            }
+
+            break;
+        }
+#endif
+#if ( defined(DUCATI_1_5) || defined(DUCATI_2_0) ) && defined(OMX_CAMERA_SUPPORTS_MANUAL_CONTROLS)
+        case VCAM_PARAM_AGC_MIN_DELAY_TIME:
+        {
+            uint32_t *delay = (uint32_t*)param;
+            OMX_TI_CONFIG_AE_DELAY agcDelTime;
+            OMX_STRUCT_INIT( agcDelTime, OMX_TI_CONFIG_AE_DELAY, mLocalVersion );
+
+            omxError = OMX_GetConfig( mCurGreContext.mHandleComp,
+                                    (OMX_INDEXTYPE)OMX_TI_IndexConfigAutoExpMinDelayTime,
+                                    &agcDelTime );
+
+            if( OMX_ErrorNone != omxError )
+                break;
+
+            *delay = agcDelTime.nDelayTime;
+            break;
+        }
+
+        case VCAM_PARAM_AGC_LOW_TH:
+        {
+            uint32_t *lowTH = (uint32_t*)param;
+            OMX_TI_CONFIG_AE_THRESHOLD ae;
+
+            OMX_STRUCT_INIT( ae, OMX_TI_CONFIG_AE_THRESHOLD, mLocalVersion );
+
+            omxError = OMX_GetConfig( mCurGreContext.mHandleComp, (OMX_INDEXTYPE)OMX_TI_IndexConfigAutoExpThreshold, &ae );
+
+            if( OMX_ErrorNone != omxError )
+                break;
+
+            *lowTH = ae.uMinTH;
+            break;
+        }
+
+        case VCAM_PARAM_AGC_HIGH_TH:
+        {
+            uint32_t *highTH = (uint32_t*)param;
+
+            OMX_TI_CONFIG_AE_THRESHOLD ae;
+            OMX_STRUCT_INIT( ae, OMX_TI_CONFIG_AE_THRESHOLD, mLocalVersion );
+
+            omxError = OMX_GetConfig( mCurGreContext.mHandleComp, (OMX_INDEXTYPE)OMX_TI_IndexConfigAutoExpThreshold, &ae );
+
+            if( OMX_ErrorNone != omxError )
+                break;
+
+            *highTH = ae.uMaxTH;
+            break;
+        }
+#endif
+
+        default:
+        {
+            ERROR("Impossible parameter id requested: %d", paramId);
+            ERROR("see VisionCamParam_e for possible parameter ids");
+            greError = -EINVAL;
+        }
+    }
+
+    if( OMX_ErrorNone != omxError )
+    {
+        greError = ConvertError(omxError);
+    }
+
+    if( greError != 0 )
+    {
+        ERROR("getParameter() exits with error 0x%x (dec: %d) for param id %d", greError, greError, paramId);
+    }
+
+    return greError;
+}
+
+OMX_ERRORTYPE OMXVisionCam::getFocusStatus(OMX_FOCUSSTATUSTYPE *status)
+{
+    OMX_ERRORTYPE eError = OMX_ErrorNone;
+    OMX_PARAM_FOCUSSTATUSTYPE focusStatus;
+    OMX_STRUCT_INIT(focusStatus, OMX_PARAM_FOCUSSTATUSTYPE, mLocalVersion);
+
+    // Get the focus status
+    OMX_CHECK(eError,OMX_GetConfig(mCurGreContext.mHandleComp,
+                                   OMX_IndexConfigCommonFocusStatus,
+                                   &focusStatus));
+    if (eError == OMX_ErrorNone)
+        *status = focusStatus.eFocusStatus;
+    return eError;
+}
+
+int OMXVisionCam::waitForFocus()
+{
+    OMX_ERRORTYPE omxError = OMX_ErrorNone;
+    OMX_FOCUSSTATUSTYPE focusStatus;
+
+    omxError = RegisterForEvent(mCurGreContext.mHandleComp,
+                              (OMX_EVENTTYPE) OMX_EventIndexSettingChanged,
+                              OMX_ALL,
+                              OMX_IndexConfigCommonFocusStatus,
+                              &mGreFocusSem,
+                              -1);
+    if (OMX_ErrorNone == omxError)
+    {
+        OMX_CONFIG_CALLBACKREQUESTTYPE focusRequestCallback;
+        OMX_STRUCT_INIT(focusRequestCallback, OMX_CONFIG_CALLBACKREQUESTTYPE, mLocalVersion);
+        focusRequestCallback.bEnable = OMX_TRUE;
+        focusRequestCallback.nIndex = OMX_IndexConfigCommonFocusStatus;
+
+        // subscribe for focus state changes
+        OMX_CHECK(omxError,OMX_SetConfig(mCurGreContext.mHandleComp,
+                                       (OMX_INDEXTYPE) OMX_IndexConfigCallbackRequest,
+                                       &focusRequestCallback));
+#ifdef VCAM_CAUTIOUS
+        // make sure it's been registered
+        OMX_CHECK(omxError,OMX_GetConfig(mCurGreContext.mHandleComp,
+                                       (OMX_INDEXTYPE) OMX_IndexConfigCallbackRequest,
+                                       &focusRequestCallback));
+
+#endif
+        if (OMX_ErrorNone == omxError && focusRequestCallback.bEnable == OMX_TRUE)
+        {
+            MSG("Waiting for Focus Callback!");
+            // wait for focus to arrive
+            sem_wait(&mGreFocusSem);
+
+            // Give the client the focus greError
+            omxError = getFocusStatus(&focusStatus);
+            MSG("Focus Status: %u", focusStatus);
+            if (OMX_ErrorNone == omxError)
+            {
+                if (m_focuscallback)
+                    m_focuscallback((int)focusStatus);
+            }
+        }
+    }
+    return ConvertError(omxError);
+}
+
+int OMXVisionCam::startAutoFocus( VisionCamFocusMode focusMode )
+{
+    int i;
+    OMX_ERRORTYPE omxError = OMX_ErrorNone;
+    bool haveEvent = true;
+    OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE focus;
+
+    if (focusMode == VCAM_FOCUS_CONTROL_OFF ||
+        focusMode == VCAM_FOCUS_CONTROL_AUTO ||
+        focusMode == VCAM_FOCUS_CONTROL_CONTINOUS_NORMAL ||
+        focusMode == VCAM_FOCUS_CONTROL_CONTINOUS_EXTENDED)
+    {
+        haveEvent = false;
+    }
+
+    // initialize the structure
+    OMX_STRUCT_INIT(focus, OMX_IMAGE_CONFIG_FOCUSCONTROLTYPE, mLocalVersion);
+    for( i = 0 ; i < VCAM_FOCUS_CONTROL_MAX ; i++ )
+    {
+        if( FocusModeLUT[ i ][ 0 ] == focusMode )
+        {
+            focus.eFocusControl = ( OMX_IMAGE_FOCUSCONTROLTYPE )FocusModeLUT[ i ][ 1 ];
+            if( focus.eFocusControl == OMX_IMAGE_FocusControlOn )
+                focus.nFocusSteps = mManualFocusDistance;
+            break;
+        }
+    }
+
+    if (i == VCAM_FOCUS_CONTROL_MAX)
+    {
+        ERROR("Unsupported focus mode requested: %d", focusMode );
+        return -EINVAL;
+    }
+
+    MSG("Focus Requested Steps @ %lu, Index @ %lu", focus.nFocusSteps, focus.nFocusStepIndex);
+
+    // tell the OMX component to change the focus control mode
+    OMX_CHECK(omxError,OMX_SetConfig(mCurGreContext.mHandleComp, OMX_IndexConfigFocusControl, &focus));
+#ifdef VCAM_CAUTIOUS
+    // ask it what mode it's in now
+    OMX_CHECK(omxError, OMX_GetConfig(mCurGreContext.mHandleComp, OMX_IndexConfigFocusControl, &focus));
+#endif
+    MSG("Focus Control Mode = 0x%08x", focus.eFocusControl);
+    if (OMX_ErrorNone == omxError && focus.eFocusControl != OMX_IMAGE_FocusControlOff)
+    {
+        if (haveEvent)
+        {
+            pthread_t thread;
+            pthread_create(&thread, NULL, FocusThreadLauncher, this);
+            // the thread will die by itself, we don't need to join it.
+        }
+    }
+
+    return ConvertError(omxError);
+}
+
+/* This will set the preview buffer sizzes, format, etc.
+    */
+OMX_ERRORTYPE OMXVisionCam::setPortDef( int port )
+{
+    OMX_ERRORTYPE omxError = OMX_ErrorNone;
+
+        VCAM_PortParameters * portData = NULL;
+        OMX_PARAM_PORTDEFINITIONTYPE portCheck;
+
+        int32_t p;
+        LOOP_PORTS( port , p )
+        {
+            omxError = initPortCheck(&portCheck, p);
+
+            if( omxError == OMX_ErrorNone )
+            {
+                portData =  &mCurGreContext.mCameraPortParams[p];
+                portCheck.format.video.nFrameWidth  = portData->mWidth;
+                portCheck.format.video.nFrameHeight = portData->mHeight;
+                portCheck.format.video.eColorFormat = portData->mColorFormat;
+                portCheck.format.video.nStride      = portData->mStride;
+                portCheck.format.video.xFramerate   = portData->mFrameRate << 16;
+                portCheck.nBufferCountActual        = portData->mNumBufs;
+
+                omxError = OMX_SetParameter(mCurGreContext.mHandleComp,
+                                          OMX_IndexParamPortDefinition,
+                                          &portCheck);
+            }
+
+            if( omxError == OMX_ErrorNone )
+                omxError = initPortCheck(&portCheck, p);
+
+            if( omxError == OMX_ErrorNone )
+                portData->mBufSize = portCheck.nBufferSize;
+
+#if defined(VCAM_SET_FORMAT_ROTATION)
+// set the rotation type on the port
+if ( omxError == OMX_ErrorNone)
+{
+    OMX_CONFIG_ROTATIONTYPE rotType;
+    OMX_STRUCT_INIT(rotType, OMX_CONFIG_ROTATIONTYPE, mLocalVersion);
+    rotType.nRotation = mCurGreContext.mCameraPortParams[p].mRotation;
+    rotType.nPortIndex = mCurGreContext.mPortsInUse[p];
+    MSG("VCAM: Configuring for Rotation %li",rotType.nRotation);
+    OMX_CHECK(omxError, OMX_SetConfig(mCurGreContext.mHandleComp,
+                                      OMX_IndexConfigCommonRotate,
+                                      &rotType));
+}
+#endif
+        }
+
+    return omxError;
+}
+
+/* This will start the preview.
+ * Before that setParameter() sould be called, to configure the preview port.
+ * This method is only called internal for OMXVisionCam
+ * by sendCommand().
+ */
+int OMXVisionCam::startPreview( VisionCamPort_e port )
+{
+    int greError = 0;
+
+    if( port < VCAM_PORT_ALL || port > VCAM_PORT_MAX - 1 )
+    {
+        ERROR("startPreview() called, but port is not specified properly.");
+        return -EINVAL;
+    }
+
+    mFlushInProcess = false;
+
+    switch((int)getComponentState())
+    {
+        case OMX_StateIdle:
+        {
+            greError = transitToState( OMX_StateExecuting );
+            mReturnToExecuting = true;
+            break;
+        }
+        case OMX_StateLoaded:
+        case OMX_StateWaitForResources:
+        case OMX_StateInvalid:
+        {
+            ERROR("Calling startPreview() in an inproper state.");
+            greError = -EBADE;
+            break;
+        }
+        case OMX_StateExecuting:
+        case OMX_StatePause:
+        {
+            break;
+        }
+        default:
+            break;
+    }
+
+    AutoLock lock(&mFrameBufferLock);
+
+    OMX_ERRORTYPE omxError;
+    omxError = setPortDef( port );
+    greError = ConvertError(omxError);
+
+    if( 0 == greError )
+    {
+        greError = portEnableDisable( OMX_CommandPortEnable, populatePortSrvc, port);
+    }
+
+    if( 0 == greError )
+    {
+        // first fill the video port buffers, then preview port
+        // otherwise preview port will start working right after it receive its frames
+        // so it won't wait for video port to get ready
+        if( VCAM_PORT_ALL == port || VCAM_PORT_VIDEO == port )
+        {
+            greError = fillPortBuffers(VCAM_PORT_VIDEO);
+        }
+
+        if( VCAM_PORT_ALL == port || VCAM_PORT_PREVIEW == port )
+        {
+            greError = fillPortBuffers(VCAM_PORT_PREVIEW);
+        }
+    }
+
+    return greError;
+}
+
+/**
+  * This will stop the preview
+  *
+  */
+int OMXVisionCam::stopPreview( VisionCamPort_e port )
+{
+    int greError = 0;
+    bool goToIdle = true;
+
+    mFlushInProcess = true;
+
+    flushBuffers( port );
+    greError = portEnableDisable( OMX_CommandPortDisable, freePortBuffersSrvc, port );
+
+    if( 0 == greError )
+    {
+        for( int p = VCAM_PORT_PREVIEW; p < VCAM_PORT_MAX; p++)
+        {
+            if( mCurGreContext.mCameraPortParams[p].mIsActive )
+            {
+                goToIdle = false;
+                break;
+            }
+        }
+
+        if ( goToIdle && OMX_StateExecuting == getComponentState() )
+        {
+            transitToState( OMX_StateIdle );
+        }
+    }
+
+    return greError;
+}
+
+/**
+  * This will free all the buffers on the preview port
+  * and switch to loaded state.
+  */
+int OMXVisionCam::releaseBuffers( VisionCamPort_e port)
+{
+    int greError = 0;
+
+    OMX_PARAM_PORTDEFINITIONTYPE portCheck[ VCAM_PORT_MAX ];
+
+    int32_t p;
+    LOOP_PORTS( port , p )
+    {
+        initPortCheck(&portCheck[p], p);
+
+        for( uint32_t indBuff = 0; indBuff < portCheck[p].nBufferCountActual; indBuff++ )
+        {
+            if( mFrameDescriptors && mFrameDescriptors[p] && mFrameDescriptors[p][indBuff] )
+                delete mFrameDescriptors[p][indBuff];
+        }
+
+        if( mFrameDescriptors && mFrameDescriptors[p] )
+        {
+            delete mFrameDescriptors[p];
+            mFrameDescriptors[p] = NULL;
+        }
+    }
+
+    if (OMX_StateIdle == getComponentState())
+        transitToState( OMX_StateLoaded, NULL, NULL );
+
+    return greError;
+}
+
+/** This will configure the component to start/stop face detection.
+ * Will also start/stop face detection extra data
+ * faces coordinates will be written into camera frame received
+ * in preview callback
+ */
+int OMXVisionCam::enableFaceDetect(VisionCamPort_e port)
+{
+    OMX_ERRORTYPE omxError = OMX_ErrorNone;
+    OMX_CONFIG_OBJDETECTIONTYPE objDetection;
+    OMX_STRUCT_INIT( objDetection, OMX_CONFIG_OBJDETECTIONTYPE ,mLocalVersion);
+    objDetection.nPortIndex = mCurGreContext.mPortsInUse[port];
+
+    if (mFaceDetectionEnabled)
+        objDetection.bEnable = OMX_TRUE;
+    else
+        objDetection.bEnable = OMX_FALSE;
+
+    omxError = OMX_SetConfig(mCurGreContext.mHandleComp, (OMX_INDEXTYPE) OMX_IndexConfigImageFaceDetection, &objDetection);
+    if( OMX_ErrorNone == omxError )
+    {
+        OMX_CONFIG_EXTRADATATYPE xData;
+        OMX_STRUCT_INIT(xData, OMX_CONFIG_EXTRADATATYPE, mLocalVersion);
+
+        xData.nPortIndex        = mCurGreContext.mPortsInUse[port];
+        xData.eExtraDataType    = OMX_FaceDetection;
+#if defined(TUNA) || defined(MAGURO)
+        xData.eCameraView       = OMX_2D_Prv;
+#endif
+        if (mFaceDetectionEnabled)
+            xData.bEnable = OMX_TRUE;
+        else
+            xData.bEnable = OMX_FALSE;
+
+        OMX_CHECK(omxError,OMX_SetConfig(mCurGreContext.mHandleComp, (OMX_INDEXTYPE)OMX_IndexConfigOtherExtraDataControl, &xData));
+    }
+    return ConvertError(omxError);
+}
+
+/** Fill the face coordinates field in camera frame,
+ *  which will be received by OMXVisionCam client at each frame.
+ */
+void OMXVisionCam::getFacesCoordinates( VisionCamFrame *frame)
+{
+    OMX_OTHER_EXTRADATATYPE* extraData = (OMX_OTHER_EXTRADATATYPE*)frame->mExtraDataBuf;
+    OMX_U8 *pExtraLimit = (OMX_U8 *)extraData + frame->mExtraDataLength;
+    OMX_FACEDETECTIONTYPE *facesData;
+    if( extraData == NULL )
+    {
+        frame->mDetectedFacesNum = 0;
+        return;
+    }
+
+    // find the faces data buffers
+    while( (OMX_EXTRADATATYPE)OMX_FaceDetection != extraData->eType && extraData->data )
+    {
+        MSG("Current Extra Data Section Size: %lu", extraData->nDataSize);
+        extraData = (OMX_OTHER_EXTRADATATYPE*)(extraData->data + extraData->nDataSize);
+
+        if( (OMX_U8 *)extraData >= pExtraLimit )
+        {
+            ERROR("ERROR: METADATA: Bad size field in metadata. %p >= %p", extraData, pExtraLimit);
+            return;
+        }
+
+        if( 0 == extraData->nDataSize )
+        {
+            ERROR("METADATA: No face data detected!");
+            frame->mDetectedFacesNum = 0;
+            memset( frame->mFaces, 0, MAX_FACES_COUNT*sizeof(VisionCamFaceType) );
+            return;
+        }
+    }
+
+    if( extraData->data )
+    {
+        facesData = (OMX_FACEDETECTIONTYPE *)(extraData->data);
+
+        frame->mDetectedFacesNum = facesData->ulFaceCount;
+
+        MSG("METADATA: FACE # %d!", frame->mDetectedFacesNum);
+
+        for(uint32_t i = 0; i < frame->mDetectedFacesNum; i++)
+        {
+            memcpy( &(frame->mFaces[i]), &(facesData->tFacePosition[i].nScore), sizeof(VisionCamFaceType)) ;
+        }
+    }
+}
+
+/** Parse through the extra data type structure to find the pointer to the relevent
+ *  data type.  This is to abstract the port number, version, and packet structure from the client.
+ */
+void OMXVisionCam::getMetadataPtrs( VisionCamFrame *frame)
+{
+    OMX_OTHER_EXTRADATATYPE* extraData = (OMX_OTHER_EXTRADATATYPE*)frame->mExtraDataBuf;
+    OMX_U8 *pExtraLimit = (OMX_U8 *)extraData + frame->mExtraDataLength;
+    frame->mMetadata.mAutoWBGains = NULL;
+    frame->mMetadata.mManualWBGains = NULL;
+    frame->mMetadata.mAncillary = NULL;
+    frame->mMetadata.mHistogram2D = NULL;
+    frame->mMetadata.mHistogramL = NULL;
+    frame->mMetadata.mHistogramR = NULL;
+
+    if( extraData == NULL )
+    {
+        return;
+    }
+
+    while( extraData->eType && extraData->nDataSize && extraData->data )   // keep looping while there is more extra data and double check size
+    {
+        switch( extraData->eType )
+        {
+            case OMX_AncillaryData:
+            {
+                OMX_TI_ANCILLARYDATATYPE *ancillaryData = NULL;
+                MSG("METADATA: Found Ancillary Data Section!");
+                ancillaryData =  (OMX_TI_ANCILLARYDATATYPE  *)(extraData->data);
+                frame->mMetadata.mAncillary= (VisionCamAncillary*)&ancillaryData->nAncillaryDataVersion;
+                break;
+            }
+
+            case OMX_WhiteBalance:
+            {
+                OMX_TI_WHITEBALANCERESULTTYPE *wbData = NULL;
+                MSG("METADATA: Found White Balance Result Data Section!");
+                wbData =  (OMX_TI_WHITEBALANCERESULTTYPE  *)(extraData->data);
+                frame->mMetadata.mAutoWBGains = (VisionCamWhiteBalGains*)&wbData->nGainR;
+                break;
+            }
+#ifndef __QNX__
+            case OMX_TI_WhiteBalanceOverWrite:
+            {
+                OMX_TI_WHITEBALANCERESULTTYPE *wbManData = NULL;
+                MSG("METADATA: Found White Balance Overwrite Data Section!");
+                wbManData =  (OMX_TI_WHITEBALANCERESULTTYPE  *)(extraData->data);
+                frame->mMetadata.mManualWBGains = (VisionCamWhiteBalGains*)&wbManData->nGainR;
+                break;
+            }
+#endif
+#if defined(DUCATI_2_0)
+            case OMX_Histogram:
+            {
+                OMX_TI_HISTOGRAMTYPE *histData = NULL;
+                MSG("METADATA: Found Histogram Result Data Section!");
+                histData =  (OMX_TI_HISTOGRAMTYPE  *)(extraData->data);
+#if defined(TUNA) || defined(MAGURO) || 1
+                if((OMX_TI_CAMERAVIEWTYPE)(histData->eCameraView) == OMX_2D_Prv)
+                    frame->mMetadata.mHistogram2D = (VisionCamHistogram*)&histData->nBins;
+                else if((OMX_TI_CAMERAVIEWTYPE)(histData->eCameraView) == OMX_3D_Left_Prv)
+                    frame->mMetadata.mHistogramL = (VisionCamHistogram*)&histData->nBins;
+                else if((OMX_TI_CAMERAVIEWTYPE)(histData->eCameraView) == OMX_3D_Right_Prv)
+                    frame->mMetadata.mHistogramR = (VisionCamHistogram*)&histData->nBins;
+#else
+                frame->mMetadata.mHistogram2D = (VisionCamHistogram*)&histData->nBins;
+#endif
+                break;
+            }
+#endif
+            default:
+            {
+                break;
+            }
+        }
+        MSG("Current Extra Data Section Size: %lu", extraData->nDataSize);
+        extraData = (OMX_OTHER_EXTRADATATYPE*)(extraData->data + extraData->nDataSize);
+        if( (OMX_U8 *)extraData >= pExtraLimit )
+        {
+            ERROR("ERROR: METADATA: Bad size field in metadata. %p >= %p", extraData, pExtraLimit);
+            break;
+        }
+    }
+}
+
+/** This shall be called by the user of this class when it finishes working
+ * with the frame and to notify VisionCam that the frame buffer is
+ * free.
+ */
+int OMXVisionCam::returnFrame(VisionCamFrame *cameraFrame)
+{
+    OMX_ERRORTYPE omxError = OMX_ErrorNone;
+    int32_t i = 0;
+    if (mFlushInProcess)
+        return 0;
+
+    if (cameraFrame == NULL)
+        return -EINVAL;
+
+    if (OMX_StateExecuting == getComponentState())
+    {
+        VisionCamPort_e port = cameraFrame->mFrameSource;
+        VCAM_PortParameters * portData = &mCurGreContext.mCameraPortParams[port];
+        for (i = 0; i < portData->mNumBufs; i++)
+        {
+            if (portData->mBufferHeader[i] &&
+                portData->mBufferHeader[i]->pAppPrivate == cameraFrame->mFrameBuff)
+            {
+                omxError = OMX_FillThisBuffer(mCurGreContext.mHandleComp,
+                                              mCurGreContext.mCameraPortParams[port].mBufferHeader[i]);
+                if (OMX_ErrorNone != omxError)
+                {
+                    ERROR("ERROR: OMX_FillThisBuffer() returned 0x%x in %s", omxError, __func__);
+                }
+                else
+                {
+                    MSG("frame returned successfully in %s", __func__);
+                }
+                break;
+            }
+        }
+        if( i == portData->mNumBufs)
+        {
+            ERROR("ERROR: returned frame not found in %s", __func__);
+        }
+    }
+    else
+    {
+        ERROR("Returning Frame when OMX-CAMERA is in the wrong state or image is NULL");
+    }
+
+    return ConvertError(omxError);
+}
+
+int OMXVisionCam::PreemptionService(/*VisionCamPreemptionActivity_e activity*/)
+{
+    OMX_ERRORTYPE omxError = OMX_ErrorNone;
+    VCAM_PortParameters * portData = NULL;
+
+    switch( mPreemptionState )
+    {
+        case VCAM_PREEMPT_SUSPEND:
+        {
+            // Register for Loaded state switch event
+            omxError = RegisterForEvent(mCurGreContext.mHandleComp,
+                                         OMX_EventCmdComplete,
+                                         OMX_CommandStateSet,
+                                         OMX_StateLoaded,
+                                         &mGreLocalSem,
+                                         -1); // Infinite timeout
+
+            if( OMX_ErrorNone == omxError )
+            {
+                for( int port = VCAM_PORT_PREVIEW; port < VCAM_PORT_MAX; port++ )
+                {
+                    // Free the OMX Buffers
+                    portData = &mCurGreContext.mCameraPortParams[port];
+                    for( int i = 0; i < portData->mNumBufs; i++ )
+                    {
+                        omxError = OMX_FreeBuffer(mCurGreContext.mHandleComp,
+                                                        mCurGreContext.mPortsInUse[port],
+                                                        portData->mBufferHeader[i]);
+
+                        portData->mBufferHeader[i] = NULL;
+
+                        if( OMX_ErrorNone != omxError )
+                        {
+                            ERROR("Preemption Service: Error 0x%x while freeing buffers!", omxError);
+                            break;
+                        }
+                    }
+                }
+            }
+
+            if( OMX_ErrorNone == omxError )
+                sem_wait(&mGreLocalSem);
+
+            if( mClientNotifier.mNotificationCallback && OMX_ErrorNone == omxError )
+                mClientNotifier.mNotificationCallback(VisionCamClientNotifier::VCAM_MESSAGE_PREEMPT_SUSPEND_ACTIVITY);
+
+            // Register for WAIT state switch event
+            omxError = RegisterForEvent(mCurGreContext.mHandleComp,
+                                         OMX_EventCmdComplete,
+                                         OMX_CommandStateSet,
+                                         OMX_StateWaitForResources,
+                                         &mGreLocalSem,
+                                         -1); // Infinite timeout
+
+            if( OMX_ErrorNone == omxError  )
+            {
+              omxError = OMX_SendCommand(mCurGreContext.mHandleComp,
+                                            OMX_CommandStateSet,
+                                            OMX_StateWaitForResources,
+                                            NULL);
+            }
+
+            if( OMX_ErrorNone == omxError  )
+              sem_wait(&mGreLocalSem);
+
+            break;
+        }
+        case VCAM_PREEMPT_RESUME:
+        {
+            if( mClientNotifier.mNotificationCallback )
+                mClientNotifier.mNotificationCallback(VisionCamClientNotifier::VCAM_MESSAGE_PREEMPT_RESUME_ACTIVITY);
+
+            // Register for IDLE state switch event
+            omxError = RegisterForEvent(mCurGreContext.mHandleComp,
+                                           OMX_EventCmdComplete,
+                                           OMX_CommandStateSet,
+                                           OMX_StateIdle,
+                                           &mGreLocalSem,
+                                           -1); //Infinite timeout
+            if( OMX_ErrorNone != omxError )
+            {
+                ERROR("Preemption Service: Error 0x%x while registering for Idle state wait.", omxError);
+                break;
+            }
+
+            for( int port = VCAM_PORT_PREVIEW; port < VCAM_PORT_MAX; port++ )
+            {
+                portData = &mCurGreContext.mCameraPortParams[port];
+                for( int buff = 0; buff < portData->mNumBufs; buff++ )
+                {
+                    OMX_BUFFERHEADERTYPE *pBufferHdr;
+                    OMX_U8 *buffer = (OMX_U8*)mBuffersInUse[port].mBuffers[buff].fd;
+
+                    omxError = OMX_UseBuffer(   mCurGreContext.mHandleComp,
+                                                &pBufferHdr,
+                                                mCurGreContext.mPortsInUse[port],
+                                                0,
+                                                portData->mBufSize,
+                                                buffer
+                                            );
+
+                    if( OMX_ErrorNone != omxError )
+                    {
+                        ERROR("Preemption Service: Error 0x%x while passing buffers to OMX Component.", omxError);
+                        break;
+                    }
+
+                    pBufferHdr->pAppPrivate = (OMX_PTR)&mBuffersInUse[port].mBuffers[buff];
+
+                    pBufferHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
+
+                    memcpy( &(pBufferHdr->nVersion), mLocalVersion, sizeof( OMX_VERSIONTYPE ) );
+
+                    portData->mBufferHeader[buff] = pBufferHdr;
+                }
+            }
+
+            sem_wait(&mGreLocalSem);
+
+//            if (mReturnToExecuting)
+//            {
+                for( int port = VCAM_PORT_PREVIEW; port < VCAM_PORT_MAX; port++ )
+                {
+                    if( mCurGreContext.mCameraPortParams[port].mIsActive )
+                        startPreview( (VisionCamPort_e)port );
+                }
+//            }
+            break;
+        }
+
+        case VCAM_PREEMPT_WAIT_TO_START:
+        {
+            if( mClientNotifier.mNotificationCallback && OMX_ErrorNone == omxError )
+                mClientNotifier.mNotificationCallback(VisionCamClientNotifier::VCAM_MESSAGE_PREEMPT_WAIT_RESOURCES);
+
+            // Register for WAIT state switch event
+            omxError = RegisterForEvent(mCurGreContext.mHandleComp,
+                                           OMX_EventCmdComplete,
+                                           OMX_CommandStateSet,
+                                           OMX_StateWaitForResources,
+                                           &mGreLocalSem,
+                                           -1); // Infinite timeout
+
+           if( OMX_ErrorNone == omxError  )
+           {
+               omxError = OMX_SendCommand(mCurGreContext.mHandleComp,
+                                             OMX_CommandStateSet,
+                                             OMX_StateWaitForResources,
+                                             NULL);
+           }
+
+           if( OMX_ErrorNone == omxError  )
+               sem_wait(&mGreLocalSem);
+
+           // Register for WAIT state switch event
+           omxError = RegisterForEvent(mCurGreContext.mHandleComp,
+                                          OMX_EventResourcesAcquired,
+                                          0,
+                                          0,
+                                          &mGreLocalSem,
+                                          -1); // Infinite timeout
+
+           if( OMX_ErrorNone == omxError  )
+               sem_wait(&mGreLocalSem);
+
+           if( mClientNotifier.mNotificationCallback && OMX_ErrorNone == omxError )
+               mClientNotifier.mNotificationCallback(VisionCamClientNotifier::VCAM_MESSAGE_PREAMPT_REASOURCES_READY);
+
+            break;
+        }
+        default:
+
+            break;
+    }
+
+    if( OMX_ErrorNone == omxError  )
+        mPreemptionState = VCAM_PREEMPT_INACTIVE;
+
+    return ConvertError(omxError);
+}
+
+OMX_ERRORTYPE OMXVisionCam::RegisterForEvent(OMX_IN OMX_HANDLETYPE hComponent,
+                                             OMX_IN OMX_EVENTTYPE eEvent,
+                                             OMX_IN OMX_U32 nData1,
+                                             OMX_IN OMX_U32 nData2,
+                                             OMX_IN sem_t *semaphore,
+                                             OMX_IN OMX_U32 timeout)
+{
+    OMXVCAM_Msg_t *msg = (OMXVCAM_Msg_t *)calloc(1, sizeof(OMXVCAM_Msg_t));
+    OMX_ERRORTYPE err = OMX_ErrorNone;
+    if (msg)
+    {
+        msg->eEvent = eEvent;
+        msg->nData1 = nData1;
+        msg->nData2 = nData2;
+        msg->semaphore = semaphore;
+        msg->hComponent = hComponent;
+        msg->timeout = timeout;
+        mEventSignalQ.push_back(msg);
+        MSG("Registering for Event %d (0x%08x)", eEvent,eEvent);
+    }
+    else
+    {
+        err = OMX_ErrorInsufficientResources;
+    }
+    return err;
+
+}
+
+extern "C" int node_compare_vcam_msg(void* a, void* b)
+{
+    OMXVCAM_Msg_t *msgA = (OMXVCAM_Msg_t *)a;
+    OMXVCAM_Msg_t *msgB = (OMXVCAM_Msg_t *)b;
+
+    MSG("Comparing Node %p and Node %p",msgA, msgB);
+
+    if (msgA->eEvent == msgB->eEvent &&
+        msgA->nData1 == msgB->nData1 &&
+        msgA->nData2 == msgB->nData2 &&
+        msgA->hComponent == msgB->hComponent)
+        return 0;
+    else if (msgA->eEvent < msgB->eEvent)
+        return -1;
+    else // if (msgA->event > msgB->event)
+        return 1;
+}
+
+/** OMXVisionCam Event Handler from OMX-CAMERA */
+OMX_ERRORTYPE OMXVisionCam::EventHandler(OMX_IN OMX_HANDLETYPE hComponent,
+                                         OMX_IN OMX_PTR pAppData,
+                                         OMX_IN OMX_EVENTTYPE eEvent,
+                                         OMX_IN OMX_U32 nData1,
+                                         OMX_IN OMX_U32 nData2,
+                                         OMX_IN OMX_PTR pEventData)
+{
+    // make a local pointer to the instance class which registered this callback.
+    OMXVisionCam *pOMXCam = (OMXVisionCam*)pAppData;
+    size_t len = pOMXCam->mEventSignalQ.size();
+
+    MSG("OMXVisionCam::EventHandler() event=%d arg1=%08x arg2=%08x ptr=%p (len=%zu)", eEvent, (uint32_t)nData1, (uint32_t)nData2, pEventData, len);
+    // check the queue to see if we were waiting on an event
+    if (len > 0)
+    {
+        OMXVCAM_Msg_t* msg = NULL;
+        std::list<OMXVCAM_Msg_t*>::iterator it;
+        for (it = pOMXCam->mEventSignalQ.begin(); it != pOMXCam->mEventSignalQ.end(); ++it) {
+          if ((*it)->eEvent > eEvent) {
+            break;
+          }
+          if (((*it)->eEvent == eEvent) &&
+              ((*it)->nData1 == nData1) &&
+              ((*it)->nData2 == nData2) &&
+              ((*it)->hComponent == hComponent)) {
+            msg = *it;
+            break;
+          }
+        }
+
+        // find the list event which matches this event
+        if (msg != NULL)
+        {
+            MSG("Found Event in List which matches incoming event!");
+            if (msg->semaphore)
+                sem_post(msg->semaphore);
+
+            pOMXCam->mEventSignalQ.erase(it);
+            free(msg);
+        }
+        else
+        {
+            MSG("No matching event found in list!");
+        }
+    }
+
+    switch( eEvent )
+    {
+        case OMX_EventError:
+        {
+            switch( nData1 )
+            {
+                case OMX_ErrorResourcesPreempted:
+                    break;
+                case OMX_ErrorResourcesLost:
+                {
+                    pthread_t thread;
+                    ERROR("OMXVisionCam lost resources!");
+                    pOMXCam->mPreemptionState = VCAM_PREEMPT_SUSPEND;
+                    pthread_create(&thread, NULL, PreemptionThreadLauncher, pOMXCam);
+                    break;
+                }
+                case OMX_ErrorInsufficientResources:
+                {
+                    pthread_t thread;
+                    ERROR("OMXVisionCam has insufficient resources!");
+                    pOMXCam->mPreemptionState = VCAM_PREEMPT_SUSPEND;
+                    pthread_create(&thread, NULL, PreemptionThreadLauncher, pOMXCam);
+                    break;
+                }
+                case OMX_ErrorIncorrectStateOperation:
+                {
+                    break;
+                }
+                case OMX_ErrorInvalidState:
+                {
+                    break;
+                }
+                default:
+
+                    break;
+            }
+            break;
+        }
+        case OMX_EventResourcesAcquired:
+        {
+            break;
+        }
+        case OMX_EventCmdComplete:
+        {
+            switch (nData1)
+            {
+                case OMX_CommandStateSet:
+                    PrintOMXState((OMX_STATETYPE)nData2);
+                    break;
+                case OMX_CommandFlush:
+                case OMX_CommandPortDisable:
+                case OMX_CommandPortEnable:
+                    break;
+            }
+            break;
+        }
+        case OMX_EventPortSettingsChanged:
+        case OMX_EventIndexSettingChanged:
+            MSG("*** Port/Index Settings have Changed!");
+            break;
+        default:
+          break;
+    }
+    return OMX_ErrorNone;
+}
+
+//GRE Empty buffer done callback
+OMX_ERRORTYPE OMXVisionCam::EmptyBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
+                                             OMX_IN OMX_PTR pAppData,
+                                             OMX_IN OMX_BUFFERHEADERTYPE* pBuffHeader)
+{
+//     OMXVisionCam *pOMXCam = (OMXVisionCam *)pAppData;
+    pAppData = pAppData;
+    hComponent = hComponent;
+    pBuffHeader = pBuffHeader;
+    return OMX_ErrorNotImplemented;
+}
+
+//GRE fill buffer done callback
+OMX_ERRORTYPE OMXVisionCam::FillBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
+                                            OMX_IN OMX_PTR pAppData,
+                                            OMX_IN OMX_BUFFERHEADERTYPE* pBuffHeader) {
+    OMXVisionCam* pCam = static_cast<OMXVisionCam*>(pAppData);
+    MSG("OMX-CAMERA has returned a frame (%p) offset=%lu!", pBuffHeader->pAppPrivate, pBuffHeader->nOffset);
+    pCam->mFrameCbData.frames.push_back(pBuffHeader);
+    pthread_mutex_unlock(&pCam->mFrameCbData.mutex);
+    return OMX_ErrorNone;
+}
+
+void OMXVisionCam::frameReceivedSrvc(void *data)
+{
+    OMX_BUFFERHEADERTYPE* pBuffHeader = (OMX_BUFFERHEADERTYPE* )data;
+    VisionCamFrame *cFrame = NULL;
+    VisionCamPort_e portInd = VCAM_PORT_MAX;
+
+    if( !data )
+    {
+        return;
+    }
+
+    if( mFlushInProcess )
+    {
+        return;
+    }
+
+    AutoLock lock(&mFrameBufferLock);
+
+    switch(pBuffHeader->nOutputPortIndex)
+    {
+        case VCAM_CAMERA_PORT_VIDEO_OUT_PREVIEW:
+        {
+            portInd = VCAM_PORT_PREVIEW;
+            break;
+        }
+        case VCAM_CAMERA_PORT_VIDEO_OUT_VIDEO:
+        {
+            portInd = VCAM_PORT_VIDEO;
+            break;
+        }
+        default:
+        {
+            portInd = VCAM_PORT_MAX;
+            break;
+        }
+    }
+
+    if( portInd > VCAM_PORT_ALL && portInd < VCAM_PORT_MAX && mCurGreContext.mCameraPortParams[portInd].mIsActive )
+    {
+        // find the frame descriptor corresponding to received buffer
+        for( int i = 0; i < mCurGreContext.mCameraPortParams[portInd].mNumBufs; i++ )
+        {
+            if( mFrameDescriptors[portInd][i]->mFrameBuff == pBuffHeader->pAppPrivate )
+            {
+                cFrame = mFrameDescriptors[portInd][i];
+                break;
+            }
+        }
+    }
+
+    if( cFrame )
+    {
+        cFrame->mFrameSource     = portInd;
+        cFrame->mLength          = pBuffHeader->nFilledLen;
+        cFrame->mTimestamp       = pBuffHeader->nTimeStamp;
+        cFrame->mWidth           = mCurGreContext.mCameraPortParams[portInd].mWidth;
+        cFrame->mHeight          = mCurGreContext.mCameraPortParams[portInd].mHeight;
+        cFrame->mCookie          = m_cookie;
+        cFrame->mContext         = this;
+        cFrame->mMetadata.mAutoWBGains = NULL;
+        cFrame->mMetadata.mManualWBGains = NULL;
+        cFrame->mMetadata.mAncillary = NULL;
+        cFrame->mMetadata.mHistogram2D = NULL;
+        cFrame->mMetadata.mHistogramL = NULL;
+        cFrame->mMetadata.mHistogramR = NULL;
+        cFrame->mExtraDataBuf    = NULL;
+        cFrame->mExtraDataLength = 0;
+        cFrame->mDetectedFacesNum = 0;
+        memset( cFrame->mFaces, 0, MAX_FACES_COUNT * sizeof(VisionCamFaceType) );
+
+        if( VCAM_PORT_PREVIEW == cFrame->mFrameSource )
+            m_frameNum++;
+
+        if (m_callback != NULL)
+        {
+            m_callback(cFrame);
+        }
+    }
+    else
+    {
+        ERROR("ERROR: a frame buffer is received, but there is no matching buffer." );
+    }
+}
+
+#if TIME_PROFILE
+void OMXVisionCam::PopulateTimeProfiler()
+{
+    mTimeProfiler[ first ] = new VisionCamTimePtofile("first");
+    mTimeProfiler[ second ] = new VisionCamTimePtofile();
+    mTimeProfiler[ last ] = new VisionCamTimePtofile();
+}
+
+VisionCamTimePtofile::VisionCamTimePtofile( const char * name ){
+  memset( &mStart, 0, sizeof(struct timeval) );
+  memset( &mEnd, 0, sizeof(struct timeval) );
+
+  if( name )
+    mName = name;
+  else
+    mName = "unknown";
+};
+
+VisionCamTimePtofile::~VisionCamTimePtofile(){
+    dump();
+};
+
+void VisionCamTimePtofile::dump() {
+    if( mEnd.tv_usec && mStart.tv_usec )
+    {
+        double time = (double)(mEnd.tv_usec = mStart.tv_usec) / (double)1000;
+        printf("TIME: %s - %g [ms]\r", mName, time );
+        memset( &mStart, 0, sizeof(struct timeval) );
+        memset( &mEnd, 0, sizeof(struct timeval) );
+    }
+}
+
+#endif // TIME_PROFILE
diff --git a/omx_cam/OMXVisionCam.h b/omx_cam/OMXVisionCam.h
new file mode 100644 (file)
index 0000000..b16a806
--- /dev/null
@@ -0,0 +1,793 @@
+/* Copyright (C) 2010 Texas Instruments, Inc. All rights reserved. */
+
+#ifndef _OMX_VISIONCAM_H_
+#define _OMX_VISIONCAM_H_
+
+#if defined(WIN32) || defined(UNDER_CE)
+  #include <windows.h>
+#else
+  #include <stdio.h>
+  #include <stdlib.h>
+  #include <math.h>
+  #include <string.h>
+#endif
+
+#include <list>
+
+#include <VisionCam.h>
+
+#include <semaphore.h>
+
+#include <OMX_Types.h>
+#include <OMX_Core.h>
+#include <OMX_IVCommon.h>
+#include <OMX_Component.h>
+#include <OMX_Index.h>
+#include <OMX_TI_Index.h>
+#include <OMX_TI_IVCommon.h>
+#include <OMX_TI_Common.h>
+#include <OMX_CoreExt.h>
+#include <OMX_IndexExt.h>
+
+/** Enables some manual camera contols, like manual white balance color gains and gamma table coeficients. */
+#define OMX_CAMERA_SUPPORTS_MANUAL_CONTROLS
+#define OMX_CAMERA_SUPPORTS_GESTURES
+
+/** Maximum camera output port count, not used. @see VisionCamPort_e */
+const uint32_t USED_PORTS_NUMBER = VCAM_PORT_MAX;
+
+/** Initial frame width. */
+const uint32_t QVGA_WIDTH = 320;
+
+/** Initial frame height. */
+const uint32_t QVGA_HEIGHT = 240;
+
+/** Initial frame rate. */
+const uint32_t INITIAL_FRAMERATE = 30;
+
+/** Minimum value for manual WB color gain. @see VCAM_PARAM_WB_COLOR_GAINS */
+const uint32_t COLOR_GAIN_MIN = 512;
+
+/** Maximum value for manual WB color gain. @see VCAM_PARAM_WB_COLOR_GAINS */
+const uint32_t COLOR_GAIN_MAX = 2048;
+
+/** Maximum white balance delay time. @see VCAM_PARAM_AWB_MIN_DELAY_TIME */
+const uint32_t AWB_Delay_Time_Max = 10000;
+
+/** Minimum white balance delay time. @see VCAM_PARAM_AWB_MIN_DELAY_TIME */
+const uint32_t AWB_Delay_Time_Min = 0;
+
+/** Maimum exposure gain delay time. @see VCAM_PARAM_AGC_MIN_DELAY_TIME */
+const uint32_t AE_Delay_Time_Max = 10000;
+
+/** Minimum exposure gain delay time. @see VCAM_PARAM_AGC_MIN_DELAY_TIME */
+const uint32_t AE_Delay_Time_Min = 0;
+
+/** Maximum count of face data that could be output bu face detction algotithm.
+  * In othe words maximum count of face that could be detected.
+*/
+const uint32_t VCAM_Max_Gesture_Per_Frame = 35;
+
+#define ARR_SIZE(arr) ( sizeof(arr)/sizeof(arr[0]) )
+
+#if TIME_PROFILE
+/** In case ot time profiling this is the start time
+  * of a certain time measurement target.
+*/
+#define TIME_START( time_prof ) {\
+ gettimeofday( &time_prof->mStart , NULL);\
+}
+
+/** In case of time profiling this is the ending time
+  * of a certain time measurement target.
+*/
+#define TIME_END( time_prof ) {\
+ gettimeofday( &time_prof->mEnd , NULL);\
+}
+
+/** @enum TimeProfileTargets
+  * Defines time profiling targets - the commands for which execution time is measured.
+  * This is just an indexing of of measured time windows.
+*/
+typedef enum _time_profile_targets{
+    first,
+    second,
+    last,
+
+    VCAM_TIME_TARGET_MAX
+}TimeProfileTargets;
+
+/** @class VisionCamTimeProfile
+  * Implementation of time profiling.
+  * Each measured time is an object of this type.
+  * Measured time is dumped when this object is destroyed.
+*/
+class VisionCamTimePtofile{
+  public:
+    /** @fn Constructor
+      * @param name     a string that will be used when measured time of dumped.
+    */
+    VisionCamTimePtofile( const char * name = NULL);
+    /** @fn Destructor
+      * Destroys a profiling object and dumps measured time in milliseconds.
+    */
+    ~VisionCamTimePtofile();
+
+    /** @fn dump()
+      * Prints the time measured for execution of command corresponding to this object.
+      * This function, also sets the start and end moment to 0, so it can be used again.
+    */
+    void dump();
+
+    struct timeval mStart;  /** System time at start. */
+    struct timeval mEnd;    /** System time at end. */
+    const char * mName;     /** User defined name of the command. Used when results are shown. */
+};
+#endif
+
+/** @struct OMXVCAM_Msg_t
+  * Message structure used for event handling for OMX Camera events.
+*/
+typedef struct _omxvcam_msg_t {
+    OMX_EVENTTYPE eEvent;       /** Event, defined by OMX IL specification. */
+    OMX_U32 nData1;             /** A data passed by OMX Camera. */
+    OMX_U32 nData2;             /** A data passed by OMX Camera. */
+    sem_t *semaphore;     /** Semaphore on which this event will be expected. */
+    OMX_HANDLETYPE hComponent;  /** OMX Camera component. */
+    OMX_U32 timeout;            /** Semaphore time out. */
+} OMXVCAM_Msg_t;
+
+/** ExtraDataTypeLUT[][]
+  * A look-up table used to translate VisoinCam extra data type to OMX extra data type.
+  * For details about OMX defined extra data types, refer to OMX IL specification.
+  * @see VisionCamExtraDataType_e
+*/
+const int ExtraDataTypeLUT[][ 2 ] =
+{
+  {  VCAM_EXTRA_DATA_NONE,               OMX_ExtraDataNone           },
+//   {  VCAM_EXIF_ATTRIBUTES            ,   VCAM_ExifAttributes          },
+  {  VCAM_ANCILLARY_DATA             ,   OMX_AncillaryData           },
+  {  VCAM_WHITE_BALANCE              ,   OMX_WhiteBalance            },
+#ifndef __QNX__
+  {  VCAM_MANUAL_WHITE_BALANCE       ,   OMX_TI_WhiteBalanceOverWrite   },
+#endif
+  {  VCAM_UNSATURATED_REGIONS        ,   OMX_UnsaturatedRegions      },
+  {  VCAM_FACE_DETECTION             ,   OMX_FaceDetection           },
+//   {  VCAM_BARCODE_DETECTION          ,   OMX_BarcodeDetection        },
+//   {  VCAM_FRONT_OBJECT_DETECTION     ,   OMX_FrontObjectDetection    },
+//   {  VCAM_MOTION_ESTIMATION          ,   OMX_MotionEstimation        },
+//   {  VCAM_DISTANCE_ESTIMATION        ,   OMX_DistanceEstimation      },
+  {  VCAM_HISTOGRAM                  ,   OMX_Histogram               },
+  {  VCAM_FOCUS_REGION               ,   OMX_FocusRegion             },
+//   {  VCAM_EXTRA_DATA_PAN_AND_SCAN    ,   OMX_ExtraDataPanAndScan     },
+//   {  VCAM_RAW_FORMAT                 ,   OMX_RawFormat               },
+//   {  VCAM_SENSOR_TYPE                ,   OMX_SensorType              },
+//   {  VCAM_SENSOR_CUSTOM_DATA_LENGTH  ,   OMX_SensorCustomDataLength  },
+//   {  VCAM_SENSOR_CUSTOM_DATA         ,   OMX_SensorCustomData        }
+};
+
+/** CaptureModeLUT[][]
+  * A look-up table, used to translate VisionCam operating mode to OMX Camera operating mode.
+  * @see VisionCamCaptureMode for supported operating modes.
+*/
+const int CaptureModeLUT[][ 2 ] =
+{
+#if defined(GT_I9100G)
+    { VCAM_VIDEO_NORMAL       , OMX_CaptureVideo                       },
+#else // all other platforms
+    { VCAM_VIDEO_NORMAL       , OMX_CaptureImageProfileBase            },
+#endif
+#if defined(GT_I9100G)
+    { VCAM_VIDEO_HIGH_SPEED   , OMX_CaptureImageHighSpeedTemporalBracketing },
+#else // all other platforms
+    { VCAM_VIDEO_HIGH_SPEED   , OMX_CaptureHighSpeedVideo              },
+#endif
+    { VCAM_GESTURE_MODE       , OMX_TI_CaptureGestureRecognition       },
+    { VCAM_STEREO_MODE        , OMX_CaptureStereoImageCapture          },
+#ifdef OMX_CAMERA_SUPPORTS_STEREO_GESTURES
+    { VCAM_STEREO_GEST_MODE   , OMX_TI_StereoGestureRecognition        },
+#endif
+#if defined(__QNX__)
+    { VCAM_VIEWFINDER_MODE    , OMX_CaptureVideo                       },
+#endif
+    { VCAM_CAP_MODE_MAX       , OMX_CamOperatingModeMax                }
+};
+
+/** FocusModeLUT[][]
+  * A look-up table, use to translate focus modes, supported by VisionCam, to OMX defined focus modes.
+  * @see VisionCamFocusMode for supported focus modes.
+*/
+const int FocusModeLUT[][ 2 ] =
+{
+    { VCAM_FOCUS_CONTROL_ON                     , OMX_IMAGE_FocusControlOn                   },
+    { VCAM_FOCUS_CONTROL_OFF                    , OMX_IMAGE_FocusControlOff                  },
+    { VCAM_FOCUS_CONTROL_AUTO                   , OMX_IMAGE_FocusControlAuto                 },
+    { VCAM_FOCUS_CONTROL_AUTO_LOCK              , OMX_IMAGE_FocusControlAutoLock             },
+#if !defined(__QNX__)
+    { VCAM_FOCUS_CONTRO_AUTO_MACRO              , OMX_IMAGE_FocusControlAutoMacro             },
+#endif
+    { VCAM_FOCUS_CONTROL_AUTO_INFINITY          , OMX_IMAGE_FocusControlAutoInfinity         },
+//    { VCAM_FOCUS_FACE_PRIORITY_MODE             , OMX_IMAGE_FocusFacePriorityMode            },
+//    { VCAM_FOCUS_REGION_PRIORITY_MODE           , OMX_IMAGE_FocusRegionPriorityMode          },
+    { VCAM_FOCUS_CONTROL_HYPERFOCAL             , OMX_IMAGE_FocusControlHyperfocal           },
+    { VCAM_FOCUS_CONTROL_PORTRAIT               , OMX_IMAGE_FocusControlPortrait             },
+    { VCAM_FOCUS_CONTROL_EXTENDED               , OMX_IMAGE_FocusControlExtended             },
+    { VCAM_FOCUS_CONTROL_CONTINOUS_NORMAL       , OMX_IMAGE_FocusControlContinousNormal      },
+#if !defined(__QNX__)
+    { VCAM_FOCUS_CONTROL_CONTINOUS_EXTENDED     , OMX_IMAGE_FocusControlContinousExtended    },
+#else
+    { VCAM_FOCUS_CONTROL_CONTINOUS_EXTENDED     , OMX_TI_IMAGE_FocusControlContinuousExtended  },
+#endif
+//    { VCAM_FOCUS_FACE_PRIORITY_CONTINOUS_MODE   , OMX_IMAGE_FocusFacePriorityContinousMode   },
+//    { VCAM_FOCUS_REGION_PRIORITY_CONTINOUS_MODE , OMX_IMAGE_FocusRegionPriorityContinousMode },
+    { VCAM_FOCUS_CONTROL_MAX                    , OMX_IMAGE_FocusControlMax                  }
+};
+
+/** MirrorTypeLUT[][]
+  * A look-up table, used to translate VisionCam supported mirroring modes, to OMX mirror modes.
+  * @see VisionCamMirrorType
+*/
+const int MirrorTypeLUT[][ 2 ] =
+{
+    {   VCAM_MIRROR_NONE        ,   OMX_MirrorNone          },
+    {   VCAM_MIRROR_VERTICAL    ,   OMX_MirrorVertical      },
+    {   VCAM_MIRROR_HORIZONTAL  ,   OMX_MirrorHorizontal    },
+    {   VCAM_MIRROR_BOTH        ,   OMX_MirrorBoth          },
+    {   VCAM_MIRROR_MAX         ,   OMX_MirrorMax           }
+};
+
+#if ( defined(DUCATI_1_5) || defined(DUCATI_2_0) ) && defined(OMX_CAMERA_SUPPORTS_GESTURES)
+/** GestureTypeLUT[][]
+  * A look-up table, used to translate VisionCam defined gesture events, to OMX defined gesture events.
+  * @see VisionCamGestureEvent_e
+*/
+const int GestureTypeLUT[][2] =
+{
+    { VCAM_GESTURE_EVENT_INVALID         , OMX_TI_GESTURE_NO_GESTURE     },
+    { VCAM_GESTURE_EVENT_SWIPE_LEFT      , OMX_TI_GESTURE_SWIPE_LEFT     },
+    { VCAM_GESTURE_EVENT_SWIPE_RIGHT     , OMX_TI_GESTURE_SWIPE_RIGHT    },
+    { VCAM_GESTURE_EVENT_FIST_LEFT       , OMX_TI_GESTURE_FIST_LEFT      },
+    { VCAM_GESTURE_EVENT_FIST_RIGHT      , OMX_TI_GESTURE_FIST_RIGHT     },
+    { VCAM_GESTURE_EVENT_MAX             , OMX_TI_GESTURE_MAX            }
+};
+
+/** ObjectTypeLUT[][]
+  * A look-up table, used to translate VisionCam gesture object type to coresponding OMX gesture object.
+  * @see VisionCamObjectType
+*/
+const int ObjectTypeLUT[][2] =
+{
+    { VCAM_OBJECT_PALM , OMX_TI_OBJECT_PALM },
+    { VCAM_OBJECT_FIST , OMX_TI_OBJECT_FIST },
+    { VCAM_OBJECT_FACE , OMX_TI_OBJECT_FACE },
+    { VCAM_OBJECT_MAX  , OMX_TI_OBJECT_MAX  }
+};
+#endif
+
+/** StereoLayoutLUT[][]
+  * A look-up table, used to translate VisionCam defined stereo layouts to OMX stereo layouts.
+  * @see VisionCamStereoLayout
+*/
+const int StereoLayoutLUT[][2] =
+{
+    {   VCAM_STEREO_LAYOUT_TOPBOTTOM,   OMX_TI_StereoFrameLayoutTopBottom   },
+    {   VCAM_STEREO_LAYOUT_LEFTRIGHT,   OMX_TI_StereoFrameLayoutLeftRight   },
+    {   VCAM_STEREO_LAYOUT_MAX,         OMX_TI_StereoFrameLayoutMax         }
+};
+
+/** OMX index of preview frame output port. */
+const int VCAM_CAMERA_PORT_VIDEO_OUT_PREVIEW = 2;
+
+/** OMX index of video frame output port. */
+const int VCAM_CAMERA_PORT_VIDEO_OUT_VIDEO = 3;
+
+/** Needed for priority memagement. Camera Group ID is set DOMX layers. */
+const unsigned int CAMERA_GROUP_ID = 8;
+
+/** @fn void* PreemptionThreadLauncher( void *arg )
+  * A thread function that implements preemption mechanism for OMXVisionCam.
+  * Preemption model used here is defined by OMX standard.
+  * @param arg  The instance of OMXVisionCam that is preempted.
+*/
+void* PreemptionThreadLauncher( void *arg );
+
+/** void* FrameThreadFunc(void *arg)
+  * Thread function that implements frame transmit/receive mechanism between user and OMX camera.
+  * @param arg  Thee instance of OMXVisinCam that this thead serves.
+*/
+void* FrameThreadFunc(void *arg);
+
+/** @class OMXVisionCam
+  * @implements VisionCam
+  *
+  * Implements OMX Camera interface. Publicly inherits VisionCam.
+  * This is the final point before camera specific software inplementaion.
+*/
+class OMXVisionCam : public VisionCam
+{
+protected:
+    OMX_HANDLETYPE* mHandle;
+
+private: // internal data types
+
+    /** @class VCAM_PortParameters
+      * Keeps all the data needed to control certain camera output port.
+    */
+    class VCAM_PortParameters
+    {
+    public:
+//        OMX_U32                         mHostBufaddr[VCAM_NUM_BUFFERS]; /** The address of each buffer assigned to this port. This is only used for tailor buffers. @todo check if last is true (gingerbread, froyo) */
+        OMX_BUFFERHEADERTYPE           *mBufferHeader[VCAM_NUM_BUFFERS];/** Buffer specific data, generated by OMX camera handle at the time a buffer is registered. */
+        OMX_U32                         mWidth;                         /** Image width in pixels of a buffer. @see fourcc_t definitions to check pixel in bytes size for different formats. */
+        OMX_U32                         mHeight;                        /** Image height in pixels of a buffer. */
+        OMX_U32                         mStride;                        /** Byte distance from one pixel to the next pixel in the y direction. */
+        OMX_U8                          mNumBufs;                       /** Number of buffers assigned to this port. */
+        OMX_U32                         mBufSize;                       /** The size of a buffer in bytes. */
+        OMX_COLOR_FORMATTYPE            mColorFormat;                   /** The fourcc_t color fomat used to calculate buffer allocation sizes. This must be also the color format applied to OMX camera. */
+//        OMX_PARAM_VIDEONOISEFILTERTYPE  mVNFMode;                       /** Video noise filtering mode: on, off or auto. @todo check if used */
+//        OMX_PARAM_VIDEOYUVRANGETYPE     mYUVRange;                      /** Frame YUV Range. @todo check if used */
+//        OMX_CONFIG_BOOLEANTYPE          mVidStabParam;                  /** Video stabilisation mode: enabled or disabled. @todo check if used and needed at all. */
+//        OMX_CONFIG_FRAMESTABTYPE        mVidStabConfig;                 /** Video stabilisation mode: enabled or disabled. @todo check if used and needed at all. */
+//        OMX_U32                         mCapFrame;                      /** @todo is it used. */
+        OMX_U32                         mFrameRate;                     /** Frame rate. @note Frame rate is applied to all ports. */
+        OMX_U32                         mRotation;                      /** Applied rotation. @see VisionCamRotation_e */
+        bool                          mIsActive;                      /** Indicates if this port is currently outputting any data. */
+    };
+
+    /** @class VCAM_ComponentContext
+      * Holds the current status of OMX camera handle.
+    */
+    class VCAM_ComponentContext
+    {
+    public:
+        OMX_HANDLETYPE              mHandleComp;                            /** The camera handle. */
+        OMX_U32                     mNumPorts;                              /** Number of ports that camera could use. */
+        /*VisionCamPort_e*/ OMX_U32            mPortsInUse[VCAM_PORT_MAX];  /** Output port indexes, as they are defined in OMX camera. */
+        OMX_U32                     mExtraDataPortIndex;                    /** @todo remove me! */
+        VCAM_PortParameters         mCameraPortParams[VCAM_PORT_MAX];       /** The parameters for each port. */
+    };
+
+    /** @struct BuffersInUse_t
+      * A structure that packs a buffer array and buffer count.
+      @todo move to port parameters
+    */
+    typedef struct BuffersInUse_t {
+        BufferMeta* mBuffers;       /** Array of buffers. */
+        uint32_t mNumberBuffers;    /** Number of buffers. */
+    } BuffersInUse_t;
+
+    /** @enum ValueTypeOrigin
+      * Used to parse look-up tables.
+      * Marks where exactly the value, for which a match is searched, is defined.
+    */
+    typedef enum
+    {
+        VCAM_VALUE_TYPE = 0,    /** Value is defined in VisionCam and matching OMX value is searched. */
+        OMX_VALUE_TYPE = 1      /** Value is defined in OMX and matching VisionCam value is searched. */
+    } ValueTypeOrigin ;
+
+    /** @enum VisionCamPreemptionActivity_e
+      * Used to define component preemption stage.
+    */
+    enum VisionCamPreemptionActivity_e {
+        VCAM_PREEMPT_INACTIVE,      /** No preemption is started. */
+        VCAM_PREEMPT_SUSPEND,       /** OMX camera was preempted by a process with a higher priority than VisionCam, so VisionCam has to be suspended. */
+        VCAM_PREEMPT_RESUME,        /** VisionCam is ready to continue its work, after it has been suspended. */
+        VCAM_PREEMPT_WAIT_TO_START  /** VisionCam is waiting to get the control over camera. */
+    };
+
+    /** @typedef int(*serviceFunc)(OMXVisionCam *, void *)
+      * Pointer to a serving function.
+      * Serving functions are used in the cases where additional setup must be done
+      * in order for a certain job to be finished by camera.
+    */
+    typedef int(*serviceFunc)(OMXVisionCam *, void *);
+// Inherited Methods from VisionCam
+public:
+    /** Constructor. */
+    OMXVisionCam();
+    /** Destructor. */
+    ~OMXVisionCam();
+
+    /** @fn int init(void * cookie)
+      * Initialises OMXVisionCam, gets a camera handle and gives some default values.
+    */
+    int init(void * cookie);
+
+    /** @fn int deinit()
+      * Deinits OMXVisionCam, releases the camera and frees all available resources.
+    */
+    int deinit();
+
+    /** @fn int useBuffers(BufferMeta* meta, uint32_t num_images, VisionCamPort_e port)
+      * Registers and allocates (internal for OMXVisionCam) frame descriptor for each buffer passed.
+      * This way, buffers are ready to be passed to OMX camera. Implements VisionCam::useBuffers().
+      * @param *prvBufArr   array of buffers as thay are allocated.
+      * @param numPrvBuf    number of the buffers in this array.
+      * @param port         the port on which these buffers must be assigned to.
+    */
+    int useBuffers(BufferMeta* meta, uint32_t num_images, VisionCamPort_e port);
+
+    /** @fn int releaseBuffers( VisionCamPort_e port )
+      * Unregisters (internal for OMXVisionCam) all buffers registered with useBuffers() to OMXVisoinCam
+      * and frees corresponding frame descriptors. Implements VisionCam::releaseBuffers().
+      * @param port     the port on which these buffers are assigned.
+    */
+    int releaseBuffers( VisionCamPort_e port );
+
+    /** @fn int flushBuffers( VisionCamPort_e port )
+      *
+    */
+    int flushBuffers( VisionCamPort_e port );
+
+    /** @fn int sendCommand( VisionCamCmd_e cmdId, void *param, uint32_t size, VisionCamPort_e port )
+      * Requests camera to execute some additional functionality. Implements VisionCam::sendCommand().
+      * @param cmdId    the command id that bust be executed.
+      * @param param    pointer to additional data that refers to this command.
+      * @param size     size of data pointed by param.
+      * @param port     the port on which this must be executed.
+      * @return         STATUS_SUCCESS on success and any other error code otherwise.
+      * @see VisionCamCmd_e     for possible commands.
+      * @see VisionCamPort_e    for available ports.
+    */
+    int sendCommand( VisionCamCmd_e cmdId, void *param, uint32_t size, VisionCamPort_e port );
+
+    /** @fn int setParameter( VisionCamParam_e paramId, void* param, uint32_t size, VisionCamPort_e port)
+      * Configure the camera with supplied parameter. Implements VisionCam::setParameter().
+      * @param  paramId ID of the parameter that has to be applied.
+      * @param  param   Pointer to parameter data.
+      * @param  size    Size of parameter data.
+      * @param  port    Output port for which this parameters will be applied.
+      * @return         STATUS_SUCCESS on success and any other error code otherwise.
+      * @see VisionCamParam_e   for possible parameters.
+      * @see VisionCamPort_e    for available ports.
+    */
+    int setParameter( VisionCamParam_e paramId, void* param, uint32_t size, VisionCamPort_e port);
+
+    /** @fn int getParameter( VisionCamParam_e paramId, void* param, uint32_t size, VisionCamPort_e port)
+      * Reads camera configuration parameter. Implements VisionCam::getParameter().
+      * @param  paramId ID of the parameter that has to be read.
+      * @param  param   Pointer to user allocated space, where parameter value will be written.
+      * @param  size    Size of parameter data.
+      * @param  port    Output port for which this parameters are applied.
+      * @return         STATUS_SUCCESS on success and any other error code otherwise.
+      * @see VisionCamParam_e   for possible parameters.
+      * @see VisionCamPort_e    for available ports.
+    */
+    int getParameter( VisionCamParam_e paramId, void* param, uint32_t size, VisionCamPort_e port);
+
+    /** @fn int returnFrame( VisionCamFrame *cameraFrame )
+      * This must be called after VisionCam client has finished his job with a frame buffer.
+      * With this, user notifies VisionCam that this frame buffer is ready to be returned back to camera.
+      * @param cameraFrame The pointer to the frame given to the user which is now completed.
+      */
+    int returnFrame( VisionCamFrame *cameraFrame );
+
+private:
+    // OMXVisionCam
+    /** @fn int startPreview( VisionCamPort_e port )
+      * Signals the camera to start a streaming a frames on a certain output port.
+      * @param port the port on which this streaming shold be started.
+      * @return         STATUS_SUCCESS on success and any other error code otherwise.
+    */
+    int startPreview( VisionCamPort_e port );
+
+    /** @fn int stopPreview( VisionCamPort_e port )
+      * Signals the camera to stop a streaming a frames on a certain output port.
+      * @param port the port on which this streaming shold be stopped.
+      * @return     STATUS_SUCCESS on success and any other error code otherwise.
+    */
+    int stopPreview( VisionCamPort_e port );
+
+    /** @fn inline OMX_STATETYPE getComponentState()
+      * Gets current state of OMX camera.
+    */
+    inline OMX_STATETYPE getComponentState();
+
+    /** @fn inline OMX_ERRORTYPE initPortCheck( OMX_PARAM_PORTDEFINITIONTYPE * portCheck , OMX_U32 portIndex )
+      * Read and initialises current configuration applied to a certain output port.
+      * The configuratin structure is passed by a pointer so it can be used later for port reconfiguration.
+      * @param portCheck    configuratin structure pointer that will be filled with appropriate data.
+      * @param portIndex    one of VisionCamPort_e port indexes; this is the port which configuration is requested
+      * @return OMX_ErrorNone on successful read.
+    */
+    inline OMX_ERRORTYPE initPortCheck( OMX_PARAM_PORTDEFINITIONTYPE * portCheck , OMX_U32 portIndex );
+
+    /** @fn inline int ConvertError(OMX_ERRORTYPE error)
+      * Converts OMX error codes to VisionCam error codes (int)
+      * @param error one of OMX error codes.
+      * @return  int value.
+      * @see int
+    */
+    inline int ConvertError(OMX_ERRORTYPE error);
+
+    /** @fn inline int getLutValue( int searchVal, ValueTypeOrigin origin, const int lut[][2], int lutSize)
+      * Parses VisionCam <-> OMX look-up tables.
+      * @param searchVal    The value for which a match is required.
+      * @param origin       Indicates if searchVal is defined by VisionCam or by OMX.
+      *                     Depending on that, returned value is respectively OMX or VisionCam defined.
+      * @param lut[][2]     The look-up table to be parsed.
+      * @param lutSize      Number of couples in this table.
+      * @return             The value corresponding to searchVal.
+    */
+    inline int getLutValue( int searchVal, ValueTypeOrigin origin, const int lut[][2], int lutSize);
+
+
+    /** @fn void GetDucatiVersion()
+      * Gets currnet domx version.
+    */
+    void GetDucatiVersion();
+
+    /** @fn OMX_ERRORTYPE RegisterForEvent(OMX_IN OMX_HANDLETYPE hComponent,
+                                           OMX_IN OMX_EVENTTYPE eEvent,
+                                           OMX_IN OMX_U32 nData1,
+                                           OMX_IN OMX_U32 nData2,
+                                           OMX_IN sem_t *semaphore,
+                                           OMX_IN OMX_U32 timeout)
+      * Creates an event message and adds it to the list of events that are expected to occur at OMX side.
+    */
+    OMX_ERRORTYPE RegisterForEvent(OMX_IN OMX_HANDLETYPE hComponent,
+                                   OMX_IN OMX_EVENTTYPE eEvent,
+                                   OMX_IN OMX_U32 nData1,
+                                   OMX_IN OMX_U32 nData2,
+                                   OMX_IN sem_t *semaphore,
+                                   OMX_IN OMX_U32 timeout);
+
+    /** @fn     static OMX_ERRORTYPE EventHandler(OMX_IN OMX_HANDLETYPE hComponent,
+                                              OMX_IN OMX_PTR pAppData,
+                                              OMX_IN OMX_EVENTTYPE eEvent,
+                                              OMX_IN OMX_U32 nData1,
+                                              OMX_IN OMX_U32 nData2,
+                                              OMX_IN OMX_PTR pEventData);
+      *
+      * OMX event handler. This is a callback function, registerd in OMX component, by the time of its initialization.
+      * It is invoked every time an event is generated by camera.
+      * The events handled are not only internal camera events,
+      * but also a results ot some external processes that deal with camera.
+    */
+    static OMX_ERRORTYPE EventHandler(OMX_IN OMX_HANDLETYPE hComponent,
+                                              OMX_IN OMX_PTR pAppData,
+                                              OMX_IN OMX_EVENTTYPE eEvent,
+                                              OMX_IN OMX_U32 nData1,
+                                              OMX_IN OMX_U32 nData2,
+                                              OMX_IN OMX_PTR pEventData);
+
+    /** @fn static OMX_ERRORTYPE EmptyBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
+                                         OMX_IN OMX_PTR pAppData,
+                                         OMX_IN OMX_BUFFERHEADERTYPE* pBuffer);
+      * A callback notifing that OMX camera has unregistered a buffer and has freed its buffer header.
+    */
+    static OMX_ERRORTYPE EmptyBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
+                                         OMX_IN OMX_PTR pAppData,
+                                         OMX_IN OMX_BUFFERHEADERTYPE* pBuffer);
+
+    /** @fn static OMX_ERRORTYPE FillBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
+                                        OMX_IN OMX_PTR pAppData,
+                                        OMX_IN OMX_BUFFERHEADERTYPE* pBuffHeader);
+      *
+      * A callback notifing that OMX camera has wrote a frame buffer and it is ready to be passed to user.
+    */
+    static OMX_ERRORTYPE FillBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
+                                        OMX_IN OMX_PTR pAppData,
+                                        OMX_IN OMX_BUFFERHEADERTYPE* pBuffHeader);
+
+//    /** int frameReceiveService(OMX_IN OMX_BUFFERHEADERTYPE* pBuffHeader)
+//      *
+//    */
+//    int frameReceiveService(OMX_IN OMX_BUFFERHEADERTYPE* pBuffHeader);
+
+    /** @fn OMX_ERRORTYPE setPortDef( int portIndex )
+      * Configures a port. Sets the data that port needs to get ready for image processing.
+      * @param portIndex    VisionCam defined index of the port.
+      * @see   VisionCamPort_e
+      * @return OMX_ErrorNone on success.
+    */
+    OMX_ERRORTYPE setPortDef( int portIndex/*, VCAM_PortParameters * portData*/);
+
+    /** @fn int startAutoFocus( VisionCamFocusMode focusMode )
+      * Starts auto focus in a certain mode. Starts a thread that will wait for focus event.
+      * @param      focusMode   mode in which auto focus must start.
+      * @see        VisionCamFocusMode
+      * @return     STATUS_SUCCESS on success and any other error code otherwise.
+    */
+    int startAutoFocus( VisionCamFocusMode focusMode );
+
+    /** @fn int enableFaceDetect(VisionCamPort_e port)
+      * This will configure the component to start/stop face detection.
+      * Will also start/stop face detection extra data
+      * faces coordinates will be written into camera frame received in preview callback.
+      * @see        VisionCamFaceType
+      * @see        VisionCamFrame::mFaces
+      * @return     STATUS_SUCCESS on success and any other error code otherwise.
+    */
+    int enableFaceDetect(VisionCamPort_e port);
+
+    /** @fn void getFacesCoordinates( VisionCamFrame *frame)
+      * Fill the face coordinates field in camera frame,
+      * which will be received by OMXVisionCam client at each frame.
+      * @param frame    a frame descripror.
+    */
+    void getFacesCoordinates( VisionCamFrame *frame);
+
+    /** @fn void getMetadataPtrs( VisionCamFrame *frame)
+      * Parse through the extra data type structure to find the pointer to the relevent
+      * data type.  This is to abstract the port number, version, and packet structure from the client.
+      * @param frame    pointer to a frame descripror.
+    */
+    void getMetadataPtrs( VisionCamFrame *frame);
+
+    /** @fn OMX_ERRORTYPE getFocusStatus(OMX_FOCUSSTATUSTYPE *status)
+      * Gest current status of focus command execution.
+      * @param *status   points to the variable, where focus status will be written.
+      * @return OMX_ErrorNone on success.
+    */
+    OMX_ERRORTYPE getFocusStatus(OMX_FOCUSSTATUSTYPE *status);
+
+    /** @fn int transitToState(OMX_STATETYPE targetState, serviceFunc transitionService = NULL, void * data = NULL)
+      * Sets OMX camera in a certain state. Camera state represent camera behaviour and configuration status.
+      * @param targetState          the state that must be reached. Refer to OMX_STATETYPE in OMX IL specification.
+      * @param transitionService    in some cases, OMXVisionCam must do additional steps in order for camera to reach requested state.
+      *                             transitionService must point to the function that does this steps.
+      * @param data                 any data (like buffers for example), that may be needed for this transition to finish.
+      * @return     STATUS_SUCCESS on success and any other error code otherwise.
+      * @see                        serviceFunc
+    */
+    int transitToState(OMX_STATETYPE targetState, serviceFunc transitionService = NULL, void * data = NULL);
+
+    /** @fn int portEnableDisable( OMX_COMMANDTYPE enCmd, serviceFunc enablementService, VisionCamPort_e port )
+      * Enables and disables a port. Enabled port transfers frames only if camera is in OMX_StateExecuting.
+      * @param enCmd                shows whether to enable the port or to disable it.
+      * @param enablementService    pointer to a function that will do the additinal steps that may be needed for this port to execute this enablement command.
+      * @param port                 Index of the port that has to be enabled/disabled.
+      * @return STATUS_SUCCESS on success and any other error code otherwise.
+    */
+    int portEnableDisable( OMX_COMMANDTYPE enCmd, serviceFunc enablementService, VisionCamPort_e port );
+
+    /** @fn int PreemptionService()
+      * Handle preemption events. Takes care of all the steps needed in order preempt camera without bothering its normal work.
+      * @return STATUS_SUCCESS on success and any other error code otherwise.
+    */
+    int PreemptionService();
+
+    /** @fn friend void* PreemptionThreadLauncher( void *arg )
+      * Started by OMXVisionCam::EventHandler(), this thread function, call preemption service.
+    */
+    friend void* PreemptionThreadLauncher( void *arg );
+
+    /** @fn int populatePort( VisionCamPort_e port )
+      * Registers all buffers, that user has passed to OMXVisionCam, to OMX camera.
+      * @param port     specifies tha port on which these buffers must be supplied.
+      * @return STATUS_SUCCESS on success and any other error code otherwise.
+    */
+    int populatePort( VisionCamPort_e port );
+
+    /** @fn static inline int populatePortSrvc( OMXVisionCam *inst, void *in )
+      * Function that may be called during camera state transitions or port eneblement.
+      * @return STATUS_SUCCESS on success and any other error code otherwise.
+    */
+    static inline int populatePortSrvc( OMXVisionCam *inst, void *in )
+    {
+        VisionCamPort_e whichPort = *(VisionCamPort_e*)in;
+        return inst->populatePort( whichPort );
+    }
+
+    /** @fn int fillPortBuffers( VisionCamPort_e port )
+      * Requests the camera to start wrtiting into buffers suppiled on a port.
+      * This is needed in some state transitions and sometimes during port enable command, depending on camera state.
+      * Basically this is needed when preview is started.
+      * @param port     the port on which buffers are supplied.
+      * @return STATUS_SUCCESS on success and any other error code otherwise.
+    */
+    int fillPortBuffers( VisionCamPort_e port );
+
+    /** @fn static inline int populatePortSrvc( OMXVisionCam *inst, void *in )
+      * Function that may be called during camera state transitions or port eneblement.
+      * @return STATUS_SUCCESS on success and any other error code otherwise.
+    */
+    static inline int fillPortBuffersSrvc( OMXVisionCam *inst, void *in )
+    {
+        VisionCamPort_e whichPort = *(VisionCamPort_e*)in;
+        return inst->fillPortBuffers( whichPort );
+    }
+
+    /** @fn int freePortBuffers( VisionCamPort_e port )
+      * Request the camera to unregister all buffers supplied to a port.
+      * Internally, the camera will  free its buffer headers.
+      * Basically this is done by the time preview is stopped.
+      * @param port     the port for which buffers must be released.
+      * @return STATUS_SUCCESS on success and any other error code otherwise.
+    */
+    int freePortBuffers( VisionCamPort_e port );
+
+    /** @fn static inline int freePortBuffersSrvc( OMXVisionCam *inst, void *in )
+      * Function that may be called during camera state transitions or port eneblement.
+      * @return STATUS_SUCCESS on success and any other error code otherwise.
+    */
+    static inline int freePortBuffersSrvc( OMXVisionCam *inst, void *in )
+    {
+        VisionCamPort_e whichPort = *((VisionCamPort_e*)in);
+        return inst->freePortBuffers( whichPort );
+    }
+
+public:
+    /** @fn int waitForFocus()
+      * Waits for focus reached event.
+      * @return STATUS_SUCCESS on success and any other error code otherwise.
+    */
+    int waitForFocus();
+
+    /** @fn void frameReceivedSrvc(void *data)
+      * Called inside frame thread, when a frame arrives,
+      * this function pareses the frame data and sends it to user via preview callback.
+      * @note In cases when a frame packing option is enabled and more then one output ports are running,
+      * then the frames from different ports are put into a packet and are sent to user only when all the ports have sent a frame.
+      * @see thread_t mFrameThread
+      * @see queue_t *mFrameMessageQ
+    */
+    void frameReceivedSrvc(void *data);
+
+    /** @var thread_t mFrameThread
+      * The thread that waits for frame event.
+      * This thead is responsible for packing a frames, if needed, and sending them to VisionCam client.
+      *
+      * @see void frameReceivedSrvc(void *data)
+      * @see queue_t *mFrameMessageQ
+    */
+    pthread_t mFrameThread;
+
+    /** @var queue_t *mFrameMessageQ
+      *
+    */
+    struct CallbackData {
+      pthread_mutex_t                  mutex;
+      std::list<OMX_BUFFERHEADERTYPE*> frames;
+      CallbackData() {
+        pthread_mutex_init(&mutex, NULL);
+      }
+      ~CallbackData() {
+        pthread_mutex_destroy(&mutex);
+      }
+    };
+    CallbackData mFrameCbData;
+
+private:
+    bool mFlushInProcess;
+    VisionCamPreemptionActivity_e mPreemptionState;
+
+    OMX_PRIORITYMGMTTYPE mVisionCamPriority;
+    VisionCamFrame ** mFrameDescriptors[VCAM_PORT_MAX];
+    VCAM_ComponentContext mCurGreContext;
+    OMX_VERSIONTYPE *mLocalVersion;
+    OMX_CALLBACKTYPE mGreCallbacks;
+
+    BuffersInUse_t mBuffersInUse[VCAM_PORT_MAX];
+
+    pthread_mutex_t mFrameBufferLock;
+    pthread_mutex_t mUserRequestLock;
+
+    sem_t mGreLocalSem;
+    sem_t mGreFocusSem;
+    sem_t mFrameReceivedSem;
+
+    std::list<OMXVCAM_Msg_t*> mEventSignalQ;
+
+    uint32_t mManualFocusDistance;
+
+    bool mFaceDetectionEnabled;
+    bool mReturnToExecuting;
+
+    VisionCamClientNotifier mClientNotifier;
+
+    VisionCamFramePack mFramePackage;
+    bool mUseFramePackaging;
+
+#ifdef _USE_GAMMA_RESET_HC_
+    bool mGammaResetPolulated;
+#endif /// _USE_GAMMA_RESET_HC_
+#if TIME_PROFILE
+    VisionCamTimePtofile * mTimeProfiler[ VCAM_TIME_TARGET_MAX ];
+    void PopulateTimeProfiler();
+#endif
+};
+
+#endif
diff --git a/omx_cam/OMXVisionCam_Gamma_Tbl.h b/omx_cam/OMXVisionCam_Gamma_Tbl.h
new file mode 100644 (file)
index 0000000..b2806d5
--- /dev/null
@@ -0,0 +1,836 @@
+#ifndef _gamma_tables_
+#define _gamma_tables_
+
+const uint8_t mGammaTablesBuf[] = {
+    0x0E, 0x00, 0x00, 0x00, /// ID -> 4 bytes
+
+    0x03,           /// eGammaTblSize -> 1 byte
+    0x00,           /// nTbl -> 1 byte
+    0x00,           /// eBypassB -> 1 byte
+    0x00,           /// eBypassG -> 1 byte
+    0x00,           /// eBypassR -> 1 byte
+    0x00, 0x00, 0x00, 0x04, /// *pnRedTable
+    0x00, 0x00, 0x00, 0x04, /// *pnBlueTable
+    0x08, 0x00, 0x00, 0x04, /// *pnGreenTable
+
+    0x10, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02,0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00,
+    0x06, 0x00, 0x02, 0x00, 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x02, 0x00, 0x0c, 0x00, 0x02, 0x00,
+    0x0e, 0x00, 0x02, 0x00, 0x10, 0x00, 0x02, 0x00, 0x12, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00,
+    0x16, 0x00, 0x02, 0x00, 0x18, 0x00, 0x02, 0x00, 0x1a, 0x00, 0x02, 0x00, 0x1c, 0x00, 0x02, 0x00,
+    0x1e, 0x00, 0x02, 0x00, 0x20, 0x00, 0x02, 0x00, 0x22, 0x00, 0x02, 0x00, 0x24, 0x00, 0x02, 0x00,
+    0x26, 0x00, 0x02, 0x00, 0x28, 0x00, 0x02, 0x00, 0x2a, 0x00, 0x02, 0x00, 0x2c, 0x00, 0x02, 0x00,
+    0x2e, 0x00, 0x02, 0x00, 0x30, 0x00, 0x02, 0x00, 0x32, 0x00, 0x02, 0x00, 0x34, 0x00, 0x02, 0x00,
+    0x36, 0x00, 0x02, 0x00, 0x38, 0x00, 0x02, 0x00, 0x3a, 0x00, 0x02, 0x00, 0x3c, 0x00, 0x02, 0x00,
+    0x3e, 0x00, 0x02, 0x00, 0x40, 0x00, 0x02, 0x00, 0x42, 0x00, 0x02, 0x00, 0x44, 0x00, 0x02, 0x00,
+    0x46, 0x00, 0x02, 0x00, 0x48, 0x00, 0x02, 0x00, 0x4a, 0x00, 0x02, 0x00, 0x4c, 0x00, 0x02, 0x00,
+    0x4e, 0x00, 0x02, 0x00, 0x50, 0x00, 0x02, 0x00, 0x52, 0x00, 0x02, 0x00, 0x54, 0x00, 0x02, 0x00,
+    0x56, 0x00, 0x02, 0x00, 0x58, 0x00, 0x02, 0x00, 0x5a, 0x00, 0x02, 0x00, 0x5c, 0x00, 0x02, 0x00,
+    0x5e, 0x00, 0x02, 0x00, 0x60, 0x00, 0x02, 0x00, 0x62, 0x00, 0x02, 0x00, 0x64, 0x00, 0x02, 0x00,
+    0x66, 0x00, 0x02, 0x00, 0x68, 0x00, 0x02, 0x00, 0x6a, 0x00, 0x02, 0x00, 0x6c, 0x00, 0x02, 0x00,
+    0x6e, 0x00, 0x02, 0x00, 0x70, 0x00, 0x02, 0x00, 0x72, 0x00, 0x02, 0x00, 0x74, 0x00, 0x02, 0x00,
+    0x76, 0x00, 0x02, 0x00, 0x78, 0x00, 0x02, 0x00, 0x7a, 0x00, 0x02, 0x00, 0x7c, 0x00, 0x02, 0x00,
+    0x7e, 0x00, 0x02, 0x00, 0x80, 0x00, 0x02, 0x00, 0x82, 0x00, 0x02, 0x00, 0x84, 0x00, 0x02, 0x00,
+    0x86, 0x00, 0x02, 0x00, 0x88, 0x00, 0x02, 0x00, 0x8a, 0x00, 0x02, 0x00, 0x8c, 0x00, 0x02, 0x00,
+    0x8e, 0x00, 0x02, 0x00, 0x90, 0x00, 0x02, 0x00, 0x92, 0x00, 0x02, 0x00, 0x94, 0x00, 0x02, 0x00,
+    0x96, 0x00, 0x02, 0x00, 0x98, 0x00, 0x02, 0x00, 0x9a, 0x00, 0x02, 0x00, 0x9c, 0x00, 0x02, 0x00,
+    0x9e, 0x00, 0x02, 0x00, 0xa0, 0x00, 0x02, 0x00, 0xa2, 0x00, 0x02, 0x00, 0xa4, 0x00, 0x02, 0x00,
+    0xa6, 0x00, 0x02, 0x00, 0xa8, 0x00, 0x02, 0x00, 0xaa, 0x00, 0x02, 0x00, 0xac, 0x00, 0x02, 0x00,
+    0xae, 0x00, 0x02, 0x00, 0xb0, 0x00, 0x02, 0x00, 0xb2, 0x00, 0x02, 0x00, 0xb4, 0x00, 0x02, 0x00,
+    0xb6, 0x00, 0x02, 0x00, 0xb8, 0x00, 0x02, 0x00, 0xba, 0x00, 0x02, 0x00, 0xbc, 0x00, 0x02, 0x00,
+    0xbe, 0x00, 0x02, 0x00, 0xc0, 0x00, 0x02, 0x00, 0xc2, 0x00, 0x02, 0x00, 0xc4, 0x00, 0x02, 0x00,
+    0xc6, 0x00, 0x02, 0x00, 0xc8, 0x00, 0x02, 0x00, 0xca, 0x00, 0x02, 0x00, 0xcc, 0x00, 0x02, 0x00,
+    0xce, 0x00, 0x02, 0x00, 0xd0, 0x00, 0x02, 0x00, 0xd2, 0x00, 0x02, 0x00, 0xd4, 0x00, 0x02, 0x00,
+    0xd6, 0x00, 0x02, 0x00, 0xd8, 0x00, 0x02, 0x00, 0xda, 0x00, 0x02, 0x00, 0xdc, 0x00, 0x02, 0x00,
+    0xde, 0x00, 0x02, 0x00, 0xe0, 0x00, 0x02, 0x00, 0xe2, 0x00, 0x02, 0x00, 0xe4, 0x00, 0x02, 0x00,
+    0xe6, 0x00, 0x02, 0x00, 0xe8, 0x00, 0x02, 0x00, 0xea, 0x00, 0x02, 0x00, 0xec, 0x00, 0x02, 0x00,
+    0xee, 0x00, 0x02, 0x00, 0xf0, 0x00, 0x02, 0x00, 0xf2, 0x00, 0x02, 0x00, 0xf4, 0x00, 0x02, 0x00,
+
+    0xf6, 0x00, 0x02, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xfa, 0x00, 0x02, 0x00, 0xfc, 0x00, 0x02, 0x00,
+    0xfe, 0x00, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x02, 0x01, 0x02, 0x00, 0x04, 0x01, 0x02, 0x00,
+    0x06, 0x01, 0x02, 0x00, 0x08, 0x01, 0x02, 0x00, 0x0a, 0x01, 0x02, 0x00, 0x0c, 0x01, 0x02, 0x00,
+    0x0e, 0x01, 0x02, 0x00, 0x10, 0x01, 0x02, 0x00, 0x12, 0x01, 0x02, 0x00, 0x14, 0x01, 0x02, 0x00,
+    0x16, 0x01, 0x02, 0x00, 0x18, 0x01, 0x02, 0x00, 0x1a, 0x01, 0x02, 0x00, 0x1c, 0x01, 0x02, 0x00,
+    0x1e, 0x01, 0x02, 0x00, 0x20, 0x01, 0x02, 0x00, 0x22, 0x01, 0x02, 0x00, 0x24, 0x01, 0x02, 0x00,
+    0x26, 0x01, 0x02, 0x00, 0x28, 0x01, 0x02, 0x00, 0x2a, 0x01, 0x02, 0x00, 0x2c, 0x01, 0x02, 0x00,
+    0x2e, 0x01, 0x02, 0x00, 0x30, 0x01, 0x02, 0x00, 0x32, 0x01, 0x02, 0x00, 0x34, 0x01, 0x02, 0x00,
+    0x36, 0x01, 0x02, 0x00, 0x38, 0x01, 0x02, 0x00, 0x3a, 0x01, 0x02, 0x00, 0x3c, 0x01, 0x02, 0x00,
+    0x3e, 0x01, 0x02, 0x00, 0x40, 0x01, 0x02, 0x00, 0x42, 0x01, 0x02, 0x00, 0x44, 0x01, 0x02, 0x00,
+    0x46, 0x01, 0x02, 0x00, 0x48, 0x01, 0x02, 0x00, 0x4a, 0x01, 0x02, 0x00, 0x4c, 0x01, 0x02, 0x00,
+    0x4e, 0x01, 0x02, 0x00, 0x50, 0x01, 0x02, 0x00, 0x52, 0x01, 0x02, 0x00, 0x54, 0x01, 0x02, 0x00,
+    0x56, 0x01, 0x02, 0x00, 0x58, 0x01, 0x02, 0x00, 0x5a, 0x01, 0x02, 0x00, 0x5c, 0x01, 0x02, 0x00,
+    0x5e, 0x01, 0x02, 0x00, 0x60, 0x01, 0x02, 0x00, 0x62, 0x01, 0x02, 0x00, 0x64, 0x01, 0x02, 0x00,
+    0x66, 0x01, 0x02, 0x00, 0x68, 0x01, 0x02, 0x00, 0x6a, 0x01, 0x02, 0x00, 0x6c, 0x01, 0x02, 0x00,
+    0x6e, 0x01, 0x02, 0x00, 0x70, 0x01, 0x02, 0x00, 0x72, 0x01, 0x02, 0x00, 0x74, 0x01, 0x02, 0x00,
+    0x76, 0x01, 0x02, 0x00, 0x78, 0x01, 0x02, 0x00, 0x7a, 0x01, 0x02, 0x00, 0x7c, 0x01, 0x02, 0x00,
+    0x7e, 0x01, 0x02, 0x00, 0x80, 0x01, 0x02, 0x00, 0x82, 0x01, 0x02, 0x00, 0x84, 0x01, 0x02, 0x00,
+    0x86, 0x01, 0x02, 0x00, 0x88, 0x01, 0x02, 0x00, 0x8a, 0x01, 0x02, 0x00, 0x8c, 0x01, 0x02, 0x00,
+    0x8e, 0x01, 0x02, 0x00, 0x90, 0x01, 0x02, 0x00, 0x92, 0x01, 0x02, 0x00, 0x94, 0x01, 0x02, 0x00,
+    0x96, 0x01, 0x02, 0x00, 0x98, 0x01, 0x02, 0x00, 0x9a, 0x01, 0x02, 0x00, 0x9c, 0x01, 0x02, 0x00,
+    0x9e, 0x01, 0x02, 0x00, 0xa0, 0x01, 0x02, 0x00, 0xa2, 0x01, 0x02, 0x00, 0xa4, 0x01, 0x02, 0x00,
+    0xa6, 0x01, 0x02, 0x00, 0xa8, 0x01, 0x02, 0x00, 0xaa, 0x01, 0x02, 0x00, 0xac, 0x01, 0x02, 0x00,
+    0xae, 0x01, 0x02, 0x00, 0xb0, 0x01, 0x02, 0x00, 0xb2, 0x01, 0x02, 0x00, 0xb4, 0x01, 0x02, 0x00,
+    0xb6, 0x01, 0x02, 0x00, 0xb8, 0x01, 0x02, 0x00, 0xba, 0x01, 0x02, 0x00, 0xbc, 0x01, 0x02, 0x00,
+    0xbe, 0x01, 0x02, 0x00, 0xc0, 0x01, 0x02, 0x00, 0xc2, 0x01, 0x02, 0x00, 0xc4, 0x01, 0x02, 0x00,
+    0xc6, 0x01, 0x02, 0x00, 0xc8, 0x01, 0x02, 0x00, 0xca, 0x01, 0x02, 0x00, 0xcc, 0x01, 0x02, 0x00,
+    0xce, 0x01, 0x02, 0x00, 0xd0, 0x01, 0x02, 0x00, 0xd2, 0x01, 0x02, 0x00, 0xd4, 0x01, 0x02, 0x00,
+    0xd6, 0x01, 0x02, 0x00, 0xd8, 0x01, 0x02, 0x00, 0xda, 0x01, 0x02, 0x00, 0xdc, 0x01, 0x02, 0x00,
+    0xde, 0x01, 0x02, 0x00, 0xe0, 0x01, 0x02, 0x00, 0xe2, 0x01, 0x02, 0x00, 0xe4, 0x01, 0x02, 0x00,
+    0xe6, 0x01, 0x02, 0x00, 0xe8, 0x01, 0x02, 0x00, 0xea, 0x01, 0x02, 0x00, 0xec, 0x01, 0x02, 0x00,
+    0xee, 0x01, 0x02, 0x00, 0xf0, 0x01, 0x02, 0x00, 0xf2, 0x01, 0x02, 0x00, 0xf4, 0x01, 0x02, 0x00,
+
+    0xf6, 0x01, 0x02, 0x00, 0xf8, 0x01, 0x02, 0x00, 0xfa, 0x01, 0x02, 0x00, 0xfc, 0x01, 0x02, 0x00,
+    0xfe, 0x01, 0x02, 0x00, 0x00, 0x02, 0x02, 0x00, 0x02, 0x02, 0x02, 0x00, 0x04, 0x02, 0x02, 0x00,
+    0x06, 0x02, 0x02, 0x00, 0x08, 0x02, 0x02, 0x00, 0x0a, 0x02, 0x02, 0x00, 0x0c, 0x02, 0x02, 0x00,
+    0x0e, 0x02, 0x02, 0x00, 0x10, 0x02, 0x02, 0x00, 0x12, 0x02, 0x02, 0x00, 0x14, 0x02, 0x02, 0x00,
+    0x16, 0x02, 0x02, 0x00, 0x18, 0x02, 0x02, 0x00, 0x1a, 0x02, 0x02, 0x00, 0x1c, 0x02, 0x02, 0x00,
+    0x1e, 0x02, 0x02, 0x00, 0x20, 0x02, 0x02, 0x00, 0x22, 0x02, 0x02, 0x00, 0x24, 0x02, 0x02, 0x00,
+    0x26, 0x02, 0x02, 0x00, 0x28, 0x02, 0x02, 0x00, 0x2a, 0x02, 0x02, 0x00, 0x2c, 0x02, 0x02, 0x00,
+    0x2e, 0x02, 0x02, 0x00, 0x30, 0x02, 0x02, 0x00, 0x32, 0x02, 0x02, 0x00, 0x34, 0x02, 0x02, 0x00,
+    0x36, 0x02, 0x02, 0x00, 0x38, 0x02, 0x02, 0x00, 0x3a, 0x02, 0x02, 0x00, 0x3c, 0x02, 0x02, 0x00,
+    0x3e, 0x02, 0x02, 0x00, 0x40, 0x02, 0x02, 0x00, 0x42, 0x02, 0x02, 0x00, 0x44, 0x02, 0x02, 0x00,
+    0x46, 0x02, 0x02, 0x00, 0x48, 0x02, 0x02, 0x00, 0x4a, 0x02, 0x02, 0x00, 0x4c, 0x02, 0x02, 0x00,
+    0x4e, 0x02, 0x02, 0x00, 0x50, 0x02, 0x02, 0x00, 0x52, 0x02, 0x02, 0x00, 0x54, 0x02, 0x02, 0x00,
+    0x56, 0x02, 0x02, 0x00, 0x58, 0x02, 0x02, 0x00, 0x5a, 0x02, 0x02, 0x00, 0x5c, 0x02, 0x02, 0x00,
+    0x5e, 0x02, 0x02, 0x00, 0x60, 0x02, 0x02, 0x00, 0x62, 0x02, 0x02, 0x00, 0x64, 0x02, 0x02, 0x00,
+    0x66, 0x02, 0x02, 0x00, 0x68, 0x02, 0x02, 0x00, 0x6a, 0x02, 0x02, 0x00, 0x6c, 0x02, 0x02, 0x00,
+    0x6e, 0x02, 0x02, 0x00, 0x70, 0x02, 0x02, 0x00, 0x72, 0x02, 0x02, 0x00, 0x74, 0x02, 0x02, 0x00,
+    0x76, 0x02, 0x02, 0x00, 0x78, 0x02, 0x02, 0x00, 0x7a, 0x02, 0x02, 0x00, 0x7c, 0x02, 0x02, 0x00,
+    0x7e, 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x00, 0x82, 0x02, 0x02, 0x00, 0x84, 0x02, 0x02, 0x00,
+    0x86, 0x02, 0x02, 0x00, 0x88, 0x02, 0x02, 0x00, 0x8a, 0x02, 0x02, 0x00, 0x8c, 0x02, 0x02, 0x00,
+    0x8e, 0x02, 0x02, 0x00, 0x90, 0x02, 0x02, 0x00, 0x92, 0x02, 0x02, 0x00, 0x94, 0x02, 0x02, 0x00,
+    0x96, 0x02, 0x02, 0x00, 0x98, 0x02, 0x02, 0x00, 0x9a, 0x02, 0x02, 0x00, 0x9c, 0x02, 0x02, 0x00,
+    0x9e, 0x02, 0x02, 0x00, 0xa0, 0x02, 0x02, 0x00, 0xa2, 0x02, 0x02, 0x00, 0xa4, 0x02, 0x02, 0x00,
+    0xa6, 0x02, 0x02, 0x00, 0xa8, 0x02, 0x02, 0x00, 0xaa, 0x02, 0x02, 0x00, 0xac, 0x02, 0x02, 0x00,
+    0xae, 0x02, 0x02, 0x00, 0xb0, 0x02, 0x02, 0x00, 0xb2, 0x02, 0x02, 0x00, 0xb4, 0x02, 0x02, 0x00,
+    0xb6, 0x02, 0x02, 0x00, 0xb8, 0x02, 0x02, 0x00, 0xba, 0x02, 0x02, 0x00, 0xbc, 0x02, 0x02, 0x00,
+    0xbe, 0x02, 0x02, 0x00, 0xc0, 0x02, 0x02, 0x00, 0xc2, 0x02, 0x02, 0x00, 0xc4, 0x02, 0x02, 0x00,
+    0xc6, 0x02, 0x02, 0x00, 0xc8, 0x02, 0x02, 0x00, 0xca, 0x02, 0x02, 0x00, 0xcc, 0x02, 0x02, 0x00,
+    0xce, 0x02, 0x02, 0x00, 0xd0, 0x02, 0x02, 0x00, 0xd2, 0x02, 0x02, 0x00, 0xd4, 0x02, 0x02, 0x00,
+    0xd6, 0x02, 0x02, 0x00, 0xd8, 0x02, 0x02, 0x00, 0xda, 0x02, 0x02, 0x00, 0xdc, 0x02, 0x02, 0x00,
+    0xde, 0x02, 0x02, 0x00, 0xe0, 0x02, 0x02, 0x00, 0xe2, 0x02, 0x02, 0x00, 0xe4, 0x02, 0x02, 0x00,
+    0xe6, 0x02, 0x02, 0x00, 0xe8, 0x02, 0x02, 0x00, 0xea, 0x02, 0x02, 0x00, 0xec, 0x02, 0x02, 0x00,
+    0xee, 0x02, 0x02, 0x00, 0xf0, 0x02, 0x02, 0x00, 0xf2, 0x02, 0x02, 0x00, 0xf4, 0x02, 0x02, 0x00,
+
+    0xf6, 0x02, 0x02, 0x00, 0xf8, 0x02, 0x02, 0x00, 0xfa, 0x02, 0x02, 0x00, 0xfc, 0x02, 0x02, 0x00,
+    0xfe, 0x02, 0x02, 0x00, 0x00, 0x03, 0x02, 0x00, 0x02, 0x03, 0x02, 0x00, 0x04, 0x03, 0x02, 0x00,
+    0x06, 0x03, 0x02, 0x00, 0x08, 0x03, 0x02, 0x00, 0x0a, 0x03, 0x02, 0x00, 0x0c, 0x03, 0x02, 0x00,
+    0x0e, 0x03, 0x02, 0x00, 0x10, 0x03, 0x02, 0x00, 0x12, 0x03, 0x02, 0x00, 0x14, 0x03, 0x02, 0x00,
+    0x16, 0x03, 0x02, 0x00, 0x18, 0x03, 0x02, 0x00, 0x1a, 0x03, 0x02, 0x00, 0x1c, 0x03, 0x02, 0x00,
+    0x1e, 0x03, 0x02, 0x00, 0x20, 0x03, 0x02, 0x00, 0x22, 0x03, 0x02, 0x00, 0x24, 0x03, 0x02, 0x00,
+    0x26, 0x03, 0x02, 0x00, 0x28, 0x03, 0x02, 0x00, 0x2a, 0x03, 0x02, 0x00, 0x2c, 0x03, 0x02, 0x00,
+    0x2e, 0x03, 0x02, 0x00, 0x30, 0x03, 0x02, 0x00, 0x32, 0x03, 0x02, 0x00, 0x34, 0x03, 0x02, 0x00,
+    0x36, 0x03, 0x02, 0x00, 0x38, 0x03, 0x02, 0x00, 0x3a, 0x03, 0x02, 0x00, 0x3c, 0x03, 0x02, 0x00,
+    0x3e, 0x03, 0x02, 0x00, 0x40, 0x03, 0x02, 0x00, 0x42, 0x03, 0x02, 0x00, 0x44, 0x03, 0x02, 0x00,
+    0x46, 0x03, 0x02, 0x00, 0x48, 0x03, 0x02, 0x00, 0x4a, 0x03, 0x02, 0x00, 0x4c, 0x03, 0x02, 0x00,
+    0x4e, 0x03, 0x02, 0x00, 0x50, 0x03, 0x02, 0x00, 0x52, 0x03, 0x02, 0x00, 0x54, 0x03, 0x02, 0x00,
+    0x56, 0x03, 0x02, 0x00, 0x58, 0x03, 0x02, 0x00, 0x5a, 0x03, 0x02, 0x00, 0x5c, 0x03, 0x02, 0x00,
+    0x5e, 0x03, 0x02, 0x00, 0x60, 0x03, 0x02, 0x00, 0x62, 0x03, 0x02, 0x00, 0x64, 0x03, 0x02, 0x00,
+    0x66, 0x03, 0x02, 0x00, 0x68, 0x03, 0x02, 0x00, 0x6a, 0x03, 0x02, 0x00, 0x6c, 0x03, 0x02, 0x00,
+    0x6e, 0x03, 0x02, 0x00, 0x70, 0x03, 0x02, 0x00, 0x72, 0x03, 0x02, 0x00, 0x74, 0x03, 0x02, 0x00,
+    0x76, 0x03, 0x02, 0x00, 0x78, 0x03, 0x02, 0x00, 0x7a, 0x03, 0x02, 0x00, 0x7c, 0x03, 0x02, 0x00,
+    0x7e, 0x03, 0x02, 0x00, 0x80, 0x03, 0x02, 0x00, 0x82, 0x03, 0x02, 0x00, 0x84, 0x03, 0x02, 0x00,
+    0x86, 0x03, 0x02, 0x00, 0x88, 0x03, 0x02, 0x00, 0x8a, 0x03, 0x02, 0x00, 0x8c, 0x03, 0x02, 0x00,
+    0x8e, 0x03, 0x02, 0x00, 0x90, 0x03, 0x02, 0x00, 0x92, 0x03, 0x02, 0x00, 0x94, 0x03, 0x02, 0x00,
+    0x96, 0x03, 0x02, 0x00, 0x98, 0x03, 0x02, 0x00, 0x9a, 0x03, 0x02, 0x00, 0x9c, 0x03, 0x02, 0x00,
+    0x9e, 0x03, 0x02, 0x00, 0xa0, 0x03, 0x02, 0x00, 0xa2, 0x03, 0x02, 0x00, 0xa4, 0x03, 0x02, 0x00,
+    0xa6, 0x03, 0x02, 0x00, 0xa8, 0x03, 0x02, 0x00, 0xaa, 0x03, 0x02, 0x00, 0xac, 0x03, 0x02, 0x00,
+    0xae, 0x03, 0x02, 0x00, 0xb0, 0x03, 0x02, 0x00, 0xb2, 0x03, 0x02, 0x00, 0xb4, 0x03, 0x02, 0x00,
+    0xb6, 0x03, 0x02, 0x00, 0xb8, 0x03, 0x02, 0x00, 0xba, 0x03, 0x02, 0x00, 0xbc, 0x03, 0x02, 0x00,
+    0xbe, 0x03, 0x02, 0x00, 0xc0, 0x03, 0x02, 0x00, 0xc2, 0x03, 0x02, 0x00, 0xc4, 0x03, 0x02, 0x00,
+    0xc6, 0x03, 0x02, 0x00, 0xc8, 0x03, 0x02, 0x00, 0xca, 0x03, 0x02, 0x00, 0xcc, 0x03, 0x02, 0x00,
+    0xce, 0x03, 0x02, 0x00, 0xd0, 0x03, 0x02, 0x00, 0xd2, 0x03, 0x02, 0x00, 0xd4, 0x03, 0x02, 0x00,
+    0xd6, 0x03, 0x02, 0x00, 0xd8, 0x03, 0x02, 0x00, 0xda, 0x03, 0x02, 0x00, 0xdc, 0x03, 0x02, 0x00,
+    0xde, 0x03, 0x02, 0x00, 0xe0, 0x03, 0x02, 0x00, 0xe2, 0x03, 0x02, 0x00, 0xe4, 0x03, 0x02, 0x00,
+    0xe6, 0x03, 0x02, 0x00, 0xe8, 0x03, 0x02, 0x00, 0xea, 0x03, 0x02, 0x00, 0xec, 0x03, 0x02, 0x00,
+    0xee, 0x03, 0x02, 0x00, 0xf0, 0x03, 0x02, 0x00, 0xf2, 0x03, 0x02, 0x00, 0xf4, 0x03, 0x02, 0x00,
+
+    0xf6, 0x03, 0x02, 0x00, 0xf8, 0x03, 0x02, 0x00, 0xfa, 0x03, 0x02, 0x00, 0xfc, 0x03, 0x02, 0x00,
+    0xfe, 0x03, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00,
+    0x06, 0x00, 0x02, 0x00, 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x02, 0x00, 0x0c, 0x00, 0x02, 0x00,
+    0x0e, 0x00, 0x02, 0x00, 0x10, 0x00, 0x02, 0x00, 0x12, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00,
+    0x16, 0x00, 0x02, 0x00, 0x18, 0x00, 0x02, 0x00, 0x1a, 0x00, 0x02, 0x00, 0x1c, 0x00, 0x02, 0x00,
+    0x1e, 0x00, 0x02, 0x00, 0x20, 0x00, 0x02, 0x00, 0x22, 0x00, 0x02, 0x00, 0x24, 0x00, 0x02, 0x00,
+    0x26, 0x00, 0x02, 0x00, 0x28, 0x00, 0x02, 0x00, 0x2a, 0x00, 0x02, 0x00, 0x2c, 0x00, 0x02, 0x00,
+    0x2e, 0x00, 0x02, 0x00, 0x30, 0x00, 0x02, 0x00, 0x32, 0x00, 0x02, 0x00, 0x34, 0x00, 0x02, 0x00,
+    0x36, 0x00, 0x02, 0x00, 0x38, 0x00, 0x02, 0x00, 0x3a, 0x00, 0x02, 0x00, 0x3c, 0x00, 0x02, 0x00,
+    0x3e, 0x00, 0x02, 0x00, 0x40, 0x00, 0x02, 0x00, 0x42, 0x00, 0x02, 0x00, 0x44, 0x00, 0x02, 0x00,
+    0x46, 0x00, 0x02, 0x00, 0x48, 0x00, 0x02, 0x00, 0x4a, 0x00, 0x02, 0x00, 0x4c, 0x00, 0x02, 0x00,
+    0x4e, 0x00, 0x02, 0x00, 0x50, 0x00, 0x02, 0x00, 0x52, 0x00, 0x02, 0x00, 0x54, 0x00, 0x02, 0x00,
+    0x56, 0x00, 0x02, 0x00, 0x58, 0x00, 0x02, 0x00, 0x5a, 0x00, 0x02, 0x00, 0x5c, 0x00, 0x02, 0x00,
+    0x5e, 0x00, 0x02, 0x00, 0x60, 0x00, 0x02, 0x00, 0x62, 0x00, 0x02, 0x00, 0x64, 0x00, 0x02, 0x00,
+    0x66, 0x00, 0x02, 0x00, 0x68, 0x00, 0x02, 0x00, 0x6a, 0x00, 0x02, 0x00, 0x6c, 0x00, 0x02, 0x00,
+    0x6e, 0x00, 0x02, 0x00, 0x70, 0x00, 0x02, 0x00, 0x72, 0x00, 0x02, 0x00, 0x74, 0x00, 0x02, 0x00,
+    0x76, 0x00, 0x02, 0x00, 0x78, 0x00, 0x02, 0x00, 0x7a, 0x00, 0x02, 0x00, 0x7c, 0x00, 0x02, 0x00,
+    0x7e, 0x00, 0x02, 0x00, 0x80, 0x00, 0x02, 0x00, 0x82, 0x00, 0x02, 0x00, 0x84, 0x00, 0x02, 0x00,
+    0x86, 0x00, 0x02, 0x00, 0x88, 0x00, 0x02, 0x00, 0x8a, 0x00, 0x02, 0x00, 0x8c, 0x00, 0x02, 0x00,
+    0x8e, 0x00, 0x02, 0x00, 0x90, 0x00, 0x02, 0x00, 0x92, 0x00, 0x02, 0x00, 0x94, 0x00, 0x02, 0x00,
+    0x96, 0x00, 0x02, 0x00, 0x98, 0x00, 0x02, 0x00, 0x9a, 0x00, 0x02, 0x00, 0x9c, 0x00, 0x02, 0x00,
+    0x9e, 0x00, 0x02, 0x00, 0xa0, 0x00, 0x02, 0x00, 0xa2, 0x00, 0x02, 0x00, 0xa4, 0x00, 0x02, 0x00,
+    0xa6, 0x00, 0x02, 0x00, 0xa8, 0x00, 0x02, 0x00, 0xaa, 0x00, 0x02, 0x00, 0xac, 0x00, 0x02, 0x00,
+    0xae, 0x00, 0x02, 0x00, 0xb0, 0x00, 0x02, 0x00, 0xb2, 0x00, 0x02, 0x00, 0xb4, 0x00, 0x02, 0x00,
+    0xb6, 0x00, 0x02, 0x00, 0xb8, 0x00, 0x02, 0x00, 0xba, 0x00, 0x02, 0x00, 0xbc, 0x00, 0x02, 0x00,
+    0xbe, 0x00, 0x02, 0x00, 0xc0, 0x00, 0x02, 0x00, 0xc2, 0x00, 0x02, 0x00, 0xc4, 0x00, 0x02, 0x00,
+    0xc6, 0x00, 0x02, 0x00, 0xc8, 0x00, 0x02, 0x00, 0xca, 0x00, 0x02, 0x00, 0xcc, 0x00, 0x02, 0x00,
+    0xce, 0x00, 0x02, 0x00, 0xd0, 0x00, 0x02, 0x00, 0xd2, 0x00, 0x02, 0x00, 0xd4, 0x00, 0x02, 0x00,
+    0xd6, 0x00, 0x02, 0x00, 0xd8, 0x00, 0x02, 0x00, 0xda, 0x00, 0x02, 0x00, 0xdc, 0x00, 0x02, 0x00,
+    0xde, 0x00, 0x02, 0x00, 0xe0, 0x00, 0x02, 0x00, 0xe2, 0x00, 0x02, 0x00, 0xe4, 0x00, 0x02, 0x00,
+    0xe6, 0x00, 0x02, 0x00, 0xe8, 0x00, 0x02, 0x00, 0xea, 0x00, 0x02, 0x00, 0xec, 0x00, 0x02, 0x00,
+    0xee, 0x00, 0x02, 0x00, 0xf0, 0x00, 0x02, 0x00, 0xf2, 0x00, 0x02, 0x00, 0xf4, 0x00, 0x02, 0x00,
+
+    0xf6, 0x00, 0x02, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xfa, 0x00, 0x02, 0x00, 0xfc, 0x00, 0x02, 0x00,
+    0xfe, 0x00, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x02, 0x01, 0x02, 0x00, 0x04, 0x01, 0x02, 0x00,
+    0x06, 0x01, 0x02, 0x00, 0x08, 0x01, 0x02, 0x00, 0x0a, 0x01, 0x02, 0x00, 0x0c, 0x01, 0x02, 0x00,
+    0x0e, 0x01, 0x02, 0x00, 0x10, 0x01, 0x02, 0x00, 0x12, 0x01, 0x02, 0x00, 0x14, 0x01, 0x02, 0x00,
+    0x16, 0x01, 0x02, 0x00, 0x18, 0x01, 0x02, 0x00, 0x1a, 0x01, 0x02, 0x00, 0x1c, 0x01, 0x02, 0x00,
+    0x1e, 0x01, 0x02, 0x00, 0x20, 0x01, 0x02, 0x00, 0x22, 0x01, 0x02, 0x00, 0x24, 0x01, 0x02, 0x00,
+    0x26, 0x01, 0x02, 0x00, 0x28, 0x01, 0x02, 0x00, 0x2a, 0x01, 0x02, 0x00, 0x2c, 0x01, 0x02, 0x00,
+    0x2e, 0x01, 0x02, 0x00, 0x30, 0x01, 0x02, 0x00, 0x32, 0x01, 0x02, 0x00, 0x34, 0x01, 0x02, 0x00,
+    0x36, 0x01, 0x02, 0x00, 0x38, 0x01, 0x02, 0x00, 0x3a, 0x01, 0x02, 0x00, 0x3c, 0x01, 0x02, 0x00,
+    0x3e, 0x01, 0x02, 0x00, 0x40, 0x01, 0x02, 0x00, 0x42, 0x01, 0x02, 0x00, 0x44, 0x01, 0x02, 0x00,
+    0x46, 0x01, 0x02, 0x00, 0x48, 0x01, 0x02, 0x00, 0x4a, 0x01, 0x02, 0x00, 0x4c, 0x01, 0x02, 0x00,
+    0x4e, 0x01, 0x02, 0x00, 0x50, 0x01, 0x02, 0x00, 0x52, 0x01, 0x02, 0x00, 0x54, 0x01, 0x02, 0x00,
+    0x56, 0x01, 0x02, 0x00, 0x58, 0x01, 0x02, 0x00, 0x5a, 0x01, 0x02, 0x00, 0x5c, 0x01, 0x02, 0x00,
+    0x5e, 0x01, 0x02, 0x00, 0x60, 0x01, 0x02, 0x00, 0x62, 0x01, 0x02, 0x00, 0x64, 0x01, 0x02, 0x00,
+    0x66, 0x01, 0x02, 0x00, 0x68, 0x01, 0x02, 0x00, 0x6a, 0x01, 0x02, 0x00, 0x6c, 0x01, 0x02, 0x00,
+    0x6e, 0x01, 0x02, 0x00, 0x70, 0x01, 0x02, 0x00, 0x72, 0x01, 0x02, 0x00, 0x74, 0x01, 0x02, 0x00,
+    0x76, 0x01, 0x02, 0x00, 0x78, 0x01, 0x02, 0x00, 0x7a, 0x01, 0x02, 0x00, 0x7c, 0x01, 0x02, 0x00,
+    0x7e, 0x01, 0x02, 0x00, 0x80, 0x01, 0x02, 0x00, 0x82, 0x01, 0x02, 0x00, 0x84, 0x01, 0x02, 0x00,
+    0x86, 0x01, 0x02, 0x00, 0x88, 0x01, 0x02, 0x00, 0x8a, 0x01, 0x02, 0x00, 0x8c, 0x01, 0x02, 0x00,
+    0x8e, 0x01, 0x02, 0x00, 0x90, 0x01, 0x02, 0x00, 0x92, 0x01, 0x02, 0x00, 0x94, 0x01, 0x02, 0x00,
+    0x96, 0x01, 0x02, 0x00, 0x98, 0x01, 0x02, 0x00, 0x9a, 0x01, 0x02, 0x00, 0x9c, 0x01, 0x02, 0x00,
+    0x9e, 0x01, 0x02, 0x00, 0xa0, 0x01, 0x02, 0x00, 0xa2, 0x01, 0x02, 0x00, 0xa4, 0x01, 0x02, 0x00,
+    0xa6, 0x01, 0x02, 0x00, 0xa8, 0x01, 0x02, 0x00, 0xaa, 0x01, 0x02, 0x00, 0xac, 0x01, 0x02, 0x00,
+    0xae, 0x01, 0x02, 0x00, 0xb0, 0x01, 0x02, 0x00, 0xb2, 0x01, 0x02, 0x00, 0xb4, 0x01, 0x02, 0x00,
+    0xb6, 0x01, 0x02, 0x00, 0xb8, 0x01, 0x02, 0x00, 0xba, 0x01, 0x02, 0x00, 0xbc, 0x01, 0x02, 0x00,
+    0xbe, 0x01, 0x02, 0x00, 0xc0, 0x01, 0x02, 0x00, 0xc2, 0x01, 0x02, 0x00, 0xc4, 0x01, 0x02, 0x00,
+    0xc6, 0x01, 0x02, 0x00, 0xc8, 0x01, 0x02, 0x00, 0xca, 0x01, 0x02, 0x00, 0xcc, 0x01, 0x02, 0x00,
+    0xce, 0x01, 0x02, 0x00, 0xd0, 0x01, 0x02, 0x00, 0xd2, 0x01, 0x02, 0x00, 0xd4, 0x01, 0x02, 0x00,
+    0xd6, 0x01, 0x02, 0x00, 0xd8, 0x01, 0x02, 0x00, 0xda, 0x01, 0x02, 0x00, 0xdc, 0x01, 0x02, 0x00,
+    0xde, 0x01, 0x02, 0x00, 0xe0, 0x01, 0x02, 0x00, 0xe2, 0x01, 0x02, 0x00, 0xe4, 0x01, 0x02, 0x00,
+    0xe6, 0x01, 0x02, 0x00, 0xe8, 0x01, 0x02, 0x00, 0xea, 0x01, 0x02, 0x00, 0xec, 0x01, 0x02, 0x00,
+    0xee, 0x01, 0x02, 0x00, 0xf0, 0x01, 0x02, 0x00, 0xf2, 0x01, 0x02, 0x00, 0xf4, 0x01, 0x02, 0x00,
+
+    0xf6, 0x01, 0x02, 0x00, 0xf8, 0x01, 0x02, 0x00, 0xfa, 0x01, 0x02, 0x00, 0xfc, 0x01, 0x02, 0x00,
+    0xfe, 0x01, 0x02, 0x00, 0x00, 0x02, 0x02, 0x00, 0x02, 0x02, 0x02, 0x00, 0x04, 0x02, 0x02, 0x00,
+    0x06, 0x02, 0x02, 0x00, 0x08, 0x02, 0x02, 0x00, 0x0a, 0x02, 0x02, 0x00, 0x0c, 0x02, 0x02, 0x00,
+    0x0e, 0x02, 0x02, 0x00, 0x10, 0x02, 0x02, 0x00, 0x12, 0x02, 0x02, 0x00, 0x14, 0x02, 0x02, 0x00,
+    0x16, 0x02, 0x02, 0x00, 0x18, 0x02, 0x02, 0x00, 0x1a, 0x02, 0x02, 0x00, 0x1c, 0x02, 0x02, 0x00,
+    0x1e, 0x02, 0x02, 0x00, 0x20, 0x02, 0x02, 0x00, 0x22, 0x02, 0x02, 0x00, 0x24, 0x02, 0x02, 0x00,
+    0x26, 0x02, 0x02, 0x00, 0x28, 0x02, 0x02, 0x00, 0x2a, 0x02, 0x02, 0x00, 0x2c, 0x02, 0x02, 0x00,
+    0x2e, 0x02, 0x02, 0x00, 0x30, 0x02, 0x02, 0x00, 0x32, 0x02, 0x02, 0x00, 0x34, 0x02, 0x02, 0x00,
+    0x36, 0x02, 0x02, 0x00, 0x38, 0x02, 0x02, 0x00, 0x3a, 0x02, 0x02, 0x00, 0x3c, 0x02, 0x02, 0x00,
+    0x3e, 0x02, 0x02, 0x00, 0x40, 0x02, 0x02, 0x00, 0x42, 0x02, 0x02, 0x00, 0x44, 0x02, 0x02, 0x00,
+    0x46, 0x02, 0x02, 0x00, 0x48, 0x02, 0x02, 0x00, 0x4a, 0x02, 0x02, 0x00, 0x4c, 0x02, 0x02, 0x00,
+    0x4e, 0x02, 0x02, 0x00, 0x50, 0x02, 0x02, 0x00, 0x52, 0x02, 0x02, 0x00, 0x54, 0x02, 0x02, 0x00,
+    0x56, 0x02, 0x02, 0x00, 0x58, 0x02, 0x02, 0x00, 0x5a, 0x02, 0x02, 0x00, 0x5c, 0x02, 0x02, 0x00,
+    0x5e, 0x02, 0x02, 0x00, 0x60, 0x02, 0x02, 0x00, 0x62, 0x02, 0x02, 0x00, 0x64, 0x02, 0x02, 0x00,
+    0x66, 0x02, 0x02, 0x00, 0x68, 0x02, 0x02, 0x00, 0x6a, 0x02, 0x02, 0x00, 0x6c, 0x02, 0x02, 0x00,
+    0x6e, 0x02, 0x02, 0x00, 0x70, 0x02, 0x02, 0x00, 0x72, 0x02, 0x02, 0x00, 0x74, 0x02, 0x02, 0x00,
+    0x76, 0x02, 0x02, 0x00, 0x78, 0x02, 0x02, 0x00, 0x7a, 0x02, 0x02, 0x00, 0x7c, 0x02, 0x02, 0x00,
+    0x7e, 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x00, 0x82, 0x02, 0x02, 0x00, 0x84, 0x02, 0x02, 0x00,
+    0x86, 0x02, 0x02, 0x00, 0x88, 0x02, 0x02, 0x00, 0x8a, 0x02, 0x02, 0x00, 0x8c, 0x02, 0x02, 0x00,
+    0x8e, 0x02, 0x02, 0x00, 0x90, 0x02, 0x02, 0x00, 0x92, 0x02, 0x02, 0x00, 0x94, 0x02, 0x02, 0x00,
+    0x96, 0x02, 0x02, 0x00, 0x98, 0x02, 0x02, 0x00, 0x9a, 0x02, 0x02, 0x00, 0x9c, 0x02, 0x02, 0x00,
+    0x9e, 0x02, 0x02, 0x00, 0xa0, 0x02, 0x02, 0x00, 0xa2, 0x02, 0x02, 0x00, 0xa4, 0x02, 0x02, 0x00,
+    0xa6, 0x02, 0x02, 0x00, 0xa8, 0x02, 0x02, 0x00, 0xaa, 0x02, 0x02, 0x00, 0xac, 0x02, 0x02, 0x00,
+    0xae, 0x02, 0x02, 0x00, 0xb0, 0x02, 0x02, 0x00, 0xb2, 0x02, 0x02, 0x00, 0xb4, 0x02, 0x02, 0x00,
+    0xb6, 0x02, 0x02, 0x00, 0xb8, 0x02, 0x02, 0x00, 0xba, 0x02, 0x02, 0x00, 0xbc, 0x02, 0x02, 0x00,
+    0xbe, 0x02, 0x02, 0x00, 0xc0, 0x02, 0x02, 0x00, 0xc2, 0x02, 0x02, 0x00, 0xc4, 0x02, 0x02, 0x00,
+    0xc6, 0x02, 0x02, 0x00, 0xc8, 0x02, 0x02, 0x00, 0xca, 0x02, 0x02, 0x00, 0xcc, 0x02, 0x02, 0x00,
+    0xce, 0x02, 0x02, 0x00, 0xd0, 0x02, 0x02, 0x00, 0xd2, 0x02, 0x02, 0x00, 0xd4, 0x02, 0x02, 0x00,
+    0xd6, 0x02, 0x02, 0x00, 0xd8, 0x02, 0x02, 0x00, 0xda, 0x02, 0x02, 0x00, 0xdc, 0x02, 0x02, 0x00,
+    0xde, 0x02, 0x02, 0x00, 0xe0, 0x02, 0x02, 0x00, 0xe2, 0x02, 0x02, 0x00, 0xe4, 0x02, 0x02, 0x00,
+    0xe6, 0x02, 0x02, 0x00, 0xe8, 0x02, 0x02, 0x00, 0xea, 0x02, 0x02, 0x00, 0xec, 0x02, 0x02, 0x00,
+    0xee, 0x02, 0x02, 0x00, 0xf0, 0x02, 0x02, 0x00, 0xf2, 0x02, 0x02, 0x00, 0xf4, 0x02, 0x02, 0x00,
+
+    0xf6, 0x02, 0x02, 0x00, 0xf8, 0x02, 0x02, 0x00, 0xfa, 0x02, 0x02, 0x00, 0xfc, 0x02, 0x02, 0x00,
+    0xfe, 0x02, 0x02, 0x00, 0x00, 0x03, 0x02, 0x00, 0x02, 0x03, 0x02, 0x00, 0x04, 0x03, 0x02, 0x00,
+    0x06, 0x03, 0x02, 0x00, 0x08, 0x03, 0x02, 0x00, 0x0a, 0x03, 0x02, 0x00, 0x0c, 0x03, 0x02, 0x00,
+    0x0e, 0x03, 0x02, 0x00, 0x10, 0x03, 0x02, 0x00, 0x12, 0x03, 0x02, 0x00, 0x14, 0x03, 0x02, 0x00,
+    0x16, 0x03, 0x02, 0x00, 0x18, 0x03, 0x02, 0x00, 0x1a, 0x03, 0x02, 0x00, 0x1c, 0x03, 0x02, 0x00,
+    0x1e, 0x03, 0x02, 0x00, 0x20, 0x03, 0x02, 0x00, 0x22, 0x03, 0x02, 0x00, 0x24, 0x03, 0x02, 0x00,
+    0x26, 0x03, 0x02, 0x00, 0x28, 0x03, 0x02, 0x00, 0x2a, 0x03, 0x02, 0x00, 0x2c, 0x03, 0x02, 0x00,
+    0x2e, 0x03, 0x02, 0x00, 0x30, 0x03, 0x02, 0x00, 0x32, 0x03, 0x02, 0x00, 0x34, 0x03, 0x02, 0x00,
+    0x36, 0x03, 0x02, 0x00, 0x38, 0x03, 0x02, 0x00, 0x3a, 0x03, 0x02, 0x00, 0x3c, 0x03, 0x02, 0x00,
+    0x3e, 0x03, 0x02, 0x00, 0x40, 0x03, 0x02, 0x00, 0x42, 0x03, 0x02, 0x00, 0x44, 0x03, 0x02, 0x00,
+    0x46, 0x03, 0x02, 0x00, 0x48, 0x03, 0x02, 0x00, 0x4a, 0x03, 0x02, 0x00, 0x4c, 0x03, 0x02, 0x00,
+    0x4e, 0x03, 0x02, 0x00, 0x50, 0x03, 0x02, 0x00, 0x52, 0x03, 0x02, 0x00, 0x54, 0x03, 0x02, 0x00,
+    0x56, 0x03, 0x02, 0x00, 0x58, 0x03, 0x02, 0x00, 0x5a, 0x03, 0x02, 0x00, 0x5c, 0x03, 0x02, 0x00,
+    0x5e, 0x03, 0x02, 0x00, 0x60, 0x03, 0x02, 0x00, 0x62, 0x03, 0x02, 0x00, 0x64, 0x03, 0x02, 0x00,
+    0x66, 0x03, 0x02, 0x00, 0x68, 0x03, 0x02, 0x00, 0x6a, 0x03, 0x02, 0x00, 0x6c, 0x03, 0x02, 0x00,
+    0x6e, 0x03, 0x02, 0x00, 0x70, 0x03, 0x02, 0x00, 0x72, 0x03, 0x02, 0x00, 0x74, 0x03, 0x02, 0x00,
+    0x76, 0x03, 0x02, 0x00, 0x78, 0x03, 0x02, 0x00, 0x7a, 0x03, 0x02, 0x00, 0x7c, 0x03, 0x02, 0x00,
+    0x7e, 0x03, 0x02, 0x00, 0x80, 0x03, 0x02, 0x00, 0x82, 0x03, 0x02, 0x00, 0x84, 0x03, 0x02, 0x00,
+    0x86, 0x03, 0x02, 0x00, 0x88, 0x03, 0x02, 0x00, 0x8a, 0x03, 0x02, 0x00, 0x8c, 0x03, 0x02, 0x00,
+    0x8e, 0x03, 0x02, 0x00, 0x90, 0x03, 0x02, 0x00, 0x92, 0x03, 0x02, 0x00, 0x94, 0x03, 0x02, 0x00,
+    0x96, 0x03, 0x02, 0x00, 0x98, 0x03, 0x02, 0x00, 0x9a, 0x03, 0x02, 0x00, 0x9c, 0x03, 0x02, 0x00,
+    0x9e, 0x03, 0x02, 0x00, 0xa0, 0x03, 0x02, 0x00, 0xa2, 0x03, 0x02, 0x00, 0xa4, 0x03, 0x02, 0x00,
+    0xa6, 0x03, 0x02, 0x00, 0xa8, 0x03, 0x02, 0x00, 0xaa, 0x03, 0x02, 0x00, 0xac, 0x03, 0x02, 0x00,
+    0xae, 0x03, 0x02, 0x00, 0xb0, 0x03, 0x02, 0x00, 0xb2, 0x03, 0x02, 0x00, 0xb4, 0x03, 0x02, 0x00,
+    0xb6, 0x03, 0x02, 0x00, 0xb8, 0x03, 0x02, 0x00, 0xba, 0x03, 0x02, 0x00, 0xbc, 0x03, 0x02, 0x00,
+    0xbe, 0x03, 0x02, 0x00, 0xc0, 0x03, 0x02, 0x00, 0xc2, 0x03, 0x02, 0x00, 0xc4, 0x03, 0x02, 0x00,
+    0xc6, 0x03, 0x02, 0x00, 0xc8, 0x03, 0x02, 0x00, 0xca, 0x03, 0x02, 0x00, 0xcc, 0x03, 0x02, 0x00,
+    0xce, 0x03, 0x02, 0x00, 0xd0, 0x03, 0x02, 0x00, 0xd2, 0x03, 0x02, 0x00, 0xd4, 0x03, 0x02, 0x00,
+    0xd6, 0x03, 0x02, 0x00, 0xd8, 0x03, 0x02, 0x00, 0xda, 0x03, 0x02, 0x00, 0xdc, 0x03, 0x02, 0x00,
+    0xde, 0x03, 0x02, 0x00, 0xe0, 0x03, 0x02, 0x00, 0xe2, 0x03, 0x02, 0x00, 0xe4, 0x03, 0x02, 0x00,
+    0xe6, 0x03, 0x02, 0x00, 0xe8, 0x03, 0x02, 0x00, 0xea, 0x03, 0x02, 0x00, 0xec, 0x03, 0x02, 0x00,
+    0xee, 0x03, 0x02, 0x00, 0xf0, 0x03, 0x02, 0x00, 0xf2, 0x03, 0x02, 0x00, 0xf4, 0x03, 0x02, 0x00,
+
+    0xf6, 0x03, 0x02, 0x00, 0xf8, 0x03, 0x02, 0x00, 0xfa, 0x03, 0x02, 0x00, 0xfc, 0x03, 0x02, 0x00,
+    0xfe, 0x03, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00,
+    0x06, 0x00, 0x02, 0x00, 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x02, 0x00, 0x0c, 0x00, 0x02, 0x00,
+    0x0e, 0x00, 0x02, 0x00, 0x10, 0x00, 0x02, 0x00, 0x12, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00,
+    0x16, 0x00, 0x02, 0x00, 0x18, 0x00, 0x02, 0x00, 0x1a, 0x00, 0x02, 0x00, 0x1c, 0x00, 0x02, 0x00,
+    0x1e, 0x00, 0x02, 0x00, 0x20, 0x00, 0x02, 0x00, 0x22, 0x00, 0x02, 0x00, 0x24, 0x00, 0x02, 0x00,
+    0x26, 0x00, 0x02, 0x00, 0x28, 0x00, 0x02, 0x00, 0x2a, 0x00, 0x02, 0x00, 0x2c, 0x00, 0x02, 0x00,
+    0x2e, 0x00, 0x02, 0x00, 0x30, 0x00, 0x02, 0x00, 0x32, 0x00, 0x02, 0x00, 0x34, 0x00, 0x02, 0x00,
+    0x36, 0x00, 0x02, 0x00, 0x38, 0x00, 0x02, 0x00, 0x3a, 0x00, 0x02, 0x00, 0x3c, 0x00, 0x02, 0x00,
+    0x3e, 0x00, 0x02, 0x00, 0x40, 0x00, 0x02, 0x00, 0x42, 0x00, 0x02, 0x00, 0x44, 0x00, 0x02, 0x00,
+    0x46, 0x00, 0x02, 0x00, 0x48, 0x00, 0x02, 0x00, 0x4a, 0x00, 0x02, 0x00, 0x4c, 0x00, 0x02, 0x00,
+    0x4e, 0x00, 0x02, 0x00, 0x50, 0x00, 0x02, 0x00, 0x52, 0x00, 0x02, 0x00, 0x54, 0x00, 0x02, 0x00,
+    0x56, 0x00, 0x02, 0x00, 0x58, 0x00, 0x02, 0x00, 0x5a, 0x00, 0x02, 0x00, 0x5c, 0x00, 0x02, 0x00,
+    0x5e, 0x00, 0x02, 0x00, 0x60, 0x00, 0x02, 0x00, 0x62, 0x00, 0x02, 0x00, 0x64, 0x00, 0x02, 0x00,
+    0x66, 0x00, 0x02, 0x00, 0x68, 0x00, 0x02, 0x00, 0x6a, 0x00, 0x02, 0x00, 0x6c, 0x00, 0x02, 0x00,
+    0x6e, 0x00, 0x02, 0x00, 0x70, 0x00, 0x02, 0x00, 0x72, 0x00, 0x02, 0x00, 0x74, 0x00, 0x02, 0x00,
+    0x76, 0x00, 0x02, 0x00, 0x78, 0x00, 0x02, 0x00, 0x7a, 0x00, 0x02, 0x00, 0x7c, 0x00, 0x02, 0x00,
+    0x7e, 0x00, 0x02, 0x00, 0x80, 0x00, 0x02, 0x00, 0x82, 0x00, 0x02, 0x00, 0x84, 0x00, 0x02, 0x00,
+    0x86, 0x00, 0x02, 0x00, 0x88, 0x00, 0x02, 0x00, 0x8a, 0x00, 0x02, 0x00, 0x8c, 0x00, 0x02, 0x00,
+    0x8e, 0x00, 0x02, 0x00, 0x90, 0x00, 0x02, 0x00, 0x92, 0x00, 0x02, 0x00, 0x94, 0x00, 0x02, 0x00,
+    0x96, 0x00, 0x02, 0x00, 0x98, 0x00, 0x02, 0x00, 0x9a, 0x00, 0x02, 0x00, 0x9c, 0x00, 0x02, 0x00,
+    0x9e, 0x00, 0x02, 0x00, 0xa0, 0x00, 0x02, 0x00, 0xa2, 0x00, 0x02, 0x00, 0xa4, 0x00, 0x02, 0x00,
+    0xa6, 0x00, 0x02, 0x00, 0xa8, 0x00, 0x02, 0x00, 0xaa, 0x00, 0x02, 0x00, 0xac, 0x00, 0x02, 0x00,
+    0xae, 0x00, 0x02, 0x00, 0xb0, 0x00, 0x02, 0x00, 0xb2, 0x00, 0x02, 0x00, 0xb4, 0x00, 0x02, 0x00,
+    0xb6, 0x00, 0x02, 0x00, 0xb8, 0x00, 0x02, 0x00, 0xba, 0x00, 0x02, 0x00, 0xbc, 0x00, 0x02, 0x00,
+    0xbe, 0x00, 0x02, 0x00, 0xc0, 0x00, 0x02, 0x00, 0xc2, 0x00, 0x02, 0x00, 0xc4, 0x00, 0x02, 0x00,
+    0xc6, 0x00, 0x02, 0x00, 0xc8, 0x00, 0x02, 0x00, 0xca, 0x00, 0x02, 0x00, 0xcc, 0x00, 0x02, 0x00,
+    0xce, 0x00, 0x02, 0x00, 0xd0, 0x00, 0x02, 0x00, 0xd2, 0x00, 0x02, 0x00, 0xd4, 0x00, 0x02, 0x00,
+    0xd6, 0x00, 0x02, 0x00, 0xd8, 0x00, 0x02, 0x00, 0xda, 0x00, 0x02, 0x00, 0xdc, 0x00, 0x02, 0x00,
+    0xde, 0x00, 0x02, 0x00, 0xe0, 0x00, 0x02, 0x00, 0xe2, 0x00, 0x02, 0x00, 0xe4, 0x00, 0x02, 0x00,
+    0xe6, 0x00, 0x02, 0x00, 0xe8, 0x00, 0x02, 0x00, 0xea, 0x00, 0x02, 0x00, 0xec, 0x00, 0x02, 0x00,
+    0xee, 0x00, 0x02, 0x00, 0xf0, 0x00, 0x02, 0x00, 0xf2, 0x00, 0x02, 0x00, 0xf4, 0x00, 0x02, 0x00,
+
+    0xf6, 0x00, 0x02, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xfa, 0x00, 0x02, 0x00, 0xfc, 0x00, 0x02, 0x00,
+    0xfe, 0x00, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x02, 0x01, 0x02, 0x00, 0x04, 0x01, 0x02, 0x00,
+    0x06, 0x01, 0x02, 0x00, 0x08, 0x01, 0x02, 0x00, 0x0a, 0x01, 0x02, 0x00, 0x0c, 0x01, 0x02, 0x00,
+    0x0e, 0x01, 0x02, 0x00, 0x10, 0x01, 0x02, 0x00, 0x12, 0x01, 0x02, 0x00, 0x14, 0x01, 0x02, 0x00,
+    0x16, 0x01, 0x02, 0x00, 0x18, 0x01, 0x02, 0x00, 0x1a, 0x01, 0x02, 0x00, 0x1c, 0x01, 0x02, 0x00,
+    0x1e, 0x01, 0x02, 0x00, 0x20, 0x01, 0x02, 0x00, 0x22, 0x01, 0x02, 0x00, 0x24, 0x01, 0x02, 0x00,
+    0x26, 0x01, 0x02, 0x00, 0x28, 0x01, 0x02, 0x00, 0x2a, 0x01, 0x02, 0x00, 0x2c, 0x01, 0x02, 0x00,
+    0x2e, 0x01, 0x02, 0x00, 0x30, 0x01, 0x02, 0x00, 0x32, 0x01, 0x02, 0x00, 0x34, 0x01, 0x02, 0x00,
+    0x36, 0x01, 0x02, 0x00, 0x38, 0x01, 0x02, 0x00, 0x3a, 0x01, 0x02, 0x00, 0x3c, 0x01, 0x02, 0x00,
+    0x3e, 0x01, 0x02, 0x00, 0x40, 0x01, 0x02, 0x00, 0x42, 0x01, 0x02, 0x00, 0x44, 0x01, 0x02, 0x00,
+    0x46, 0x01, 0x02, 0x00, 0x48, 0x01, 0x02, 0x00, 0x4a, 0x01, 0x02, 0x00, 0x4c, 0x01, 0x02, 0x00,
+    0x4e, 0x01, 0x02, 0x00, 0x50, 0x01, 0x02, 0x00, 0x52, 0x01, 0x02, 0x00, 0x54, 0x01, 0x02, 0x00,
+    0x56, 0x01, 0x02, 0x00, 0x58, 0x01, 0x02, 0x00, 0x5a, 0x01, 0x02, 0x00, 0x5c, 0x01, 0x02, 0x00,
+    0x5e, 0x01, 0x02, 0x00, 0x60, 0x01, 0x02, 0x00, 0x62, 0x01, 0x02, 0x00, 0x64, 0x01, 0x02, 0x00,
+    0x66, 0x01, 0x02, 0x00, 0x68, 0x01, 0x02, 0x00, 0x6a, 0x01, 0x02, 0x00, 0x6c, 0x01, 0x02, 0x00,
+    0x6e, 0x01, 0x02, 0x00, 0x70, 0x01, 0x02, 0x00, 0x72, 0x01, 0x02, 0x00, 0x74, 0x01, 0x02, 0x00,
+    0x76, 0x01, 0x02, 0x00, 0x78, 0x01, 0x02, 0x00, 0x7a, 0x01, 0x02, 0x00, 0x7c, 0x01, 0x02, 0x00,
+    0x7e, 0x01, 0x02, 0x00, 0x80, 0x01, 0x02, 0x00, 0x82, 0x01, 0x02, 0x00, 0x84, 0x01, 0x02, 0x00,
+    0x86, 0x01, 0x02, 0x00, 0x88, 0x01, 0x02, 0x00, 0x8a, 0x01, 0x02, 0x00, 0x8c, 0x01, 0x02, 0x00,
+    0x8e, 0x01, 0x02, 0x00, 0x90, 0x01, 0x02, 0x00, 0x92, 0x01, 0x02, 0x00, 0x94, 0x01, 0x02, 0x00,
+    0x96, 0x01, 0x02, 0x00, 0x98, 0x01, 0x02, 0x00, 0x9a, 0x01, 0x02, 0x00, 0x9c, 0x01, 0x02, 0x00,
+    0x9e, 0x01, 0x02, 0x00, 0xa0, 0x01, 0x02, 0x00, 0xa2, 0x01, 0x02, 0x00, 0xa4, 0x01, 0x02, 0x00,
+    0xa6, 0x01, 0x02, 0x00, 0xa8, 0x01, 0x02, 0x00, 0xaa, 0x01, 0x02, 0x00, 0xac, 0x01, 0x02, 0x00,
+    0xae, 0x01, 0x02, 0x00, 0xb0, 0x01, 0x02, 0x00, 0xb2, 0x01, 0x02, 0x00, 0xb4, 0x01, 0x02, 0x00,
+    0xb6, 0x01, 0x02, 0x00, 0xb8, 0x01, 0x02, 0x00, 0xba, 0x01, 0x02, 0x00, 0xbc, 0x01, 0x02, 0x00,
+    0xbe, 0x01, 0x02, 0x00, 0xc0, 0x01, 0x02, 0x00, 0xc2, 0x01, 0x02, 0x00, 0xc4, 0x01, 0x02, 0x00,
+    0xc6, 0x01, 0x02, 0x00, 0xc8, 0x01, 0x02, 0x00, 0xca, 0x01, 0x02, 0x00, 0xcc, 0x01, 0x02, 0x00,
+    0xce, 0x01, 0x02, 0x00, 0xd0, 0x01, 0x02, 0x00, 0xd2, 0x01, 0x02, 0x00, 0xd4, 0x01, 0x02, 0x00,
+    0xd6, 0x01, 0x02, 0x00, 0xd8, 0x01, 0x02, 0x00, 0xda, 0x01, 0x02, 0x00, 0xdc, 0x01, 0x02, 0x00,
+    0xde, 0x01, 0x02, 0x00, 0xe0, 0x01, 0x02, 0x00, 0xe2, 0x01, 0x02, 0x00, 0xe4, 0x01, 0x02, 0x00,
+    0xe6, 0x01, 0x02, 0x00, 0xe8, 0x01, 0x02, 0x00, 0xea, 0x01, 0x02, 0x00, 0xec, 0x01, 0x02, 0x00,
+    0xee, 0x01, 0x02, 0x00, 0xf0, 0x01, 0x02, 0x00, 0xf2, 0x01, 0x02, 0x00, 0xf4, 0x01, 0x02, 0x00,
+
+    0xf6, 0x01, 0x02, 0x00, 0xf8, 0x01, 0x02, 0x00, 0xfa, 0x01, 0x02, 0x00, 0xfc, 0x01, 0x02, 0x00,
+    0xfe, 0x01, 0x02, 0x00, 0x00, 0x02, 0x02, 0x00, 0x02, 0x02, 0x02, 0x00, 0x04, 0x02, 0x02, 0x00,
+    0x06, 0x02, 0x02, 0x00, 0x08, 0x02, 0x02, 0x00, 0x0a, 0x02, 0x02, 0x00, 0x0c, 0x02, 0x02, 0x00,
+    0x0e, 0x02, 0x02, 0x00, 0x10, 0x02, 0x02, 0x00, 0x12, 0x02, 0x02, 0x00, 0x14, 0x02, 0x02, 0x00,
+    0x16, 0x02, 0x02, 0x00, 0x18, 0x02, 0x02, 0x00, 0x1a, 0x02, 0x02, 0x00, 0x1c, 0x02, 0x02, 0x00,
+    0x1e, 0x02, 0x02, 0x00, 0x20, 0x02, 0x02, 0x00, 0x22, 0x02, 0x02, 0x00, 0x24, 0x02, 0x02, 0x00,
+    0x26, 0x02, 0x02, 0x00, 0x28, 0x02, 0x02, 0x00, 0x2a, 0x02, 0x02, 0x00, 0x2c, 0x02, 0x02, 0x00,
+    0x2e, 0x02, 0x02, 0x00, 0x30, 0x02, 0x02, 0x00, 0x32, 0x02, 0x02, 0x00, 0x34, 0x02, 0x02, 0x00,
+    0x36, 0x02, 0x02, 0x00, 0x38, 0x02, 0x02, 0x00, 0x3a, 0x02, 0x02, 0x00, 0x3c, 0x02, 0x02, 0x00,
+    0x3e, 0x02, 0x02, 0x00, 0x40, 0x02, 0x02, 0x00, 0x42, 0x02, 0x02, 0x00, 0x44, 0x02, 0x02, 0x00,
+    0x46, 0x02, 0x02, 0x00, 0x48, 0x02, 0x02, 0x00, 0x4a, 0x02, 0x02, 0x00, 0x4c, 0x02, 0x02, 0x00,
+    0x4e, 0x02, 0x02, 0x00, 0x50, 0x02, 0x02, 0x00, 0x52, 0x02, 0x02, 0x00, 0x54, 0x02, 0x02, 0x00,
+    0x56, 0x02, 0x02, 0x00, 0x58, 0x02, 0x02, 0x00, 0x5a, 0x02, 0x02, 0x00, 0x5c, 0x02, 0x02, 0x00,
+    0x5e, 0x02, 0x02, 0x00, 0x60, 0x02, 0x02, 0x00, 0x62, 0x02, 0x02, 0x00, 0x64, 0x02, 0x02, 0x00,
+    0x66, 0x02, 0x02, 0x00, 0x68, 0x02, 0x02, 0x00, 0x6a, 0x02, 0x02, 0x00, 0x6c, 0x02, 0x02, 0x00,
+    0x6e, 0x02, 0x02, 0x00, 0x70, 0x02, 0x02, 0x00, 0x72, 0x02, 0x02, 0x00, 0x74, 0x02, 0x02, 0x00,
+    0x76, 0x02, 0x02, 0x00, 0x78, 0x02, 0x02, 0x00, 0x7a, 0x02, 0x02, 0x00, 0x7c, 0x02, 0x02, 0x00,
+    0x7e, 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x00, 0x82, 0x02, 0x02, 0x00, 0x84, 0x02, 0x02, 0x00,
+    0x86, 0x02, 0x02, 0x00, 0x88, 0x02, 0x02, 0x00, 0x8a, 0x02, 0x02, 0x00, 0x8c, 0x02, 0x02, 0x00,
+    0x8e, 0x02, 0x02, 0x00, 0x90, 0x02, 0x02, 0x00, 0x92, 0x02, 0x02, 0x00, 0x94, 0x02, 0x02, 0x00,
+    0x96, 0x02, 0x02, 0x00, 0x98, 0x02, 0x02, 0x00, 0x9a, 0x02, 0x02, 0x00, 0x9c, 0x02, 0x02, 0x00,
+    0x9e, 0x02, 0x02, 0x00, 0xa0, 0x02, 0x02, 0x00, 0xa2, 0x02, 0x02, 0x00, 0xa4, 0x02, 0x02, 0x00,
+    0xa6, 0x02, 0x02, 0x00, 0xa8, 0x02, 0x02, 0x00, 0xaa, 0x02, 0x02, 0x00, 0xac, 0x02, 0x02, 0x00,
+    0xae, 0x02, 0x02, 0x00, 0xb0, 0x02, 0x02, 0x00, 0xb2, 0x02, 0x02, 0x00, 0xb4, 0x02, 0x02, 0x00,
+    0xb6, 0x02, 0x02, 0x00, 0xb8, 0x02, 0x02, 0x00, 0xba, 0x02, 0x02, 0x00, 0xbc, 0x02, 0x02, 0x00,
+    0xbe, 0x02, 0x02, 0x00, 0xc0, 0x02, 0x02, 0x00, 0xc2, 0x02, 0x02, 0x00, 0xc4, 0x02, 0x02, 0x00,
+    0xc6, 0x02, 0x02, 0x00, 0xc8, 0x02, 0x02, 0x00, 0xca, 0x02, 0x02, 0x00, 0xcc, 0x02, 0x02, 0x00,
+    0xce, 0x02, 0x02, 0x00, 0xd0, 0x02, 0x02, 0x00, 0xd2, 0x02, 0x02, 0x00, 0xd4, 0x02, 0x02, 0x00,
+    0xd6, 0x02, 0x02, 0x00, 0xd8, 0x02, 0x02, 0x00, 0xda, 0x02, 0x02, 0x00, 0xdc, 0x02, 0x02, 0x00,
+    0xde, 0x02, 0x02, 0x00, 0xe0, 0x02, 0x02, 0x00, 0xe2, 0x02, 0x02, 0x00, 0xe4, 0x02, 0x02, 0x00,
+    0xe6, 0x02, 0x02, 0x00, 0xe8, 0x02, 0x02, 0x00, 0xea, 0x02, 0x02, 0x00, 0xec, 0x02, 0x02, 0x00,
+    0xee, 0x02, 0x02, 0x00, 0xf0, 0x02, 0x02, 0x00, 0xf2, 0x02, 0x02, 0x00, 0xf4, 0x02, 0x02, 0x00,
+
+    0xf6, 0x02, 0x02, 0x00, 0xf8, 0x02, 0x02, 0x00, 0xfa, 0x02, 0x02, 0x00, 0xfc, 0x02, 0x02, 0x00,
+    0xfe, 0x02, 0x02, 0x00, 0x00, 0x03, 0x02, 0x00, 0x02, 0x03, 0x02, 0x00, 0x04, 0x03, 0x02, 0x00,
+    0x06, 0x03, 0x02, 0x00, 0x08, 0x03, 0x02, 0x00, 0x0a, 0x03, 0x02, 0x00, 0x0c, 0x03, 0x02, 0x00,
+    0x0e, 0x03, 0x02, 0x00, 0x10, 0x03, 0x02, 0x00, 0x12, 0x03, 0x02, 0x00, 0x14, 0x03, 0x02, 0x00,
+    0x16, 0x03, 0x02, 0x00, 0x18, 0x03, 0x02, 0x00, 0x1a, 0x03, 0x02, 0x00, 0x1c, 0x03, 0x02, 0x00,
+    0x1e, 0x03, 0x02, 0x00, 0x20, 0x03, 0x02, 0x00, 0x22, 0x03, 0x02, 0x00, 0x24, 0x03, 0x02, 0x00,
+    0x26, 0x03, 0x02, 0x00, 0x28, 0x03, 0x02, 0x00, 0x2a, 0x03, 0x02, 0x00, 0x2c, 0x03, 0x02, 0x00,
+    0x2e, 0x03, 0x02, 0x00, 0x30, 0x03, 0x02, 0x00, 0x32, 0x03, 0x02, 0x00, 0x34, 0x03, 0x02, 0x00,
+    0x36, 0x03, 0x02, 0x00, 0x38, 0x03, 0x02, 0x00, 0x3a, 0x03, 0x02, 0x00, 0x3c, 0x03, 0x02, 0x00,
+    0x3e, 0x03, 0x02, 0x00, 0x40, 0x03, 0x02, 0x00, 0x42, 0x03, 0x02, 0x00, 0x44, 0x03, 0x02, 0x00,
+    0x46, 0x03, 0x02, 0x00, 0x48, 0x03, 0x02, 0x00, 0x4a, 0x03, 0x02, 0x00, 0x4c, 0x03, 0x02, 0x00,
+    0x4e, 0x03, 0x02, 0x00, 0x50, 0x03, 0x02, 0x00, 0x52, 0x03, 0x02, 0x00, 0x54, 0x03, 0x02, 0x00,
+    0x56, 0x03, 0x02, 0x00, 0x58, 0x03, 0x02, 0x00, 0x5a, 0x03, 0x02, 0x00, 0x5c, 0x03, 0x02, 0x00,
+    0x5e, 0x03, 0x02, 0x00, 0x60, 0x03, 0x02, 0x00, 0x62, 0x03, 0x02, 0x00, 0x64, 0x03, 0x02, 0x00,
+    0x66, 0x03, 0x02, 0x00, 0x68, 0x03, 0x02, 0x00, 0x6a, 0x03, 0x02, 0x00, 0x6c, 0x03, 0x02, 0x00,
+    0x6e, 0x03, 0x02, 0x00, 0x70, 0x03, 0x02, 0x00, 0x72, 0x03, 0x02, 0x00, 0x74, 0x03, 0x02, 0x00,
+    0x76, 0x03, 0x02, 0x00, 0x78, 0x03, 0x02, 0x00, 0x7a, 0x03, 0x02, 0x00, 0x7c, 0x03, 0x02, 0x00,
+    0x7e, 0x03, 0x02, 0x00, 0x80, 0x03, 0x02, 0x00, 0x82, 0x03, 0x02, 0x00, 0x84, 0x03, 0x02, 0x00,
+    0x86, 0x03, 0x02, 0x00, 0x88, 0x03, 0x02, 0x00, 0x8a, 0x03, 0x02, 0x00, 0x8c, 0x03, 0x02, 0x00,
+    0x8e, 0x03, 0x02, 0x00, 0x90, 0x03, 0x02, 0x00, 0x92, 0x03, 0x02, 0x00, 0x94, 0x03, 0x02, 0x00,
+    0x96, 0x03, 0x02, 0x00, 0x98, 0x03, 0x02, 0x00, 0x9a, 0x03, 0x02, 0x00, 0x9c, 0x03, 0x02, 0x00,
+    0x9e, 0x03, 0x02, 0x00, 0xa0, 0x03, 0x02, 0x00, 0xa2, 0x03, 0x02, 0x00, 0xa4, 0x03, 0x02, 0x00,
+    0xa6, 0x03, 0x02, 0x00, 0xa8, 0x03, 0x02, 0x00, 0xaa, 0x03, 0x02, 0x00, 0xac, 0x03, 0x02, 0x00,
+    0xae, 0x03, 0x02, 0x00, 0xb0, 0x03, 0x02, 0x00, 0xb2, 0x03, 0x02, 0x00, 0xb4, 0x03, 0x02, 0x00,
+    0xb6, 0x03, 0x02, 0x00, 0xb8, 0x03, 0x02, 0x00, 0xba, 0x03, 0x02, 0x00, 0xbc, 0x03, 0x02, 0x00,
+    0xbe, 0x03, 0x02, 0x00, 0xc0, 0x03, 0x02, 0x00, 0xc2, 0x03, 0x02, 0x00, 0xc4, 0x03, 0x02, 0x00,
+    0xc6, 0x03, 0x02, 0x00, 0xc8, 0x03, 0x02, 0x00, 0xca, 0x03, 0x02, 0x00, 0xcc, 0x03, 0x02, 0x00,
+    0xce, 0x03, 0x02, 0x00, 0xd0, 0x03, 0x02, 0x00, 0xd2, 0x03, 0x02, 0x00, 0xd4, 0x03, 0x02, 0x00,
+    0xd6, 0x03, 0x02, 0x00, 0xd8, 0x03, 0x02, 0x00, 0xda, 0x03, 0x02, 0x00, 0xdc, 0x03, 0x02, 0x00,
+    0xde, 0x03, 0x02, 0x00, 0xe0, 0x03, 0x02, 0x00, 0xe2, 0x03, 0x02, 0x00, 0xe4, 0x03, 0x02, 0x00,
+    0xe6, 0x03, 0x02, 0x00, 0xe8, 0x03, 0x02, 0x00, 0xea, 0x03, 0x02, 0x00, 0xec, 0x03, 0x02, 0x00,
+    0xee, 0x03, 0x02, 0x00, 0xf0, 0x03, 0x02, 0x00, 0xf2, 0x03, 0x02, 0x00, 0xf4, 0x03, 0x02, 0x00,
+
+    0xf6, 0x03, 0x02, 0x00, 0xf8, 0x03, 0x02, 0x00, 0xfa, 0x03, 0x02, 0x00, 0xfc, 0x03, 0x02, 0x00,
+    0xfe, 0x03, 0x02, 0x00
+};
+
+#ifdef _USE_GAMMA_RESET_HC_
+const uint8_t mGammaResetTablesBuf[] = {
+    0x0E, 0x00, 0x00, 0x00, /// ID -> 4 bytes
+
+    0x03,           /// eGammaTblSize -> 1 byte
+    0x00,           /// nTbl -> 1 byte
+    0x00,           /// eBypassB -> 1 byte
+    0x00,           /// eBypassG -> 1 byte
+    0x00,           /// eBypassR -> 1 byte
+    0x00, 0x00, 0x00, 0x04, /// *pnRedTable
+    0x00, 0x00, 0x00, 0x04, /// *pnBlueTable
+    0x08, 0x00, 0x00, 0x04, /// *pnGreenTable
+
+    0x10, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02,0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00,
+    0x06, 0x00, 0x02, 0x00, 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x02, 0x00, 0x0c, 0x00, 0x02, 0x00,
+    0x0e, 0x00, 0x02, 0x00, 0x10, 0x00, 0x02, 0x00, 0x12, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00,
+    0x16, 0x00, 0x02, 0x00, 0x18, 0x00, 0x02, 0x00, 0x1a, 0x00, 0x02, 0x00, 0x1c, 0x00, 0x02, 0x00,
+    0x1e, 0x00, 0x02, 0x00, 0x20, 0x00, 0x02, 0x00, 0x22, 0x00, 0x02, 0x00, 0x24, 0x00, 0x02, 0x00,
+    0x26, 0x00, 0x02, 0x00, 0x28, 0x00, 0x02, 0x00, 0x2a, 0x00, 0x02, 0x00, 0x2c, 0x00, 0x02, 0x00,
+    0x2e, 0x00, 0x02, 0x00, 0x30, 0x00, 0x02, 0x00, 0x32, 0x00, 0x02, 0x00, 0x34, 0x00, 0x02, 0x00,
+    0x36, 0x00, 0x02, 0x00, 0x38, 0x00, 0x02, 0x00, 0x3a, 0x00, 0x02, 0x00, 0x3c, 0x00, 0x02, 0x00,
+    0x3e, 0x00, 0x02, 0x00, 0x40, 0x00, 0x02, 0x00, 0x42, 0x00, 0x02, 0x00, 0x44, 0x00, 0x02, 0x00,
+    0x46, 0x00, 0x02, 0x00, 0x48, 0x00, 0x02, 0x00, 0x4a, 0x00, 0x02, 0x00, 0x4c, 0x00, 0x02, 0x00,
+    0x4e, 0x00, 0x02, 0x00, 0x50, 0x00, 0x02, 0x00, 0x52, 0x00, 0x02, 0x00, 0x54, 0x00, 0x02, 0x00,
+    0x56, 0x00, 0x02, 0x00, 0x58, 0x00, 0x02, 0x00, 0x5a, 0x00, 0x02, 0x00, 0x5c, 0x00, 0x02, 0x00,
+    0x5e, 0x00, 0x02, 0x00, 0x60, 0x00, 0x02, 0x00, 0x62, 0x00, 0x02, 0x00, 0x64, 0x00, 0x02, 0x00,
+    0x66, 0x00, 0x02, 0x00, 0x68, 0x00, 0x02, 0x00, 0x6a, 0x00, 0x02, 0x00, 0x6c, 0x00, 0x02, 0x00,
+    0x6e, 0x00, 0x02, 0x00, 0x70, 0x00, 0x02, 0x00, 0x72, 0x00, 0x02, 0x00, 0x74, 0x00, 0x02, 0x00,
+    0x76, 0x00, 0x02, 0x00, 0x78, 0x00, 0x02, 0x00, 0x7a, 0x00, 0x02, 0x00, 0x7c, 0x00, 0x02, 0x00,
+    0x7e, 0x00, 0x02, 0x00, 0x80, 0x00, 0x02, 0x00, 0x82, 0x00, 0x02, 0x00, 0x84, 0x00, 0x02, 0x00,
+    0x86, 0x00, 0x02, 0x00, 0x88, 0x00, 0x02, 0x00, 0x8a, 0x00, 0x02, 0x00, 0x8c, 0x00, 0x02, 0x00,
+    0x8e, 0x00, 0x02, 0x00, 0x90, 0x00, 0x02, 0x00, 0x92, 0x00, 0x02, 0x00, 0x94, 0x00, 0x02, 0x00,
+    0x96, 0x00, 0x02, 0x00, 0x98, 0x00, 0x02, 0x00, 0x9a, 0x00, 0x02, 0x00, 0x9c, 0x00, 0x02, 0x00,
+    0x9e, 0x00, 0x02, 0x00, 0xa0, 0x00, 0x02, 0x00, 0xa2, 0x00, 0x02, 0x00, 0xa4, 0x00, 0x02, 0x00,
+    0xa6, 0x00, 0x02, 0x00, 0xa8, 0x00, 0x02, 0x00, 0xaa, 0x00, 0x02, 0x00, 0xac, 0x00, 0x02, 0x00,
+    0xae, 0x00, 0x02, 0x00, 0xb0, 0x00, 0x02, 0x00, 0xb2, 0x00, 0x02, 0x00, 0xb4, 0x00, 0x02, 0x00,
+    0xb6, 0x00, 0x02, 0x00, 0xb8, 0x00, 0x02, 0x00, 0xba, 0x00, 0x02, 0x00, 0xbc, 0x00, 0x02, 0x00,
+    0xbe, 0x00, 0x02, 0x00, 0xc0, 0x00, 0x02, 0x00, 0xc2, 0x00, 0x02, 0x00, 0xc4, 0x00, 0x02, 0x00,
+    0xc6, 0x00, 0x02, 0x00, 0xc8, 0x00, 0x02, 0x00, 0xca, 0x00, 0x02, 0x00, 0xcc, 0x00, 0x02, 0x00,
+    0xce, 0x00, 0x02, 0x00, 0xd0, 0x00, 0x02, 0x00, 0xd2, 0x00, 0x02, 0x00, 0xd4, 0x00, 0x02, 0x00,
+    0xd6, 0x00, 0x02, 0x00, 0xd8, 0x00, 0x02, 0x00, 0xda, 0x00, 0x02, 0x00, 0xdc, 0x00, 0x02, 0x00,
+    0xde, 0x00, 0x02, 0x00, 0xe0, 0x00, 0x02, 0x00, 0xe2, 0x00, 0x02, 0x00, 0xe4, 0x00, 0x02, 0x00,
+    0xe6, 0x00, 0x02, 0x00, 0xe8, 0x00, 0x02, 0x00, 0xea, 0x00, 0x02, 0x00, 0xec, 0x00, 0x02, 0x00,
+    0xee, 0x00, 0x02, 0x00, 0xf0, 0x00, 0x02, 0x00, 0xf2, 0x00, 0x02, 0x00, 0xf4, 0x00, 0x02, 0x00,
+
+    0xf6, 0x00, 0x02, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xfa, 0x00, 0x02, 0x00, 0xfc, 0x00, 0x02, 0x00,
+    0xfe, 0x00, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x02, 0x01, 0x02, 0x00, 0x04, 0x01, 0x02, 0x00,
+    0x06, 0x01, 0x02, 0x00, 0x08, 0x01, 0x02, 0x00, 0x0a, 0x01, 0x02, 0x00, 0x0c, 0x01, 0x02, 0x00,
+    0x0e, 0x01, 0x02, 0x00, 0x10, 0x01, 0x02, 0x00, 0x12, 0x01, 0x02, 0x00, 0x14, 0x01, 0x02, 0x00,
+    0x16, 0x01, 0x02, 0x00, 0x18, 0x01, 0x02, 0x00, 0x1a, 0x01, 0x02, 0x00, 0x1c, 0x01, 0x02, 0x00,
+    0x1e, 0x01, 0x02, 0x00, 0x20, 0x01, 0x02, 0x00, 0x22, 0x01, 0x02, 0x00, 0x24, 0x01, 0x02, 0x00,
+    0x26, 0x01, 0x02, 0x00, 0x28, 0x01, 0x02, 0x00, 0x2a, 0x01, 0x02, 0x00, 0x2c, 0x01, 0x02, 0x00,
+    0x2e, 0x01, 0x02, 0x00, 0x30, 0x01, 0x02, 0x00, 0x32, 0x01, 0x02, 0x00, 0x34, 0x01, 0x02, 0x00,
+    0x36, 0x01, 0x02, 0x00, 0x38, 0x01, 0x02, 0x00, 0x3a, 0x01, 0x02, 0x00, 0x3c, 0x01, 0x02, 0x00,
+    0x3e, 0x01, 0x02, 0x00, 0x40, 0x01, 0x02, 0x00, 0x42, 0x01, 0x02, 0x00, 0x44, 0x01, 0x02, 0x00,
+    0x46, 0x01, 0x02, 0x00, 0x48, 0x01, 0x02, 0x00, 0x4a, 0x01, 0x02, 0x00, 0x4c, 0x01, 0x02, 0x00,
+    0x4e, 0x01, 0x02, 0x00, 0x50, 0x01, 0x02, 0x00, 0x52, 0x01, 0x02, 0x00, 0x54, 0x01, 0x02, 0x00,
+    0x56, 0x01, 0x02, 0x00, 0x58, 0x01, 0x02, 0x00, 0x5a, 0x01, 0x02, 0x00, 0x5c, 0x01, 0x02, 0x00,
+    0x5e, 0x01, 0x02, 0x00, 0x60, 0x01, 0x02, 0x00, 0x62, 0x01, 0x02, 0x00, 0x64, 0x01, 0x02, 0x00,
+    0x66, 0x01, 0x02, 0x00, 0x68, 0x01, 0x02, 0x00, 0x6a, 0x01, 0x02, 0x00, 0x6c, 0x01, 0x02, 0x00,
+    0x6e, 0x01, 0x02, 0x00, 0x70, 0x01, 0x02, 0x00, 0x72, 0x01, 0x02, 0x00, 0x74, 0x01, 0x02, 0x00,
+    0x76, 0x01, 0x02, 0x00, 0x78, 0x01, 0x02, 0x00, 0x7a, 0x01, 0x02, 0x00, 0x7c, 0x01, 0x02, 0x00,
+    0x7e, 0x01, 0x02, 0x00, 0x80, 0x01, 0x02, 0x00, 0x82, 0x01, 0x02, 0x00, 0x84, 0x01, 0x02, 0x00,
+    0x86, 0x01, 0x02, 0x00, 0x88, 0x01, 0x02, 0x00, 0x8a, 0x01, 0x02, 0x00, 0x8c, 0x01, 0x02, 0x00,
+    0x8e, 0x01, 0x02, 0x00, 0x90, 0x01, 0x02, 0x00, 0x92, 0x01, 0x02, 0x00, 0x94, 0x01, 0x02, 0x00,
+    0x96, 0x01, 0x02, 0x00, 0x98, 0x01, 0x02, 0x00, 0x9a, 0x01, 0x02, 0x00, 0x9c, 0x01, 0x02, 0x00,
+    0x9e, 0x01, 0x02, 0x00, 0xa0, 0x01, 0x02, 0x00, 0xa2, 0x01, 0x02, 0x00, 0xa4, 0x01, 0x02, 0x00,
+    0xa6, 0x01, 0x02, 0x00, 0xa8, 0x01, 0x02, 0x00, 0xaa, 0x01, 0x02, 0x00, 0xac, 0x01, 0x02, 0x00,
+    0xae, 0x01, 0x02, 0x00, 0xb0, 0x01, 0x02, 0x00, 0xb2, 0x01, 0x02, 0x00, 0xb4, 0x01, 0x02, 0x00,
+    0xb6, 0x01, 0x02, 0x00, 0xb8, 0x01, 0x02, 0x00, 0xba, 0x01, 0x02, 0x00, 0xbc, 0x01, 0x02, 0x00,
+    0xbe, 0x01, 0x02, 0x00, 0xc0, 0x01, 0x02, 0x00, 0xc2, 0x01, 0x02, 0x00, 0xc4, 0x01, 0x02, 0x00,
+    0xc6, 0x01, 0x02, 0x00, 0xc8, 0x01, 0x02, 0x00, 0xca, 0x01, 0x02, 0x00, 0xcc, 0x01, 0x02, 0x00,
+    0xce, 0x01, 0x02, 0x00, 0xd0, 0x01, 0x02, 0x00, 0xd2, 0x01, 0x02, 0x00, 0xd4, 0x01, 0x02, 0x00,
+    0xd6, 0x01, 0x02, 0x00, 0xd8, 0x01, 0x02, 0x00, 0xda, 0x01, 0x02, 0x00, 0xdc, 0x01, 0x02, 0x00,
+    0xde, 0x01, 0x02, 0x00, 0xe0, 0x01, 0x02, 0x00, 0xe2, 0x01, 0x02, 0x00, 0xe4, 0x01, 0x02, 0x00,
+    0xe6, 0x01, 0x02, 0x00, 0xe8, 0x01, 0x02, 0x00, 0xea, 0x01, 0x02, 0x00, 0xec, 0x01, 0x02, 0x00,
+    0xee, 0x01, 0x02, 0x00, 0xf0, 0x01, 0x02, 0x00, 0xf2, 0x01, 0x02, 0x00, 0xf4, 0x01, 0x02, 0x00,
+
+    0xf6, 0x01, 0x02, 0x00, 0xf8, 0x01, 0x02, 0x00, 0xfa, 0x01, 0x02, 0x00, 0xfc, 0x01, 0x02, 0x00,
+    0xfe, 0x01, 0x02, 0x00, 0x00, 0x02, 0x02, 0x00, 0x02, 0x02, 0x02, 0x00, 0x04, 0x02, 0x02, 0x00,
+    0x06, 0x02, 0x02, 0x00, 0x08, 0x02, 0x02, 0x00, 0x0a, 0x02, 0x02, 0x00, 0x0c, 0x02, 0x02, 0x00,
+    0x0e, 0x02, 0x02, 0x00, 0x10, 0x02, 0x02, 0x00, 0x12, 0x02, 0x02, 0x00, 0x14, 0x02, 0x02, 0x00,
+    0x16, 0x02, 0x02, 0x00, 0x18, 0x02, 0x02, 0x00, 0x1a, 0x02, 0x02, 0x00, 0x1c, 0x02, 0x02, 0x00,
+    0x1e, 0x02, 0x02, 0x00, 0x20, 0x02, 0x02, 0x00, 0x22, 0x02, 0x02, 0x00, 0x24, 0x02, 0x02, 0x00,
+    0x26, 0x02, 0x02, 0x00, 0x28, 0x02, 0x02, 0x00, 0x2a, 0x02, 0x02, 0x00, 0x2c, 0x02, 0x02, 0x00,
+    0x2e, 0x02, 0x02, 0x00, 0x30, 0x02, 0x02, 0x00, 0x32, 0x02, 0x02, 0x00, 0x34, 0x02, 0x02, 0x00,
+    0x36, 0x02, 0x02, 0x00, 0x38, 0x02, 0x02, 0x00, 0x3a, 0x02, 0x02, 0x00, 0x3c, 0x02, 0x02, 0x00,
+    0x3e, 0x02, 0x02, 0x00, 0x40, 0x02, 0x02, 0x00, 0x42, 0x02, 0x02, 0x00, 0x44, 0x02, 0x02, 0x00,
+    0x46, 0x02, 0x02, 0x00, 0x48, 0x02, 0x02, 0x00, 0x4a, 0x02, 0x02, 0x00, 0x4c, 0x02, 0x02, 0x00,
+    0x4e, 0x02, 0x02, 0x00, 0x50, 0x02, 0x02, 0x00, 0x52, 0x02, 0x02, 0x00, 0x54, 0x02, 0x02, 0x00,
+    0x56, 0x02, 0x02, 0x00, 0x58, 0x02, 0x02, 0x00, 0x5a, 0x02, 0x02, 0x00, 0x5c, 0x02, 0x02, 0x00,
+    0x5e, 0x02, 0x02, 0x00, 0x60, 0x02, 0x02, 0x00, 0x62, 0x02, 0x02, 0x00, 0x64, 0x02, 0x02, 0x00,
+    0x66, 0x02, 0x02, 0x00, 0x68, 0x02, 0x02, 0x00, 0x6a, 0x02, 0x02, 0x00, 0x6c, 0x02, 0x02, 0x00,
+    0x6e, 0x02, 0x02, 0x00, 0x70, 0x02, 0x02, 0x00, 0x72, 0x02, 0x02, 0x00, 0x74, 0x02, 0x02, 0x00,
+    0x76, 0x02, 0x02, 0x00, 0x78, 0x02, 0x02, 0x00, 0x7a, 0x02, 0x02, 0x00, 0x7c, 0x02, 0x02, 0x00,
+    0x7e, 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x00, 0x82, 0x02, 0x02, 0x00, 0x84, 0x02, 0x02, 0x00,
+    0x86, 0x02, 0x02, 0x00, 0x88, 0x02, 0x02, 0x00, 0x8a, 0x02, 0x02, 0x00, 0x8c, 0x02, 0x02, 0x00,
+    0x8e, 0x02, 0x02, 0x00, 0x90, 0x02, 0x02, 0x00, 0x92, 0x02, 0x02, 0x00, 0x94, 0x02, 0x02, 0x00,
+    0x96, 0x02, 0x02, 0x00, 0x98, 0x02, 0x02, 0x00, 0x9a, 0x02, 0x02, 0x00, 0x9c, 0x02, 0x02, 0x00,
+    0x9e, 0x02, 0x02, 0x00, 0xa0, 0x02, 0x02, 0x00, 0xa2, 0x02, 0x02, 0x00, 0xa4, 0x02, 0x02, 0x00,
+    0xa6, 0x02, 0x02, 0x00, 0xa8, 0x02, 0x02, 0x00, 0xaa, 0x02, 0x02, 0x00, 0xac, 0x02, 0x02, 0x00,
+    0xae, 0x02, 0x02, 0x00, 0xb0, 0x02, 0x02, 0x00, 0xb2, 0x02, 0x02, 0x00, 0xb4, 0x02, 0x02, 0x00,
+    0xb6, 0x02, 0x02, 0x00, 0xb8, 0x02, 0x02, 0x00, 0xba, 0x02, 0x02, 0x00, 0xbc, 0x02, 0x02, 0x00,
+    0xbe, 0x02, 0x02, 0x00, 0xc0, 0x02, 0x02, 0x00, 0xc2, 0x02, 0x02, 0x00, 0xc4, 0x02, 0x02, 0x00,
+    0xc6, 0x02, 0x02, 0x00, 0xc8, 0x02, 0x02, 0x00, 0xca, 0x02, 0x02, 0x00, 0xcc, 0x02, 0x02, 0x00,
+    0xce, 0x02, 0x02, 0x00, 0xd0, 0x02, 0x02, 0x00, 0xd2, 0x02, 0x02, 0x00, 0xd4, 0x02, 0x02, 0x00,
+    0xd6, 0x02, 0x02, 0x00, 0xd8, 0x02, 0x02, 0x00, 0xda, 0x02, 0x02, 0x00, 0xdc, 0x02, 0x02, 0x00,
+    0xde, 0x02, 0x02, 0x00, 0xe0, 0x02, 0x02, 0x00, 0xe2, 0x02, 0x02, 0x00, 0xe4, 0x02, 0x02, 0x00,
+    0xe6, 0x02, 0x02, 0x00, 0xe8, 0x02, 0x02, 0x00, 0xea, 0x02, 0x02, 0x00, 0xec, 0x02, 0x02, 0x00,
+    0xee, 0x02, 0x02, 0x00, 0xf0, 0x02, 0x02, 0x00, 0xf2, 0x02, 0x02, 0x00, 0xf4, 0x02, 0x02, 0x00,
+
+    0xf6, 0x02, 0x02, 0x00, 0xf8, 0x02, 0x02, 0x00, 0xfa, 0x02, 0x02, 0x00, 0xfc, 0x02, 0x02, 0x00,
+    0xfe, 0x02, 0x02, 0x00, 0x00, 0x03, 0x02, 0x00, 0x02, 0x03, 0x02, 0x00, 0x04, 0x03, 0x02, 0x00,
+    0x06, 0x03, 0x02, 0x00, 0x08, 0x03, 0x02, 0x00, 0x0a, 0x03, 0x02, 0x00, 0x0c, 0x03, 0x02, 0x00,
+    0x0e, 0x03, 0x02, 0x00, 0x10, 0x03, 0x02, 0x00, 0x12, 0x03, 0x02, 0x00, 0x14, 0x03, 0x02, 0x00,
+    0x16, 0x03, 0x02, 0x00, 0x18, 0x03, 0x02, 0x00, 0x1a, 0x03, 0x02, 0x00, 0x1c, 0x03, 0x02, 0x00,
+    0x1e, 0x03, 0x02, 0x00, 0x20, 0x03, 0x02, 0x00, 0x22, 0x03, 0x02, 0x00, 0x24, 0x03, 0x02, 0x00,
+    0x26, 0x03, 0x02, 0x00, 0x28, 0x03, 0x02, 0x00, 0x2a, 0x03, 0x02, 0x00, 0x2c, 0x03, 0x02, 0x00,
+    0x2e, 0x03, 0x02, 0x00, 0x30, 0x03, 0x02, 0x00, 0x32, 0x03, 0x02, 0x00, 0x34, 0x03, 0x02, 0x00,
+    0x36, 0x03, 0x02, 0x00, 0x38, 0x03, 0x02, 0x00, 0x3a, 0x03, 0x02, 0x00, 0x3c, 0x03, 0x02, 0x00,
+    0x3e, 0x03, 0x02, 0x00, 0x40, 0x03, 0x02, 0x00, 0x42, 0x03, 0x02, 0x00, 0x44, 0x03, 0x02, 0x00,
+    0x46, 0x03, 0x02, 0x00, 0x48, 0x03, 0x02, 0x00, 0x4a, 0x03, 0x02, 0x00, 0x4c, 0x03, 0x02, 0x00,
+    0x4e, 0x03, 0x02, 0x00, 0x50, 0x03, 0x02, 0x00, 0x52, 0x03, 0x02, 0x00, 0x54, 0x03, 0x02, 0x00,
+    0x56, 0x03, 0x02, 0x00, 0x58, 0x03, 0x02, 0x00, 0x5a, 0x03, 0x02, 0x00, 0x5c, 0x03, 0x02, 0x00,
+    0x5e, 0x03, 0x02, 0x00, 0x60, 0x03, 0x02, 0x00, 0x62, 0x03, 0x02, 0x00, 0x64, 0x03, 0x02, 0x00,
+    0x66, 0x03, 0x02, 0x00, 0x68, 0x03, 0x02, 0x00, 0x6a, 0x03, 0x02, 0x00, 0x6c, 0x03, 0x02, 0x00,
+    0x6e, 0x03, 0x02, 0x00, 0x70, 0x03, 0x02, 0x00, 0x72, 0x03, 0x02, 0x00, 0x74, 0x03, 0x02, 0x00,
+    0x76, 0x03, 0x02, 0x00, 0x78, 0x03, 0x02, 0x00, 0x7a, 0x03, 0x02, 0x00, 0x7c, 0x03, 0x02, 0x00,
+    0x7e, 0x03, 0x02, 0x00, 0x80, 0x03, 0x02, 0x00, 0x82, 0x03, 0x02, 0x00, 0x84, 0x03, 0x02, 0x00,
+    0x86, 0x03, 0x02, 0x00, 0x88, 0x03, 0x02, 0x00, 0x8a, 0x03, 0x02, 0x00, 0x8c, 0x03, 0x02, 0x00,
+    0x8e, 0x03, 0x02, 0x00, 0x90, 0x03, 0x02, 0x00, 0x92, 0x03, 0x02, 0x00, 0x94, 0x03, 0x02, 0x00,
+    0x96, 0x03, 0x02, 0x00, 0x98, 0x03, 0x02, 0x00, 0x9a, 0x03, 0x02, 0x00, 0x9c, 0x03, 0x02, 0x00,
+    0x9e, 0x03, 0x02, 0x00, 0xa0, 0x03, 0x02, 0x00, 0xa2, 0x03, 0x02, 0x00, 0xa4, 0x03, 0x02, 0x00,
+    0xa6, 0x03, 0x02, 0x00, 0xa8, 0x03, 0x02, 0x00, 0xaa, 0x03, 0x02, 0x00, 0xac, 0x03, 0x02, 0x00,
+    0xae, 0x03, 0x02, 0x00, 0xb0, 0x03, 0x02, 0x00, 0xb2, 0x03, 0x02, 0x00, 0xb4, 0x03, 0x02, 0x00,
+    0xb6, 0x03, 0x02, 0x00, 0xb8, 0x03, 0x02, 0x00, 0xba, 0x03, 0x02, 0x00, 0xbc, 0x03, 0x02, 0x00,
+    0xbe, 0x03, 0x02, 0x00, 0xc0, 0x03, 0x02, 0x00, 0xc2, 0x03, 0x02, 0x00, 0xc4, 0x03, 0x02, 0x00,
+    0xc6, 0x03, 0x02, 0x00, 0xc8, 0x03, 0x02, 0x00, 0xca, 0x03, 0x02, 0x00, 0xcc, 0x03, 0x02, 0x00,
+    0xce, 0x03, 0x02, 0x00, 0xd0, 0x03, 0x02, 0x00, 0xd2, 0x03, 0x02, 0x00, 0xd4, 0x03, 0x02, 0x00,
+    0xd6, 0x03, 0x02, 0x00, 0xd8, 0x03, 0x02, 0x00, 0xda, 0x03, 0x02, 0x00, 0xdc, 0x03, 0x02, 0x00,
+    0xde, 0x03, 0x02, 0x00, 0xe0, 0x03, 0x02, 0x00, 0xe2, 0x03, 0x02, 0x00, 0xe4, 0x03, 0x02, 0x00,
+    0xe6, 0x03, 0x02, 0x00, 0xe8, 0x03, 0x02, 0x00, 0xea, 0x03, 0x02, 0x00, 0xec, 0x03, 0x02, 0x00,
+    0xee, 0x03, 0x02, 0x00, 0xf0, 0x03, 0x02, 0x00, 0xf2, 0x03, 0x02, 0x00, 0xf4, 0x03, 0x02, 0x00,
+
+    0xf6, 0x03, 0x02, 0x00, 0xf8, 0x03, 0x02, 0x00, 0xfa, 0x03, 0x02, 0x00, 0xfc, 0x03, 0x02, 0x00,
+    0xfe, 0x03, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00,
+    0x06, 0x00, 0x02, 0x00, 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x02, 0x00, 0x0c, 0x00, 0x02, 0x00,
+    0x0e, 0x00, 0x02, 0x00, 0x10, 0x00, 0x02, 0x00, 0x12, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00,
+    0x16, 0x00, 0x02, 0x00, 0x18, 0x00, 0x02, 0x00, 0x1a, 0x00, 0x02, 0x00, 0x1c, 0x00, 0x02, 0x00,
+    0x1e, 0x00, 0x02, 0x00, 0x20, 0x00, 0x02, 0x00, 0x22, 0x00, 0x02, 0x00, 0x24, 0x00, 0x02, 0x00,
+    0x26, 0x00, 0x02, 0x00, 0x28, 0x00, 0x02, 0x00, 0x2a, 0x00, 0x02, 0x00, 0x2c, 0x00, 0x02, 0x00,
+    0x2e, 0x00, 0x02, 0x00, 0x30, 0x00, 0x02, 0x00, 0x32, 0x00, 0x02, 0x00, 0x34, 0x00, 0x02, 0x00,
+    0x36, 0x00, 0x02, 0x00, 0x38, 0x00, 0x02, 0x00, 0x3a, 0x00, 0x02, 0x00, 0x3c, 0x00, 0x02, 0x00,
+    0x3e, 0x00, 0x02, 0x00, 0x40, 0x00, 0x02, 0x00, 0x42, 0x00, 0x02, 0x00, 0x44, 0x00, 0x02, 0x00,
+    0x46, 0x00, 0x02, 0x00, 0x48, 0x00, 0x02, 0x00, 0x4a, 0x00, 0x02, 0x00, 0x4c, 0x00, 0x02, 0x00,
+    0x4e, 0x00, 0x02, 0x00, 0x50, 0x00, 0x02, 0x00, 0x52, 0x00, 0x02, 0x00, 0x54, 0x00, 0x02, 0x00,
+    0x56, 0x00, 0x02, 0x00, 0x58, 0x00, 0x02, 0x00, 0x5a, 0x00, 0x02, 0x00, 0x5c, 0x00, 0x02, 0x00,
+    0x5e, 0x00, 0x02, 0x00, 0x60, 0x00, 0x02, 0x00, 0x62, 0x00, 0x02, 0x00, 0x64, 0x00, 0x02, 0x00,
+    0x66, 0x00, 0x02, 0x00, 0x68, 0x00, 0x02, 0x00, 0x6a, 0x00, 0x02, 0x00, 0x6c, 0x00, 0x02, 0x00,
+    0x6e, 0x00, 0x02, 0x00, 0x70, 0x00, 0x02, 0x00, 0x72, 0x00, 0x02, 0x00, 0x74, 0x00, 0x02, 0x00,
+    0x76, 0x00, 0x02, 0x00, 0x78, 0x00, 0x02, 0x00, 0x7a, 0x00, 0x02, 0x00, 0x7c, 0x00, 0x02, 0x00,
+    0x7e, 0x00, 0x02, 0x00, 0x80, 0x00, 0x02, 0x00, 0x82, 0x00, 0x02, 0x00, 0x84, 0x00, 0x02, 0x00,
+    0x86, 0x00, 0x02, 0x00, 0x88, 0x00, 0x02, 0x00, 0x8a, 0x00, 0x02, 0x00, 0x8c, 0x00, 0x02, 0x00,
+    0x8e, 0x00, 0x02, 0x00, 0x90, 0x00, 0x02, 0x00, 0x92, 0x00, 0x02, 0x00, 0x94, 0x00, 0x02, 0x00,
+    0x96, 0x00, 0x02, 0x00, 0x98, 0x00, 0x02, 0x00, 0x9a, 0x00, 0x02, 0x00, 0x9c, 0x00, 0x02, 0x00,
+    0x9e, 0x00, 0x02, 0x00, 0xa0, 0x00, 0x02, 0x00, 0xa2, 0x00, 0x02, 0x00, 0xa4, 0x00, 0x02, 0x00,
+    0xa6, 0x00, 0x02, 0x00, 0xa8, 0x00, 0x02, 0x00, 0xaa, 0x00, 0x02, 0x00, 0xac, 0x00, 0x02, 0x00,
+    0xae, 0x00, 0x02, 0x00, 0xb0, 0x00, 0x02, 0x00, 0xb2, 0x00, 0x02, 0x00, 0xb4, 0x00, 0x02, 0x00,
+    0xb6, 0x00, 0x02, 0x00, 0xb8, 0x00, 0x02, 0x00, 0xba, 0x00, 0x02, 0x00, 0xbc, 0x00, 0x02, 0x00,
+    0xbe, 0x00, 0x02, 0x00, 0xc0, 0x00, 0x02, 0x00, 0xc2, 0x00, 0x02, 0x00, 0xc4, 0x00, 0x02, 0x00,
+    0xc6, 0x00, 0x02, 0x00, 0xc8, 0x00, 0x02, 0x00, 0xca, 0x00, 0x02, 0x00, 0xcc, 0x00, 0x02, 0x00,
+    0xce, 0x00, 0x02, 0x00, 0xd0, 0x00, 0x02, 0x00, 0xd2, 0x00, 0x02, 0x00, 0xd4, 0x00, 0x02, 0x00,
+    0xd6, 0x00, 0x02, 0x00, 0xd8, 0x00, 0x02, 0x00, 0xda, 0x00, 0x02, 0x00, 0xdc, 0x00, 0x02, 0x00,
+    0xde, 0x00, 0x02, 0x00, 0xe0, 0x00, 0x02, 0x00, 0xe2, 0x00, 0x02, 0x00, 0xe4, 0x00, 0x02, 0x00,
+    0xe6, 0x00, 0x02, 0x00, 0xe8, 0x00, 0x02, 0x00, 0xea, 0x00, 0x02, 0x00, 0xec, 0x00, 0x02, 0x00,
+    0xee, 0x00, 0x02, 0x00, 0xf0, 0x00, 0x02, 0x00, 0xf2, 0x00, 0x02, 0x00, 0xf4, 0x00, 0x02, 0x00,
+
+    0xf6, 0x00, 0x02, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xfa, 0x00, 0x02, 0x00, 0xfc, 0x00, 0x02, 0x00,
+    0xfe, 0x00, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x02, 0x01, 0x02, 0x00, 0x04, 0x01, 0x02, 0x00,
+    0x06, 0x01, 0x02, 0x00, 0x08, 0x01, 0x02, 0x00, 0x0a, 0x01, 0x02, 0x00, 0x0c, 0x01, 0x02, 0x00,
+    0x0e, 0x01, 0x02, 0x00, 0x10, 0x01, 0x02, 0x00, 0x12, 0x01, 0x02, 0x00, 0x14, 0x01, 0x02, 0x00,
+    0x16, 0x01, 0x02, 0x00, 0x18, 0x01, 0x02, 0x00, 0x1a, 0x01, 0x02, 0x00, 0x1c, 0x01, 0x02, 0x00,
+    0x1e, 0x01, 0x02, 0x00, 0x20, 0x01, 0x02, 0x00, 0x22, 0x01, 0x02, 0x00, 0x24, 0x01, 0x02, 0x00,
+    0x26, 0x01, 0x02, 0x00, 0x28, 0x01, 0x02, 0x00, 0x2a, 0x01, 0x02, 0x00, 0x2c, 0x01, 0x02, 0x00,
+    0x2e, 0x01, 0x02, 0x00, 0x30, 0x01, 0x02, 0x00, 0x32, 0x01, 0x02, 0x00, 0x34, 0x01, 0x02, 0x00,
+    0x36, 0x01, 0x02, 0x00, 0x38, 0x01, 0x02, 0x00, 0x3a, 0x01, 0x02, 0x00, 0x3c, 0x01, 0x02, 0x00,
+    0x3e, 0x01, 0x02, 0x00, 0x40, 0x01, 0x02, 0x00, 0x42, 0x01, 0x02, 0x00, 0x44, 0x01, 0x02, 0x00,
+    0x46, 0x01, 0x02, 0x00, 0x48, 0x01, 0x02, 0x00, 0x4a, 0x01, 0x02, 0x00, 0x4c, 0x01, 0x02, 0x00,
+    0x4e, 0x01, 0x02, 0x00, 0x50, 0x01, 0x02, 0x00, 0x52, 0x01, 0x02, 0x00, 0x54, 0x01, 0x02, 0x00,
+    0x56, 0x01, 0x02, 0x00, 0x58, 0x01, 0x02, 0x00, 0x5a, 0x01, 0x02, 0x00, 0x5c, 0x01, 0x02, 0x00,
+    0x5e, 0x01, 0x02, 0x00, 0x60, 0x01, 0x02, 0x00, 0x62, 0x01, 0x02, 0x00, 0x64, 0x01, 0x02, 0x00,
+    0x66, 0x01, 0x02, 0x00, 0x68, 0x01, 0x02, 0x00, 0x6a, 0x01, 0x02, 0x00, 0x6c, 0x01, 0x02, 0x00,
+    0x6e, 0x01, 0x02, 0x00, 0x70, 0x01, 0x02, 0x00, 0x72, 0x01, 0x02, 0x00, 0x74, 0x01, 0x02, 0x00,
+    0x76, 0x01, 0x02, 0x00, 0x78, 0x01, 0x02, 0x00, 0x7a, 0x01, 0x02, 0x00, 0x7c, 0x01, 0x02, 0x00,
+    0x7e, 0x01, 0x02, 0x00, 0x80, 0x01, 0x02, 0x00, 0x82, 0x01, 0x02, 0x00, 0x84, 0x01, 0x02, 0x00,
+    0x86, 0x01, 0x02, 0x00, 0x88, 0x01, 0x02, 0x00, 0x8a, 0x01, 0x02, 0x00, 0x8c, 0x01, 0x02, 0x00,
+    0x8e, 0x01, 0x02, 0x00, 0x90, 0x01, 0x02, 0x00, 0x92, 0x01, 0x02, 0x00, 0x94, 0x01, 0x02, 0x00,
+    0x96, 0x01, 0x02, 0x00, 0x98, 0x01, 0x02, 0x00, 0x9a, 0x01, 0x02, 0x00, 0x9c, 0x01, 0x02, 0x00,
+    0x9e, 0x01, 0x02, 0x00, 0xa0, 0x01, 0x02, 0x00, 0xa2, 0x01, 0x02, 0x00, 0xa4, 0x01, 0x02, 0x00,
+    0xa6, 0x01, 0x02, 0x00, 0xa8, 0x01, 0x02, 0x00, 0xaa, 0x01, 0x02, 0x00, 0xac, 0x01, 0x02, 0x00,
+    0xae, 0x01, 0x02, 0x00, 0xb0, 0x01, 0x02, 0x00, 0xb2, 0x01, 0x02, 0x00, 0xb4, 0x01, 0x02, 0x00,
+    0xb6, 0x01, 0x02, 0x00, 0xb8, 0x01, 0x02, 0x00, 0xba, 0x01, 0x02, 0x00, 0xbc, 0x01, 0x02, 0x00,
+    0xbe, 0x01, 0x02, 0x00, 0xc0, 0x01, 0x02, 0x00, 0xc2, 0x01, 0x02, 0x00, 0xc4, 0x01, 0x02, 0x00,
+    0xc6, 0x01, 0x02, 0x00, 0xc8, 0x01, 0x02, 0x00, 0xca, 0x01, 0x02, 0x00, 0xcc, 0x01, 0x02, 0x00,
+    0xce, 0x01, 0x02, 0x00, 0xd0, 0x01, 0x02, 0x00, 0xd2, 0x01, 0x02, 0x00, 0xd4, 0x01, 0x02, 0x00,
+    0xd6, 0x01, 0x02, 0x00, 0xd8, 0x01, 0x02, 0x00, 0xda, 0x01, 0x02, 0x00, 0xdc, 0x01, 0x02, 0x00,
+    0xde, 0x01, 0x02, 0x00, 0xe0, 0x01, 0x02, 0x00, 0xe2, 0x01, 0x02, 0x00, 0xe4, 0x01, 0x02, 0x00,
+    0xe6, 0x01, 0x02, 0x00, 0xe8, 0x01, 0x02, 0x00, 0xea, 0x01, 0x02, 0x00, 0xec, 0x01, 0x02, 0x00,
+    0xee, 0x01, 0x02, 0x00, 0xf0, 0x01, 0x02, 0x00, 0xf2, 0x01, 0x02, 0x00, 0xf4, 0x01, 0x02, 0x00,
+
+    0xf6, 0x01, 0x02, 0x00, 0xf8, 0x01, 0x02, 0x00, 0xfa, 0x01, 0x02, 0x00, 0xfc, 0x01, 0x02, 0x00,
+    0xfe, 0x01, 0x02, 0x00, 0x00, 0x02, 0x02, 0x00, 0x02, 0x02, 0x02, 0x00, 0x04, 0x02, 0x02, 0x00,
+    0x06, 0x02, 0x02, 0x00, 0x08, 0x02, 0x02, 0x00, 0x0a, 0x02, 0x02, 0x00, 0x0c, 0x02, 0x02, 0x00,
+    0x0e, 0x02, 0x02, 0x00, 0x10, 0x02, 0x02, 0x00, 0x12, 0x02, 0x02, 0x00, 0x14, 0x02, 0x02, 0x00,
+    0x16, 0x02, 0x02, 0x00, 0x18, 0x02, 0x02, 0x00, 0x1a, 0x02, 0x02, 0x00, 0x1c, 0x02, 0x02, 0x00,
+    0x1e, 0x02, 0x02, 0x00, 0x20, 0x02, 0x02, 0x00, 0x22, 0x02, 0x02, 0x00, 0x24, 0x02, 0x02, 0x00,
+    0x26, 0x02, 0x02, 0x00, 0x28, 0x02, 0x02, 0x00, 0x2a, 0x02, 0x02, 0x00, 0x2c, 0x02, 0x02, 0x00,
+    0x2e, 0x02, 0x02, 0x00, 0x30, 0x02, 0x02, 0x00, 0x32, 0x02, 0x02, 0x00, 0x34, 0x02, 0x02, 0x00,
+    0x36, 0x02, 0x02, 0x00, 0x38, 0x02, 0x02, 0x00, 0x3a, 0x02, 0x02, 0x00, 0x3c, 0x02, 0x02, 0x00,
+    0x3e, 0x02, 0x02, 0x00, 0x40, 0x02, 0x02, 0x00, 0x42, 0x02, 0x02, 0x00, 0x44, 0x02, 0x02, 0x00,
+    0x46, 0x02, 0x02, 0x00, 0x48, 0x02, 0x02, 0x00, 0x4a, 0x02, 0x02, 0x00, 0x4c, 0x02, 0x02, 0x00,
+    0x4e, 0x02, 0x02, 0x00, 0x50, 0x02, 0x02, 0x00, 0x52, 0x02, 0x02, 0x00, 0x54, 0x02, 0x02, 0x00,
+    0x56, 0x02, 0x02, 0x00, 0x58, 0x02, 0x02, 0x00, 0x5a, 0x02, 0x02, 0x00, 0x5c, 0x02, 0x02, 0x00,
+    0x5e, 0x02, 0x02, 0x00, 0x60, 0x02, 0x02, 0x00, 0x62, 0x02, 0x02, 0x00, 0x64, 0x02, 0x02, 0x00,
+    0x66, 0x02, 0x02, 0x00, 0x68, 0x02, 0x02, 0x00, 0x6a, 0x02, 0x02, 0x00, 0x6c, 0x02, 0x02, 0x00,
+    0x6e, 0x02, 0x02, 0x00, 0x70, 0x02, 0x02, 0x00, 0x72, 0x02, 0x02, 0x00, 0x74, 0x02, 0x02, 0x00,
+    0x76, 0x02, 0x02, 0x00, 0x78, 0x02, 0x02, 0x00, 0x7a, 0x02, 0x02, 0x00, 0x7c, 0x02, 0x02, 0x00,
+    0x7e, 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x00, 0x82, 0x02, 0x02, 0x00, 0x84, 0x02, 0x02, 0x00,
+    0x86, 0x02, 0x02, 0x00, 0x88, 0x02, 0x02, 0x00, 0x8a, 0x02, 0x02, 0x00, 0x8c, 0x02, 0x02, 0x00,
+    0x8e, 0x02, 0x02, 0x00, 0x90, 0x02, 0x02, 0x00, 0x92, 0x02, 0x02, 0x00, 0x94, 0x02, 0x02, 0x00,
+    0x96, 0x02, 0x02, 0x00, 0x98, 0x02, 0x02, 0x00, 0x9a, 0x02, 0x02, 0x00, 0x9c, 0x02, 0x02, 0x00,
+    0x9e, 0x02, 0x02, 0x00, 0xa0, 0x02, 0x02, 0x00, 0xa2, 0x02, 0x02, 0x00, 0xa4, 0x02, 0x02, 0x00,
+    0xa6, 0x02, 0x02, 0x00, 0xa8, 0x02, 0x02, 0x00, 0xaa, 0x02, 0x02, 0x00, 0xac, 0x02, 0x02, 0x00,
+    0xae, 0x02, 0x02, 0x00, 0xb0, 0x02, 0x02, 0x00, 0xb2, 0x02, 0x02, 0x00, 0xb4, 0x02, 0x02, 0x00,
+    0xb6, 0x02, 0x02, 0x00, 0xb8, 0x02, 0x02, 0x00, 0xba, 0x02, 0x02, 0x00, 0xbc, 0x02, 0x02, 0x00,
+    0xbe, 0x02, 0x02, 0x00, 0xc0, 0x02, 0x02, 0x00, 0xc2, 0x02, 0x02, 0x00, 0xc4, 0x02, 0x02, 0x00,
+    0xc6, 0x02, 0x02, 0x00, 0xc8, 0x02, 0x02, 0x00, 0xca, 0x02, 0x02, 0x00, 0xcc, 0x02, 0x02, 0x00,
+    0xce, 0x02, 0x02, 0x00, 0xd0, 0x02, 0x02, 0x00, 0xd2, 0x02, 0x02, 0x00, 0xd4, 0x02, 0x02, 0x00,
+    0xd6, 0x02, 0x02, 0x00, 0xd8, 0x02, 0x02, 0x00, 0xda, 0x02, 0x02, 0x00, 0xdc, 0x02, 0x02, 0x00,
+    0xde, 0x02, 0x02, 0x00, 0xe0, 0x02, 0x02, 0x00, 0xe2, 0x02, 0x02, 0x00, 0xe4, 0x02, 0x02, 0x00,
+    0xe6, 0x02, 0x02, 0x00, 0xe8, 0x02, 0x02, 0x00, 0xea, 0x02, 0x02, 0x00, 0xec, 0x02, 0x02, 0x00,
+    0xee, 0x02, 0x02, 0x00, 0xf0, 0x02, 0x02, 0x00, 0xf2, 0x02, 0x02, 0x00, 0xf4, 0x02, 0x02, 0x00,
+
+    0xf6, 0x02, 0x02, 0x00, 0xf8, 0x02, 0x02, 0x00, 0xfa, 0x02, 0x02, 0x00, 0xfc, 0x02, 0x02, 0x00,
+    0xfe, 0x02, 0x02, 0x00, 0x00, 0x03, 0x02, 0x00, 0x02, 0x03, 0x02, 0x00, 0x04, 0x03, 0x02, 0x00,
+    0x06, 0x03, 0x02, 0x00, 0x08, 0x03, 0x02, 0x00, 0x0a, 0x03, 0x02, 0x00, 0x0c, 0x03, 0x02, 0x00,
+    0x0e, 0x03, 0x02, 0x00, 0x10, 0x03, 0x02, 0x00, 0x12, 0x03, 0x02, 0x00, 0x14, 0x03, 0x02, 0x00,
+    0x16, 0x03, 0x02, 0x00, 0x18, 0x03, 0x02, 0x00, 0x1a, 0x03, 0x02, 0x00, 0x1c, 0x03, 0x02, 0x00,
+    0x1e, 0x03, 0x02, 0x00, 0x20, 0x03, 0x02, 0x00, 0x22, 0x03, 0x02, 0x00, 0x24, 0x03, 0x02, 0x00,
+    0x26, 0x03, 0x02, 0x00, 0x28, 0x03, 0x02, 0x00, 0x2a, 0x03, 0x02, 0x00, 0x2c, 0x03, 0x02, 0x00,
+    0x2e, 0x03, 0x02, 0x00, 0x30, 0x03, 0x02, 0x00, 0x32, 0x03, 0x02, 0x00, 0x34, 0x03, 0x02, 0x00,
+    0x36, 0x03, 0x02, 0x00, 0x38, 0x03, 0x02, 0x00, 0x3a, 0x03, 0x02, 0x00, 0x3c, 0x03, 0x02, 0x00,
+    0x3e, 0x03, 0x02, 0x00, 0x40, 0x03, 0x02, 0x00, 0x42, 0x03, 0x02, 0x00, 0x44, 0x03, 0x02, 0x00,
+    0x46, 0x03, 0x02, 0x00, 0x48, 0x03, 0x02, 0x00, 0x4a, 0x03, 0x02, 0x00, 0x4c, 0x03, 0x02, 0x00,
+    0x4e, 0x03, 0x02, 0x00, 0x50, 0x03, 0x02, 0x00, 0x52, 0x03, 0x02, 0x00, 0x54, 0x03, 0x02, 0x00,
+    0x56, 0x03, 0x02, 0x00, 0x58, 0x03, 0x02, 0x00, 0x5a, 0x03, 0x02, 0x00, 0x5c, 0x03, 0x02, 0x00,
+    0x5e, 0x03, 0x02, 0x00, 0x60, 0x03, 0x02, 0x00, 0x62, 0x03, 0x02, 0x00, 0x64, 0x03, 0x02, 0x00,
+    0x66, 0x03, 0x02, 0x00, 0x68, 0x03, 0x02, 0x00, 0x6a, 0x03, 0x02, 0x00, 0x6c, 0x03, 0x02, 0x00,
+    0x6e, 0x03, 0x02, 0x00, 0x70, 0x03, 0x02, 0x00, 0x72, 0x03, 0x02, 0x00, 0x74, 0x03, 0x02, 0x00,
+    0x76, 0x03, 0x02, 0x00, 0x78, 0x03, 0x02, 0x00, 0x7a, 0x03, 0x02, 0x00, 0x7c, 0x03, 0x02, 0x00,
+    0x7e, 0x03, 0x02, 0x00, 0x80, 0x03, 0x02, 0x00, 0x82, 0x03, 0x02, 0x00, 0x84, 0x03, 0x02, 0x00,
+    0x86, 0x03, 0x02, 0x00, 0x88, 0x03, 0x02, 0x00, 0x8a, 0x03, 0x02, 0x00, 0x8c, 0x03, 0x02, 0x00,
+    0x8e, 0x03, 0x02, 0x00, 0x90, 0x03, 0x02, 0x00, 0x92, 0x03, 0x02, 0x00, 0x94, 0x03, 0x02, 0x00,
+    0x96, 0x03, 0x02, 0x00, 0x98, 0x03, 0x02, 0x00, 0x9a, 0x03, 0x02, 0x00, 0x9c, 0x03, 0x02, 0x00,
+    0x9e, 0x03, 0x02, 0x00, 0xa0, 0x03, 0x02, 0x00, 0xa2, 0x03, 0x02, 0x00, 0xa4, 0x03, 0x02, 0x00,
+    0xa6, 0x03, 0x02, 0x00, 0xa8, 0x03, 0x02, 0x00, 0xaa, 0x03, 0x02, 0x00, 0xac, 0x03, 0x02, 0x00,
+    0xae, 0x03, 0x02, 0x00, 0xb0, 0x03, 0x02, 0x00, 0xb2, 0x03, 0x02, 0x00, 0xb4, 0x03, 0x02, 0x00,
+    0xb6, 0x03, 0x02, 0x00, 0xb8, 0x03, 0x02, 0x00, 0xba, 0x03, 0x02, 0x00, 0xbc, 0x03, 0x02, 0x00,
+    0xbe, 0x03, 0x02, 0x00, 0xc0, 0x03, 0x02, 0x00, 0xc2, 0x03, 0x02, 0x00, 0xc4, 0x03, 0x02, 0x00,
+    0xc6, 0x03, 0x02, 0x00, 0xc8, 0x03, 0x02, 0x00, 0xca, 0x03, 0x02, 0x00, 0xcc, 0x03, 0x02, 0x00,
+    0xce, 0x03, 0x02, 0x00, 0xd0, 0x03, 0x02, 0x00, 0xd2, 0x03, 0x02, 0x00, 0xd4, 0x03, 0x02, 0x00,
+    0xd6, 0x03, 0x02, 0x00, 0xd8, 0x03, 0x02, 0x00, 0xda, 0x03, 0x02, 0x00, 0xdc, 0x03, 0x02, 0x00,
+    0xde, 0x03, 0x02, 0x00, 0xe0, 0x03, 0x02, 0x00, 0xe2, 0x03, 0x02, 0x00, 0xe4, 0x03, 0x02, 0x00,
+    0xe6, 0x03, 0x02, 0x00, 0xe8, 0x03, 0x02, 0x00, 0xea, 0x03, 0x02, 0x00, 0xec, 0x03, 0x02, 0x00,
+    0xee, 0x03, 0x02, 0x00, 0xf0, 0x03, 0x02, 0x00, 0xf2, 0x03, 0x02, 0x00, 0xf4, 0x03, 0x02, 0x00,
+
+    0xf6, 0x03, 0x02, 0x00, 0xf8, 0x03, 0x02, 0x00, 0xfa, 0x03, 0x02, 0x00, 0xfc, 0x03, 0x02, 0x00,
+    0xfe, 0x03, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x02, 0x00, 0x04, 0x00, 0x02, 0x00,
+    0x06, 0x00, 0x02, 0x00, 0x08, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x02, 0x00, 0x0c, 0x00, 0x02, 0x00,
+    0x0e, 0x00, 0x02, 0x00, 0x10, 0x00, 0x02, 0x00, 0x12, 0x00, 0x02, 0x00, 0x14, 0x00, 0x02, 0x00,
+    0x16, 0x00, 0x02, 0x00, 0x18, 0x00, 0x02, 0x00, 0x1a, 0x00, 0x02, 0x00, 0x1c, 0x00, 0x02, 0x00,
+    0x1e, 0x00, 0x02, 0x00, 0x20, 0x00, 0x02, 0x00, 0x22, 0x00, 0x02, 0x00, 0x24, 0x00, 0x02, 0x00,
+    0x26, 0x00, 0x02, 0x00, 0x28, 0x00, 0x02, 0x00, 0x2a, 0x00, 0x02, 0x00, 0x2c, 0x00, 0x02, 0x00,
+    0x2e, 0x00, 0x02, 0x00, 0x30, 0x00, 0x02, 0x00, 0x32, 0x00, 0x02, 0x00, 0x34, 0x00, 0x02, 0x00,
+    0x36, 0x00, 0x02, 0x00, 0x38, 0x00, 0x02, 0x00, 0x3a, 0x00, 0x02, 0x00, 0x3c, 0x00, 0x02, 0x00,
+    0x3e, 0x00, 0x02, 0x00, 0x40, 0x00, 0x02, 0x00, 0x42, 0x00, 0x02, 0x00, 0x44, 0x00, 0x02, 0x00,
+    0x46, 0x00, 0x02, 0x00, 0x48, 0x00, 0x02, 0x00, 0x4a, 0x00, 0x02, 0x00, 0x4c, 0x00, 0x02, 0x00,
+    0x4e, 0x00, 0x02, 0x00, 0x50, 0x00, 0x02, 0x00, 0x52, 0x00, 0x02, 0x00, 0x54, 0x00, 0x02, 0x00,
+    0x56, 0x00, 0x02, 0x00, 0x58, 0x00, 0x02, 0x00, 0x5a, 0x00, 0x02, 0x00, 0x5c, 0x00, 0x02, 0x00,
+    0x5e, 0x00, 0x02, 0x00, 0x60, 0x00, 0x02, 0x00, 0x62, 0x00, 0x02, 0x00, 0x64, 0x00, 0x02, 0x00,
+    0x66, 0x00, 0x02, 0x00, 0x68, 0x00, 0x02, 0x00, 0x6a, 0x00, 0x02, 0x00, 0x6c, 0x00, 0x02, 0x00,
+    0x6e, 0x00, 0x02, 0x00, 0x70, 0x00, 0x02, 0x00, 0x72, 0x00, 0x02, 0x00, 0x74, 0x00, 0x02, 0x00,
+    0x76, 0x00, 0x02, 0x00, 0x78, 0x00, 0x02, 0x00, 0x7a, 0x00, 0x02, 0x00, 0x7c, 0x00, 0x02, 0x00,
+    0x7e, 0x00, 0x02, 0x00, 0x80, 0x00, 0x02, 0x00, 0x82, 0x00, 0x02, 0x00, 0x84, 0x00, 0x02, 0x00,
+    0x86, 0x00, 0x02, 0x00, 0x88, 0x00, 0x02, 0x00, 0x8a, 0x00, 0x02, 0x00, 0x8c, 0x00, 0x02, 0x00,
+    0x8e, 0x00, 0x02, 0x00, 0x90, 0x00, 0x02, 0x00, 0x92, 0x00, 0x02, 0x00, 0x94, 0x00, 0x02, 0x00,
+    0x96, 0x00, 0x02, 0x00, 0x98, 0x00, 0x02, 0x00, 0x9a, 0x00, 0x02, 0x00, 0x9c, 0x00, 0x02, 0x00,
+    0x9e, 0x00, 0x02, 0x00, 0xa0, 0x00, 0x02, 0x00, 0xa2, 0x00, 0x02, 0x00, 0xa4, 0x00, 0x02, 0x00,
+    0xa6, 0x00, 0x02, 0x00, 0xa8, 0x00, 0x02, 0x00, 0xaa, 0x00, 0x02, 0x00, 0xac, 0x00, 0x02, 0x00,
+    0xae, 0x00, 0x02, 0x00, 0xb0, 0x00, 0x02, 0x00, 0xb2, 0x00, 0x02, 0x00, 0xb4, 0x00, 0x02, 0x00,
+    0xb6, 0x00, 0x02, 0x00, 0xb8, 0x00, 0x02, 0x00, 0xba, 0x00, 0x02, 0x00, 0xbc, 0x00, 0x02, 0x00,
+    0xbe, 0x00, 0x02, 0x00, 0xc0, 0x00, 0x02, 0x00, 0xc2, 0x00, 0x02, 0x00, 0xc4, 0x00, 0x02, 0x00,
+    0xc6, 0x00, 0x02, 0x00, 0xc8, 0x00, 0x02, 0x00, 0xca, 0x00, 0x02, 0x00, 0xcc, 0x00, 0x02, 0x00,
+    0xce, 0x00, 0x02, 0x00, 0xd0, 0x00, 0x02, 0x00, 0xd2, 0x00, 0x02, 0x00, 0xd4, 0x00, 0x02, 0x00,
+    0xd6, 0x00, 0x02, 0x00, 0xd8, 0x00, 0x02, 0x00, 0xda, 0x00, 0x02, 0x00, 0xdc, 0x00, 0x02, 0x00,
+    0xde, 0x00, 0x02, 0x00, 0xe0, 0x00, 0x02, 0x00, 0xe2, 0x00, 0x02, 0x00, 0xe4, 0x00, 0x02, 0x00,
+    0xe6, 0x00, 0x02, 0x00, 0xe8, 0x00, 0x02, 0x00, 0xea, 0x00, 0x02, 0x00, 0xec, 0x00, 0x02, 0x00,
+    0xee, 0x00, 0x02, 0x00, 0xf0, 0x00, 0x02, 0x00, 0xf2, 0x00, 0x02, 0x00, 0xf4, 0x00, 0x02, 0x00,
+
+    0xf6, 0x00, 0x02, 0x00, 0xf8, 0x00, 0x02, 0x00, 0xfa, 0x00, 0x02, 0x00, 0xfc, 0x00, 0x02, 0x00,
+    0xfe, 0x00, 0x02, 0x00, 0x00, 0x01, 0x02, 0x00, 0x02, 0x01, 0x02, 0x00, 0x04, 0x01, 0x02, 0x00,
+    0x06, 0x01, 0x02, 0x00, 0x08, 0x01, 0x02, 0x00, 0x0a, 0x01, 0x02, 0x00, 0x0c, 0x01, 0x02, 0x00,
+    0x0e, 0x01, 0x02, 0x00, 0x10, 0x01, 0x02, 0x00, 0x12, 0x01, 0x02, 0x00, 0x14, 0x01, 0x02, 0x00,
+    0x16, 0x01, 0x02, 0x00, 0x18, 0x01, 0x02, 0x00, 0x1a, 0x01, 0x02, 0x00, 0x1c, 0x01, 0x02, 0x00,
+    0x1e, 0x01, 0x02, 0x00, 0x20, 0x01, 0x02, 0x00, 0x22, 0x01, 0x02, 0x00, 0x24, 0x01, 0x02, 0x00,
+    0x26, 0x01, 0x02, 0x00, 0x28, 0x01, 0x02, 0x00, 0x2a, 0x01, 0x02, 0x00, 0x2c, 0x01, 0x02, 0x00,
+    0x2e, 0x01, 0x02, 0x00, 0x30, 0x01, 0x02, 0x00, 0x32, 0x01, 0x02, 0x00, 0x34, 0x01, 0x02, 0x00,
+    0x36, 0x01, 0x02, 0x00, 0x38, 0x01, 0x02, 0x00, 0x3a, 0x01, 0x02, 0x00, 0x3c, 0x01, 0x02, 0x00,
+    0x3e, 0x01, 0x02, 0x00, 0x40, 0x01, 0x02, 0x00, 0x42, 0x01, 0x02, 0x00, 0x44, 0x01, 0x02, 0x00,
+    0x46, 0x01, 0x02, 0x00, 0x48, 0x01, 0x02, 0x00, 0x4a, 0x01, 0x02, 0x00, 0x4c, 0x01, 0x02, 0x00,
+    0x4e, 0x01, 0x02, 0x00, 0x50, 0x01, 0x02, 0x00, 0x52, 0x01, 0x02, 0x00, 0x54, 0x01, 0x02, 0x00,
+    0x56, 0x01, 0x02, 0x00, 0x58, 0x01, 0x02, 0x00, 0x5a, 0x01, 0x02, 0x00, 0x5c, 0x01, 0x02, 0x00,
+    0x5e, 0x01, 0x02, 0x00, 0x60, 0x01, 0x02, 0x00, 0x62, 0x01, 0x02, 0x00, 0x64, 0x01, 0x02, 0x00,
+    0x66, 0x01, 0x02, 0x00, 0x68, 0x01, 0x02, 0x00, 0x6a, 0x01, 0x02, 0x00, 0x6c, 0x01, 0x02, 0x00,
+    0x6e, 0x01, 0x02, 0x00, 0x70, 0x01, 0x02, 0x00, 0x72, 0x01, 0x02, 0x00, 0x74, 0x01, 0x02, 0x00,
+    0x76, 0x01, 0x02, 0x00, 0x78, 0x01, 0x02, 0x00, 0x7a, 0x01, 0x02, 0x00, 0x7c, 0x01, 0x02, 0x00,
+    0x7e, 0x01, 0x02, 0x00, 0x80, 0x01, 0x02, 0x00, 0x82, 0x01, 0x02, 0x00, 0x84, 0x01, 0x02, 0x00,
+    0x86, 0x01, 0x02, 0x00, 0x88, 0x01, 0x02, 0x00, 0x8a, 0x01, 0x02, 0x00, 0x8c, 0x01, 0x02, 0x00,
+    0x8e, 0x01, 0x02, 0x00, 0x90, 0x01, 0x02, 0x00, 0x92, 0x01, 0x02, 0x00, 0x94, 0x01, 0x02, 0x00,
+    0x96, 0x01, 0x02, 0x00, 0x98, 0x01, 0x02, 0x00, 0x9a, 0x01, 0x02, 0x00, 0x9c, 0x01, 0x02, 0x00,
+    0x9e, 0x01, 0x02, 0x00, 0xa0, 0x01, 0x02, 0x00, 0xa2, 0x01, 0x02, 0x00, 0xa4, 0x01, 0x02, 0x00,
+    0xa6, 0x01, 0x02, 0x00, 0xa8, 0x01, 0x02, 0x00, 0xaa, 0x01, 0x02, 0x00, 0xac, 0x01, 0x02, 0x00,
+    0xae, 0x01, 0x02, 0x00, 0xb0, 0x01, 0x02, 0x00, 0xb2, 0x01, 0x02, 0x00, 0xb4, 0x01, 0x02, 0x00,
+    0xb6, 0x01, 0x02, 0x00, 0xb8, 0x01, 0x02, 0x00, 0xba, 0x01, 0x02, 0x00, 0xbc, 0x01, 0x02, 0x00,
+    0xbe, 0x01, 0x02, 0x00, 0xc0, 0x01, 0x02, 0x00, 0xc2, 0x01, 0x02, 0x00, 0xc4, 0x01, 0x02, 0x00,
+    0xc6, 0x01, 0x02, 0x00, 0xc8, 0x01, 0x02, 0x00, 0xca, 0x01, 0x02, 0x00, 0xcc, 0x01, 0x02, 0x00,
+    0xce, 0x01, 0x02, 0x00, 0xd0, 0x01, 0x02, 0x00, 0xd2, 0x01, 0x02, 0x00, 0xd4, 0x01, 0x02, 0x00,
+    0xd6, 0x01, 0x02, 0x00, 0xd8, 0x01, 0x02, 0x00, 0xda, 0x01, 0x02, 0x00, 0xdc, 0x01, 0x02, 0x00,
+    0xde, 0x01, 0x02, 0x00, 0xe0, 0x01, 0x02, 0x00, 0xe2, 0x01, 0x02, 0x00, 0xe4, 0x01, 0x02, 0x00,
+    0xe6, 0x01, 0x02, 0x00, 0xe8, 0x01, 0x02, 0x00, 0xea, 0x01, 0x02, 0x00, 0xec, 0x01, 0x02, 0x00,
+    0xee, 0x01, 0x02, 0x00, 0xf0, 0x01, 0x02, 0x00, 0xf2, 0x01, 0x02, 0x00, 0xf4, 0x01, 0x02, 0x00,
+
+    0xf6, 0x01, 0x02, 0x00, 0xf8, 0x01, 0x02, 0x00, 0xfa, 0x01, 0x02, 0x00, 0xfc, 0x01, 0x02, 0x00,
+    0xfe, 0x01, 0x02, 0x00, 0x00, 0x02, 0x02, 0x00, 0x02, 0x02, 0x02, 0x00, 0x04, 0x02, 0x02, 0x00,
+    0x06, 0x02, 0x02, 0x00, 0x08, 0x02, 0x02, 0x00, 0x0a, 0x02, 0x02, 0x00, 0x0c, 0x02, 0x02, 0x00,
+    0x0e, 0x02, 0x02, 0x00, 0x10, 0x02, 0x02, 0x00, 0x12, 0x02, 0x02, 0x00, 0x14, 0x02, 0x02, 0x00,
+    0x16, 0x02, 0x02, 0x00, 0x18, 0x02, 0x02, 0x00, 0x1a, 0x02, 0x02, 0x00, 0x1c, 0x02, 0x02, 0x00,
+    0x1e, 0x02, 0x02, 0x00, 0x20, 0x02, 0x02, 0x00, 0x22, 0x02, 0x02, 0x00, 0x24, 0x02, 0x02, 0x00,
+    0x26, 0x02, 0x02, 0x00, 0x28, 0x02, 0x02, 0x00, 0x2a, 0x02, 0x02, 0x00, 0x2c, 0x02, 0x02, 0x00,
+    0x2e, 0x02, 0x02, 0x00, 0x30, 0x02, 0x02, 0x00, 0x32, 0x02, 0x02, 0x00, 0x34, 0x02, 0x02, 0x00,
+    0x36, 0x02, 0x02, 0x00, 0x38, 0x02, 0x02, 0x00, 0x3a, 0x02, 0x02, 0x00, 0x3c, 0x02, 0x02, 0x00,
+    0x3e, 0x02, 0x02, 0x00, 0x40, 0x02, 0x02, 0x00, 0x42, 0x02, 0x02, 0x00, 0x44, 0x02, 0x02, 0x00,
+    0x46, 0x02, 0x02, 0x00, 0x48, 0x02, 0x02, 0x00, 0x4a, 0x02, 0x02, 0x00, 0x4c, 0x02, 0x02, 0x00,
+    0x4e, 0x02, 0x02, 0x00, 0x50, 0x02, 0x02, 0x00, 0x52, 0x02, 0x02, 0x00, 0x54, 0x02, 0x02, 0x00,
+    0x56, 0x02, 0x02, 0x00, 0x58, 0x02, 0x02, 0x00, 0x5a, 0x02, 0x02, 0x00, 0x5c, 0x02, 0x02, 0x00,
+    0x5e, 0x02, 0x02, 0x00, 0x60, 0x02, 0x02, 0x00, 0x62, 0x02, 0x02, 0x00, 0x64, 0x02, 0x02, 0x00,
+    0x66, 0x02, 0x02, 0x00, 0x68, 0x02, 0x02, 0x00, 0x6a, 0x02, 0x02, 0x00, 0x6c, 0x02, 0x02, 0x00,
+    0x6e, 0x02, 0x02, 0x00, 0x70, 0x02, 0x02, 0x00, 0x72, 0x02, 0x02, 0x00, 0x74, 0x02, 0x02, 0x00,
+    0x76, 0x02, 0x02, 0x00, 0x78, 0x02, 0x02, 0x00, 0x7a, 0x02, 0x02, 0x00, 0x7c, 0x02, 0x02, 0x00,
+    0x7e, 0x02, 0x02, 0x00, 0x80, 0x02, 0x02, 0x00, 0x82, 0x02, 0x02, 0x00, 0x84, 0x02, 0x02, 0x00,
+    0x86, 0x02, 0x02, 0x00, 0x88, 0x02, 0x02, 0x00, 0x8a, 0x02, 0x02, 0x00, 0x8c, 0x02, 0x02, 0x00,
+    0x8e, 0x02, 0x02, 0x00, 0x90, 0x02, 0x02, 0x00, 0x92, 0x02, 0x02, 0x00, 0x94, 0x02, 0x02, 0x00,
+    0x96, 0x02, 0x02, 0x00, 0x98, 0x02, 0x02, 0x00, 0x9a, 0x02, 0x02, 0x00, 0x9c, 0x02, 0x02, 0x00,
+    0x9e, 0x02, 0x02, 0x00, 0xa0, 0x02, 0x02, 0x00, 0xa2, 0x02, 0x02, 0x00, 0xa4, 0x02, 0x02, 0x00,
+    0xa6, 0x02, 0x02, 0x00, 0xa8, 0x02, 0x02, 0x00, 0xaa, 0x02, 0x02, 0x00, 0xac, 0x02, 0x02, 0x00,
+    0xae, 0x02, 0x02, 0x00, 0xb0, 0x02, 0x02, 0x00, 0xb2, 0x02, 0x02, 0x00, 0xb4, 0x02, 0x02, 0x00,
+    0xb6, 0x02, 0x02, 0x00, 0xb8, 0x02, 0x02, 0x00, 0xba, 0x02, 0x02, 0x00, 0xbc, 0x02, 0x02, 0x00,
+    0xbe, 0x02, 0x02, 0x00, 0xc0, 0x02, 0x02, 0x00, 0xc2, 0x02, 0x02, 0x00, 0xc4, 0x02, 0x02, 0x00,
+    0xc6, 0x02, 0x02, 0x00, 0xc8, 0x02, 0x02, 0x00, 0xca, 0x02, 0x02, 0x00, 0xcc, 0x02, 0x02, 0x00,
+    0xce, 0x02, 0x02, 0x00, 0xd0, 0x02, 0x02, 0x00, 0xd2, 0x02, 0x02, 0x00, 0xd4, 0x02, 0x02, 0x00,
+    0xd6, 0x02, 0x02, 0x00, 0xd8, 0x02, 0x02, 0x00, 0xda, 0x02, 0x02, 0x00, 0xdc, 0x02, 0x02, 0x00,
+    0xde, 0x02, 0x02, 0x00, 0xe0, 0x02, 0x02, 0x00, 0xe2, 0x02, 0x02, 0x00, 0xe4, 0x02, 0x02, 0x00,
+    0xe6, 0x02, 0x02, 0x00, 0xe8, 0x02, 0x02, 0x00, 0xea, 0x02, 0x02, 0x00, 0xec, 0x02, 0x02, 0x00,
+    0xee, 0x02, 0x02, 0x00, 0xf0, 0x02, 0x02, 0x00, 0xf2, 0x02, 0x02, 0x00, 0xf4, 0x02, 0x02, 0x00,
+
+    0xf6, 0x02, 0x02, 0x00, 0xf8, 0x02, 0x02, 0x00, 0xfa, 0x02, 0x02, 0x00, 0xfc, 0x02, 0x02, 0x00,
+    0xfe, 0x02, 0x02, 0x00, 0x00, 0x03, 0x02, 0x00, 0x02, 0x03, 0x02, 0x00, 0x04, 0x03, 0x02, 0x00,
+    0x06, 0x03, 0x02, 0x00, 0x08, 0x03, 0x02, 0x00, 0x0a, 0x03, 0x02, 0x00, 0x0c, 0x03, 0x02, 0x00,
+    0x0e, 0x03, 0x02, 0x00, 0x10, 0x03, 0x02, 0x00, 0x12, 0x03, 0x02, 0x00, 0x14, 0x03, 0x02, 0x00,
+    0x16, 0x03, 0x02, 0x00, 0x18, 0x03, 0x02, 0x00, 0x1a, 0x03, 0x02, 0x00, 0x1c, 0x03, 0x02, 0x00,
+    0x1e, 0x03, 0x02, 0x00, 0x20, 0x03, 0x02, 0x00, 0x22, 0x03, 0x02, 0x00, 0x24, 0x03, 0x02, 0x00,
+    0x26, 0x03, 0x02, 0x00, 0x28, 0x03, 0x02, 0x00, 0x2a, 0x03, 0x02, 0x00, 0x2c, 0x03, 0x02, 0x00,
+    0x2e, 0x03, 0x02, 0x00, 0x30, 0x03, 0x02, 0x00, 0x32, 0x03, 0x02, 0x00, 0x34, 0x03, 0x02, 0x00,
+    0x36, 0x03, 0x02, 0x00, 0x38, 0x03, 0x02, 0x00, 0x3a, 0x03, 0x02, 0x00, 0x3c, 0x03, 0x02, 0x00,
+    0x3e, 0x03, 0x02, 0x00, 0x40, 0x03, 0x02, 0x00, 0x42, 0x03, 0x02, 0x00, 0x44, 0x03, 0x02, 0x00,
+    0x46, 0x03, 0x02, 0x00, 0x48, 0x03, 0x02, 0x00, 0x4a, 0x03, 0x02, 0x00, 0x4c, 0x03, 0x02, 0x00,
+    0x4e, 0x03, 0x02, 0x00, 0x50, 0x03, 0x02, 0x00, 0x52, 0x03, 0x02, 0x00, 0x54, 0x03, 0x02, 0x00,
+    0x56, 0x03, 0x02, 0x00, 0x58, 0x03, 0x02, 0x00, 0x5a, 0x03, 0x02, 0x00, 0x5c, 0x03, 0x02, 0x00,
+    0x5e, 0x03, 0x02, 0x00, 0x60, 0x03, 0x02, 0x00, 0x62, 0x03, 0x02, 0x00, 0x64, 0x03, 0x02, 0x00,
+    0x66, 0x03, 0x02, 0x00, 0x68, 0x03, 0x02, 0x00, 0x6a, 0x03, 0x02, 0x00, 0x6c, 0x03, 0x02, 0x00,
+    0x6e, 0x03, 0x02, 0x00, 0x70, 0x03, 0x02, 0x00, 0x72, 0x03, 0x02, 0x00, 0x74, 0x03, 0x02, 0x00,
+    0x76, 0x03, 0x02, 0x00, 0x78, 0x03, 0x02, 0x00, 0x7a, 0x03, 0x02, 0x00, 0x7c, 0x03, 0x02, 0x00,
+    0x7e, 0x03, 0x02, 0x00, 0x80, 0x03, 0x02, 0x00, 0x82, 0x03, 0x02, 0x00, 0x84, 0x03, 0x02, 0x00,
+    0x86, 0x03, 0x02, 0x00, 0x88, 0x03, 0x02, 0x00, 0x8a, 0x03, 0x02, 0x00, 0x8c, 0x03, 0x02, 0x00,
+    0x8e, 0x03, 0x02, 0x00, 0x90, 0x03, 0x02, 0x00, 0x92, 0x03, 0x02, 0x00, 0x94, 0x03, 0x02, 0x00,
+    0x96, 0x03, 0x02, 0x00, 0x98, 0x03, 0x02, 0x00, 0x9a, 0x03, 0x02, 0x00, 0x9c, 0x03, 0x02, 0x00,
+    0x9e, 0x03, 0x02, 0x00, 0xa0, 0x03, 0x02, 0x00, 0xa2, 0x03, 0x02, 0x00, 0xa4, 0x03, 0x02, 0x00,
+    0xa6, 0x03, 0x02, 0x00, 0xa8, 0x03, 0x02, 0x00, 0xaa, 0x03, 0x02, 0x00, 0xac, 0x03, 0x02, 0x00,
+    0xae, 0x03, 0x02, 0x00, 0xb0, 0x03, 0x02, 0x00, 0xb2, 0x03, 0x02, 0x00, 0xb4, 0x03, 0x02, 0x00,
+    0xb6, 0x03, 0x02, 0x00, 0xb8, 0x03, 0x02, 0x00, 0xba, 0x03, 0x02, 0x00, 0xbc, 0x03, 0x02, 0x00,
+    0xbe, 0x03, 0x02, 0x00, 0xc0, 0x03, 0x02, 0x00, 0xc2, 0x03, 0x02, 0x00, 0xc4, 0x03, 0x02, 0x00,
+    0xc6, 0x03, 0x02, 0x00, 0xc8, 0x03, 0x02, 0x00, 0xca, 0x03, 0x02, 0x00, 0xcc, 0x03, 0x02, 0x00,
+    0xce, 0x03, 0x02, 0x00, 0xd0, 0x03, 0x02, 0x00, 0xd2, 0x03, 0x02, 0x00, 0xd4, 0x03, 0x02, 0x00,
+    0xd6, 0x03, 0x02, 0x00, 0xd8, 0x03, 0x02, 0x00, 0xda, 0x03, 0x02, 0x00, 0xdc, 0x03, 0x02, 0x00,
+    0xde, 0x03, 0x02, 0x00, 0xe0, 0x03, 0x02, 0x00, 0xe2, 0x03, 0x02, 0x00, 0xe4, 0x03, 0x02, 0x00,
+    0xe6, 0x03, 0x02, 0x00, 0xe8, 0x03, 0x02, 0x00, 0xea, 0x03, 0x02, 0x00, 0xec, 0x03, 0x02, 0x00,
+    0xee, 0x03, 0x02, 0x00, 0xf0, 0x03, 0x02, 0x00, 0xf2, 0x03, 0x02, 0x00, 0xf4, 0x03, 0x02, 0x00,
+
+    0xf6, 0x03, 0x02, 0x00, 0xf8, 0x03, 0x02, 0x00, 0xfa, 0x03, 0x02, 0x00, 0xfc, 0x03, 0x02, 0x00,
+    0xfe, 0x03, 0x02, 0x00
+};
+#else
+const uint8_t mGammaResetTablesBuf[] = {
+    0x0E, 0x00, 0x00, 0x00, /// ID -> 4 bytes
+};
+#endif /// _USE_GAMMA_RESET_HC_
+
+// const uint8_t mGammaResetTablesBuf[] = {
+//     0x0E, 0x00, 0x00, 0x00
+// };
+#endif /// _gamma_tables_
+
diff --git a/omx_cam/OMXVisionCam_WB_patch.h b/omx_cam/OMXVisionCam_WB_patch.h
new file mode 100644 (file)
index 0000000..16720f5
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef WB_GAIN_PATCH
+#define WB_GAIN_PATCH
+
+uint8_t mWBbuffer[] =  {  0x0C, 0x00, 0x00, 0x00,
+                          0x04, 0x00, 0x00, 0x00,
+                          0x0C, 0x00, 0x00, 0x00,
+                          0x00, 0x00, 0x00, 0x00,
+                          0x00, 0x00, 0x00, 0x00,
+                          0x00, 0x02, 0x00, 0x02,
+                          0x00, 0x02, 0x00, 0x02
+                        };
+
+const uint8_t mWBresetBuffer[] = {  0x0C, 0x00, 0x00, 0x00 };
+
+#endif
\ No newline at end of file
diff --git a/omx_cam/VisionCam.h b/omx_cam/VisionCam.h
new file mode 100644 (file)
index 0000000..bc41af4
--- /dev/null
@@ -0,0 +1,1083 @@
+/* Copyright (C) 2012 Texas Instruments, Inc. All rights reserved */
+
+#ifndef _VISION_CAM_H_
+#define _VISION_CAM_H_
+
+/** MAX_FACES_COUNT
+  *
+  * Maximum number of face coordinates
+  * that face detect algorithm can output.
+*/
+const uint32_t MAX_FACES_COUNT = 35;
+
+/** VCAM_NUM_BUFFERS
+  *
+  * The maximum number of buffers that
+  * VisionCam would be able to operate with.
+*/
+const uint32_t VCAM_NUM_BUFFERS = 8;
+
+#define VCAM_DO_IF_FAILED(ret, statement, action)   {\
+    ret = statement;\
+    if (STATUS_FAILED(ret)) { \
+        ERROR("ERROR: VCAM Failure %d in function %s on file:line %s:%u\n", ret, __FUNCTION__, __FILE__, __LINE__);\
+        action;\
+    }\
+}
+
+#define VCAM_BREAK_IF_FAILED(ret, statement)        VCAM_DO_IF_FAILED(ret, statement, break)
+#define VCAM_RETURN_IF_FAILED(ret, statement)       VCAM_DO_IF_FAILED(ret, statement, return ret)
+#define VCAM_CONTINUE_IF_FAILED(ret, statement)     VCAM_DO_IF_FAILED(ret, statement, continue)
+#define VCAM_COMPLAIN_IF_FAILED(ret, statement)     VCAM_DO_IF_FAILED(ret, statement, )
+#define VCAM_GOTO_IF_FAILED(ret, statement, label)  VCAM_DO_IF_FAILED(ret, statement, goto label)
+
+#define TIME_PROFILE 0
+
+/** @enum VisionCamCmd_e
+  *
+  * Enumeration containing the all valid commands
+  * that could be accepted by VisionCam.
+  * @see VisionCam::sendCommand().
+*/
+typedef enum _vcam_cmds_e
+{
+    VCAM_CMD_PREVIEW_START = 0, /**< Start preview command. */
+    VCAM_CMD_PREVIEW_STOP,      /**< Stop preview command. */
+    VCAM_EXTRA_DATA_START,      /**< Enable transfering of e certain image meta data type.
+                                  @see VisionCamExtraDataType_e.
+                                */
+
+    VCAM_EXTRA_DATA_STOP,       /**< Disable transfering of e certain image meta data type.
+                                  @see VisionCamExtraDataType_e.
+                                */
+
+    VCAM_CMD_LOCK_AWB,          /**< Lock of auto white balance coeficients. */
+    VCAM_CMD_LOCK_AE,           /**< Lock exposure */
+    VCAM_CMD_QUIT,              /**< */
+#if TIME_PROFILE
+    VCAM_DUMP_TIMES,            /**< Performance measurment option. */
+#endif
+    VCAM_CMD_FACE_DETECTION,    /**< Enable/Disable face detection algo.
+                                  @see bool
+                                */
+
+    VCAM_CMD_FREEZE_AWB_PARAMS, /**< Freeze white balance parameters aliance.
+                                  Auto white balance algorithm continues to work but its output is not applied,
+                                  for a certain amount of time.
+                                  After this time expires WB parameter are immediately set to the most recent calculated.
+                                  A pointer to an unsigned integer representing a time in millseconds.
+                                  Minimum freeze time is 0 and maximum 10000.
+                                */
+
+    VCAM_CMD_FREEZE_AGC_PARAMS, /**< Freeze exposure algorithm aliance.
+                                  Auto white balance alorythm continues to work but its output is not applied,
+                                  for a certain amount of time.
+                                  After this time expires WB parameter are imediately set so the most recent calculated.
+                                  A pointer to an unsigned integer representing a time in millseconds.
+                                  Minimum freeze time is 0 and maximum 10000.
+                                */
+
+    VCAM_CMD_SET_CLIENT_NOTIFICATION_CALLBACK, /**< Set client notification handler.
+                                                 @see VisionCamClientNotifierCallback
+                                                */
+    VCAM_CMD_PACK_FRAMES,       /**< Enables frame packing.
+                                    In cases when more than one frame sources are selected
+                                    (for example preiew and video port in OMX camera) this option ensures that
+                                    the frames from all sources will be passed to VisionCam client
+                                    in a single call to its preview callback.
+                                    @see VisionCamFramePack
+                                */
+
+    VCAM_CMD_MAX
+} VisionCamCmd_e;
+
+/** @enum VisionCamParam_e
+*
+*   Enumeration listing possible camera parameters.
+*   These values are passed to VisionCam::setParameter().
+*   @see VisionCam::setParameter().
+*/
+typedef enum _vcam_params_e
+{
+    VCAM_PARAM_MIN = 0x7F000001,    /**< To avoid collisions with VisionCamCmd_e. */
+
+    VCAM_PARAM_DO_AUTOFOCUS,        /**< Start auto focus of a given type @see VisionCamFocusMode. */
+    VCAM_PARAM_DO_MANUALFOCUS,      /**< Start manual focus; a value representing
+                                         focal distance must be passed. */
+
+    VCAM_PARAM_CONTRAST,            /**< Set the contrast parameter; a value,
+                                         in the range of -100 to 100 must be passed. */
+
+    VCAM_PARAM_SHARPNESS,           /**< Set the sharpness parameter; a value,
+                                        in the range of -100 to 100 must be passed. */
+
+    VCAM_PARAM_BRIGHTNESS,          /**< Brighness parameter; a value,
+                                        in the range of 0 to 200 must be passed. */
+
+    VCAM_PARAM_SATURATION,          /**< Saturation parameter; a value,
+                                        in the range of -100 to 100 must be passed. */
+
+    VCAM_PARAM_HEIGHT,              /**< Preview frame height.
+                                        This will be applied before next start preview command.
+                                        If the buffers allocated, at the momonet of next preview start, are not
+                                        with corresponding dimensions, you might receive corrupted frames
+                                        or even memory corruptions may appear.
+                                        This option if not preffered since preview width and height are strongly dependent.
+                                        use VCAM_PARAM_RESOLUTION instead.
+                                        @see VCAM_PARAM_RESOLUTION .
+                                        */
+
+    VCAM_PARAM_WIDTH,               /**< Preview frame width.
+                                        This will be applied before next start preview command.
+                                        If the buffers allocated, at the momonet of next preview start, do not
+                                        have corresponding dimensions, you might receive corrupted frames
+                                        or even memory corruptions may appear.
+                                        This option isn't preffered since preview width and height are strongly dependent to each other.
+                                        use VCAM_PARAM_RESOLUTION instead.
+                                        @see VCAM_PARAM_RESOLUTION .
+                                        */
+
+    VCAM_PARAM_FPS_FIXED,           /**< Frame rate. */
+
+    VCAM_PARAM_FPS_VAR,             /**< Set the variable frame rate.
+                                        A pointer to a structure of type VisionCamVarFramerateType must be passed
+                                        to specify minimum and maximum fps.
+                                        Variable frame rate means that fps is constantly recalculated
+                                        according to current light conditions.
+                                        @see VisionCamVarFramerateType .
+                                    */
+
+    VCAM_PARAM_COLOR_SPACE_FOURCC,  /**< Color space that will be used.
+                                        This should match the color space option,
+                                        passed to buffer allocating API.
+                                        @see _fourcc
+                                    */
+
+    VCAM_PARAM_NAME,                /**< When the input video is read from a file, this is the file name */
+
+    VCAM_PARAM_FLICKER,             /**< Set flicker avoiding parameter.
+                                        @see VisionCamFlickerType .
+                                    */
+
+    VCAM_PARAM_CROP,                /**< Crop option for preview frame.
+                                        @see VisionCamRectType .
+                                    */
+    VCAM_PARAM_CAP_MODE,            /**< Camera operating mode.
+                                        different operating modes provide different camera functionalities.
+                                        @see VisionCamCaptureMode .
+                                    */
+
+    VCAM_PARAM_SENSOR_SELECT,       /**< Active camera.
+                                        This can be done either during preview or when preview is stopped.
+                                        @see VisionCamSensorSelection.
+                                        Where :
+                                        primary sensor: the sensor at the back of the device.
+                                        secondary sensor: the sensor at the front of the device (user facing sensor).
+                                        stereo sensor: in case of stereo camera presence;
+                                        this corresponds to the couple of sensors located at the same side.
+                                    */
+
+    VCAM_PARAM_EXPOSURE_COMPENSATION, /**< EV compensation measured in ISOs.*/
+
+    VCAM_PARAM_RESOLUTION,          /**< Preview resolution.
+                                        This requires preview stop and reallocating the image buffers.
+                                        If preview is running: VisionCam::setParameter() retuns -EBADE.
+                                        A pointer to a value of VisionCamResolIdex type must be passed.
+                                        @see VisionCamResolIdex
+                                        @see VisionCamResolutions
+                                        @see VisionCamResType
+                                    */
+
+    VCAM_PARAM_MANUAL_EXPOSURE,     /**< Manual exposure time.
+                                        This affects the frame rate.
+                                        A pointer to an unsigned integer value must be passed.
+                                        This value must be in the range of 30 to 100
+                                        and represents the exposition time in milliseconds for each frame.
+                                    */
+
+    VCAM_PARAM_AWB_MODE,            /**< White balance mode.
+                                        @see VisionCamWhiteBalType.
+                                    */
+
+    VCAM_PARAM_COLOR_TEMP,          /**< Color temperature in Kelvins. */
+
+    VCAM_PARAM_EXPOSURE_ISO,        /**< Exposure ISO.
+                                        An unsigned integer value, in the range of 100 to 800, must be passed.
+                                    */
+
+    VCAM_PARAM_WB_COLOR_GAINS,      /**< White balance color gain manual control.
+                                        Refers to the color channels of a non-sompressed image.
+                                        This is specific setting, valid only in gesture operating modes:
+                                        VCAM_GESTURE_MODE and VCAM_STEREO_GEST_MODE (@see VisionCamCaptureMode).
+                                        @see VisionCamWhiteBalGains.
+                                        @note This functionallity might not be enabled for some devices.
+                                    */
+
+    VCAM_PARAM_GAMMA_TBLS,          /**< 3A gamma table coefficients manual control.
+                                        This is specific setting, valid only in gesture operating modes:
+                                        VCAM_GESTURE_MODE and VCAM_STEREO_GEST_MODE (@see VisionCamCaptureMode).
+                                        @see VisionCamGammaTableType
+                                    */
+
+    VCAM_PARAM_ROTATION,            /**< Preview frame rotation.
+                                        Pointer to an unsigned integer value must be passed,
+                                        which will represent the degrees of rotation.
+                                        Possible values are: 0, 90, 180, 270 in degrees.
+                                        @see VisionCamRotation_e
+                                    */
+
+    VCAM_PARAM_MIRROR,              /**< Sensor mirroring depending on the sensor,
+                                        this setting will provide HW or SW mirroring of the image.
+                                        @see VisionCamMirrorType
+                                    */
+
+    VCAM_PARAM_STEREO_INFO,         /**< Stereo image layout and subsampling.
+                                      @see VisionCamStereoInfo
+                                    */
+
+    VCAM_PARAM_AWB_MIN_DELAY_TIME,  /**< This will stop white balance algorithm for a certain period of time.
+                                        When this time expires, WB algorithm will start again and will smoothly
+                                        change WB parameters until they reach the values that suit to the light conditions.
+                                        Parameter is pointer to unsigned integer value,
+                                        which represents the delay time in millseconds.
+                                    */
+
+    VCAM_PARAM_GESTURES_INFO,       /**< Notify the camera auto algorithms that a gesture is detected, and gives location
+                                        of the region of interest.
+                                    */
+
+    VCAM_PARAM_AGC_MIN_DELAY_TIME,  /**< This will stop exposure gain recalculations for a certain period of time.
+                                        When this time expires, exposure algorithms will smooth
+                                        the light conditions.
+                                        Parameter is pointer to unsigned integer value,
+                                        which represents the delay time in millseconds.
+                                    */
+
+    VCAM_PARAM_AGC_LOW_TH,          /**< Automatic gain control low threshold.
+                                        Pointer to an integer value must be passed.
+                                        Ragne is 0 - 10000.
+                                    */
+
+    VCAM_PARAM_AGC_HIGH_TH,         /**< Automatic gain control high threshold.
+                                        Pointer to an integer value must be passed.
+                                        Ragne is 0 - 10000.
+                                    */
+
+    VCAM_PARAM_2DBUFFER_DIM,        /**< Used to get buffer allocation information.
+                                      This information is limited to 2D buffer dimensions (width and height).
+                                      @see VisionCamResType
+                                    */
+
+    VCAM_PARAM_PATH,                /**<
+                                    */
+
+    VCAM_PARAM_MAX
+} VisionCamParam_e;
+
+/** @enum VisionCamExtraDataType_e
+  * Defines which meta data type to be transferred.
+  * @see VCAM_EXTRA_DATA_START
+  * @see VCAM_EXTRA_DATA_STOP
+*/
+typedef enum _vcam_extradatatypes_e
+{
+   VCAM_EXTRA_DATA_NONE = 0,
+//     VCAM_EXIF_ATTRIBUTES,
+    VCAM_ANCILLARY_DATA,
+    VCAM_WHITE_BALANCE,
+    VCAM_UNSATURATED_REGIONS,
+    VCAM_FACE_DETECTION,
+//     VCAM_BARCODE_DETECTION,
+//     VCAM_FRONT_OBJECT_DETECTION,
+//     VCAM_MOTION_ESTIMATION,
+    VCAM_MTIS_TYPE,
+//     VCAM_DISTANCE_ESTIMATION,
+    VCAM_HISTOGRAM,
+    VCAM_FOCUS_REGION,
+//     VCAM_EXTRA_DATA_PAN_AND_SCAN,
+//     VCAM_RAW_FORMAT,
+//     VCAM_SENSOR_TYPE,
+//     VCAM_SENSOR_CUSTOM_DATA_LENGTH,
+//     VCAM_SENSOR_CUSTOM_DATA,
+    VCAM_MANUAL_WHITE_BALANCE,
+    VCAM_EXTRA_DATA_TYPE_MAX
+} VisionCamExtraDataType_e;
+
+/** @enum VisionCamFlickerType
+  * Possible flicker avoidance modes.
+  * @see VCAM_PARAM_FLICKER
+*/
+typedef enum _flicker_type
+{
+    FLICKER_OFF,                    /**< No flicker correction. */
+    FLICKER_AUTO,                   /**< Automatic flicker correction. */
+    FLICKER_50Hz,                   /**< 50 Hz flicker  correction. */
+    FLICKER_60Hz,                   /**< 60 Hz flicker correction. */
+    FLICKER_100Hz = FLICKER_50Hz,   /**< 100 Hz flicker correction. */
+    FLICKER_120Hz = FLICKER_60Hz,   /**< 120 Hz flicker correction. */
+
+    FLICKER_MAX = 0X7fffffff
+}VisionCamFlickerType;
+
+/** @enum VisionCamRotation_e
+  * Enumatarion that is used to configure
+  * HW rotation of preview frames.
+  * @see VCAM_PARAM_ROTATION
+*/
+typedef enum _vcam_rotation_e {
+    VCAM_ROTATION_0     = 0,    /**< No rotation. */
+    VCAM_ROTATION_90    = 90,   /**< Rotate 90 degrees right. */
+    VCAM_ROTATION_180   = 180,  /**< Rotate 180 degrees */
+    VCAM_ROTATION_270   = 270   /**< Rotate 270 degrees right*/
+}VisionCamRotation_e;
+
+/** @enum VisionCamSensorSelection
+  * Defines different sensors.
+  * @see VCAM_PARAM_SENSOR_SELECT
+*/
+typedef enum _sensor_selection
+{
+    VCAM_SENSOR_PRIMARY = 0,    /**< Usually this is the sensor on the back of the device. */
+    VCAM_SENSOR_SECONDARY = 1,  /**< usually, this is the sensor at the front of the device. */
+    VCAM_SENSOR_STEREO = 2,     /**< In case os stereo cameras, this is stereo use case. */
+
+    VCAM_SENSOR_MAX = 0x7fffffff
+}VisionCamSensorSelection;
+
+/** @enum VisionCamStereoLayout
+  * Defines possible stereo imaging layouts.
+  * @see VisionCamStereoInfo
+*/
+typedef enum _stereo_layout
+{
+    VCAM_STEREO_LAYOUT_TOPBOTTOM,   /**< Left and right frames are located one above the other. */
+    VCAM_STEREO_LAYOUT_LEFTRIGHT,   /**< Left and right frames are located next to each other. */
+
+    VCAM_STEREO_LAYOUT_MAX
+} VisionCamStereoLayout;
+
+/** @enum VisionCamCaptureMode
+  * Defines possible camera operating modes.
+*/
+typedef enum _capture_mode
+{
+    VCAM_VIDEO_NORMAL,      /**< Normal vide processing pipe. */
+    VCAM_VIDEO_HIGH_SPEED,  /**< High speed video processing pipe. */
+    VCAM_GESTURE_MODE,      /**< Video pipe optimized for gesture computations. */
+    VCAM_STEREO_MODE,       /**< Normal stereo pipe. */
+    VCAM_STEREO_GEST_MODE,  /**< stereo pipe, optimized for gesture computations. */
+#if defined(__QNX__)
+    VCAM_VIEWFINDER_MODE,
+#endif
+
+    VCAM_CAP_MODE_MAX
+}VisionCamCaptureMode;
+
+/** @enum VisionCamGestureEvent_e
+  * Defines different gesture events.
+*/
+typedef enum _vcam_gesture_event_e {
+    VCAM_GESTURE_EVENT_INVALID = 0, /**< No or invalid gesture event. Could also mean incompatible software version. */
+    VCAM_GESTURE_EVENT_SWIPE_LEFT,  /**< Swipe to the left. */
+    VCAM_GESTURE_EVENT_SWIPE_RIGHT, /**< Swite to the right. */
+    VCAM_GESTURE_EVENT_FIST_LEFT,   /**< Fist turned to left. */
+    VCAM_GESTURE_EVENT_FIST_RIGHT,  /**< Fist turned to right. */
+
+    VCAM_GESTURE_EVENT_MAX,
+} VisionCamGestureEvent_e;
+
+/** @enum VisionCamFocusMode
+  * Defines focus modes.
+*/
+typedef enum _vcam_focus_mode
+{
+    VCAM_FOCUS_CONTROL_ON = 0,                  /**< Focus is enabled. */
+    VCAM_FOCUS_CONTROL_OFF,                     /**< Focus is disabled. */
+    VCAM_FOCUS_CONTROL_AUTO,                    /**< Continuous autofocus is enabled. */
+    VCAM_FOCUS_CONTROL_AUTO_LOCK,               /**< Single autoficus enabled - once fous position of lens is reached, focus algorithm stops. */
+    /// TI extension follow
+    VCAM_FOCUS_CONTRO_AUTO_MACRO,               /**< Auto focus in macro mode. */
+    VCAM_FOCUS_CONTROL_AUTO_INFINITY,           /**< Infinity focus mode. */
+    VCAM_FOCUS_FACE_PRIORITY_MODE,              /**< Emphasis of focus algorithm is the output of face detect. */
+    VCAM_FOCUS_REGION_PRIORITY_MODE,            /**< Focuses on given regions. */
+    VCAM_FOCUS_CONTROL_HYPERFOCAL,              /**<  */
+    VCAM_FOCUS_CONTROL_PORTRAIT,                /**<  */
+    VCAM_FOCUS_CONTROL_EXTENDED,                /**<  */
+    VCAM_FOCUS_CONTROL_CONTINOUS_NORMAL,        /**<  */
+    VCAM_FOCUS_CONTROL_CONTINOUS_EXTENDED,      /**<  */
+    VCAM_FOCUS_FACE_PRIORITY_CONTINOUS_MODE,    /**<  */
+    VCAM_FOCUS_REGION_PRIORITY_CONTINOUS_MODE,  /**<  */
+    VCAM_FOCUS_CONTROL_MAX
+}VisionCamFocusMode;
+
+/** @struct VisionCamStereoInfo
+  * Configuration for stereo operating modes.
+*/
+typedef struct _vcam_stereo_info_t {
+    VisionCamStereoLayout layout;       /**< Stereo image layout: top bottom or side by side.*/
+    uint32_t               subsampling; /**< Set to 1 if you are setting your
+                                            dimensions manually to double to desire value.
+                                            Set to 2 if you want to compress the two images
+                                            into a normal image.
+                                        */
+} VisionCamStereoInfo;
+
+/** @enum VisionCamLockState
+  * Defines enable and disable modes used for variety of settings.
+*/
+typedef enum _vcam_lock_state
+{
+    UNLOCKED    = false,
+    LOCKED      = true
+}VisionCamLockState;
+
+/** @enum VisionCamResolIdex
+  * Defines VisionCam resolutions.
+  * @see VisionCamResolutions
+  * @see VisionCamResType
+*/
+typedef enum _e_resol_index
+{
+    VCAM_RES_2MP = 0,   /**< 1600 x 1200 pixels */
+    VCAM_RES_1_25MP,    /**< 1300 x 976 pixels */
+    VCAM_RES_720p,      /**< 1280 x 720 pixels */
+    VCAM_RES_SVGA,      /**< 800 x 480 pixels */
+    VCAM_RES_D1PAL,     /**< 720 x 576 pixels */
+    VCAM_RES_D1NTSC,    /**< 720 x 480 pixels */
+    VCAM_RES_PAL,       /**< 768 x 576 pixels */
+    VCAM_RES_VGA,       /**< 640 x 480 pixels */
+    VCAM_RES_CIF,       /**< 352 x 288 pixels */
+    VCAM_RES_QVGA,      /**< 320 x 240 pixels */
+    VCAM_RES_QCIF,      /**< 176 x 144 pixels */
+    VCAM_RES_QQVGA,     /**< 160 x 120 pixels */
+    VCAM_RES_SQCIF,     /**< 128 x 96 pixels */
+    VCAM_RES_SXVGA,     /**< 1280 x 960 pixels */
+
+    VCAM_RESOL_MAX
+}VisionCamResolIdex;
+
+/** @struct VisionCamResType
+  * Packs resolution index and resolutin sizes for supported resolutins.
+  * @see VisionCamResolIdex
+*/
+typedef struct _res_type
+{
+    VisionCamResolIdex mResIdx; /**< VisionCam defined resolution index. */
+    uint32_t            mWidth; /**< Width in pixels. */
+    uint32_t            mHeight;/**< Height in pixels. */
+}VisionCamResType;
+
+/** VisionCamResolutions[]
+  * Predefined resolution indexes and sizes.
+  * The only possible for VisionCam.
+*/
+const VisionCamResType VisionCamResolutions[] = {
+    { VCAM_RES_2MP    , 1600, 1200 },
+    { VCAM_RES_1_25MP , 1300, 976  },
+    { VCAM_RES_720p   , 1280, 720  },
+    { VCAM_RES_SVGA   , 800 , 480  },
+    { VCAM_RES_D1PAL  , 720 , 576  },
+    { VCAM_RES_D1NTSC , 720 , 480  },
+    { VCAM_RES_PAL    , 768 , 576  },
+    { VCAM_RES_VGA    , 640 , 480  },
+    { VCAM_RES_CIF    , 352 , 288  },
+    { VCAM_RES_QVGA   , 320 , 240  },
+    { VCAM_RES_QCIF   , 176 , 144  },
+    { VCAM_RES_QQVGA  , 160 , 120  },
+    { VCAM_RES_SQCIF  , 128 , 96   },
+    { VCAM_RES_SXVGA  , 1280, 960  }
+};
+
+/** @enum VisionCamObjectType
+  * Defines some gesture objects.
+  * These are not the only supported.
+*/
+typedef enum _vcam_object_type {
+    VCAM_OBJECT_PALM,   /**< Palm */
+    VCAM_OBJECT_FIST,   /**< Fist */
+    VCAM_OBJECT_FACE,   /**< Face */
+
+    VCAM_OBJECT_MAX
+}VisionCamObjectType;
+
+/** @enum VisionCamWhiteBalType
+  * Defines different white balance modes used by VisionCam
+*/
+typedef enum _vcam_white_bal_type {
+    VCAM_WHITE_BAL_CONTROL_OFF = 0,         /**< White balance algorithm is turned off. */
+    VCAM_WHITE_BAL_CONTROL_AUTO,            /**< Automatic white balance. */
+    VCAM_WHITE_BAL_CONTROL_SUNLIGHT,        /**< WB optimized for sunny light conditions. */
+    VCAM_WHITE_BAL_CONTROL_CLOUDY,          /**< WB optimized for cloudy light conditions. */
+    VCAM_WHITE_BAL_CONTROL_SHADE,           /**< WB optimized for shaded light conditions. */
+    VCAM_WHITE_BAL_CONTROL_TUNGSTEN,        /**< WB optimized for tungsten (worm) light conditions. */
+    VCAM_WHITE_BAL_CONTROL_FLUORESCENT,     /**< WB optimized for flourescent light conditions. */
+    VCAM_WHITE_BAL_CONTROL_INCANDESCENT,    /**< WB optimized for incadescent (warm) light conditions. */
+    VCAM_WHITE_BAL_CONTROL_FLASH,           /**< WB optimized for camera flash. */
+    VCAM_WHITE_BAL_CONTROL_HORIZON,         /**< WB optimized for landscape sunny conditions.. */
+    VCAM_WHITE_BAL_CONTROL_FACEPRIORITYMODE = 0X7F000001,
+
+    VCAM_WHITE_BAL_CONTROL_MAX
+}VisionCamWhiteBalType;
+
+/** @enum VisionCamMirrorType
+  * Mirroring of image in frame buffer.
+*/
+typedef enum _vcam_mirror_type{
+    VCAM_MIRROR_NONE,           /**< No mirror applied. */
+    VCAM_MIRROR_VERTICAL,       /**< Mirror by vertical axis. */
+    VCAM_MIRROR_HORIZONTAL,     /**< Mirror by horizontal axis. */
+    VCAM_MIRROR_BOTH,           /**< Mirror by bith vertical and horizontal axis. */
+
+    VCAM_MIRROR_MAX
+}VisionCamMirrorType;
+
+/** @enum VisionCamPort_e
+  * Defines different camera output ports.
+  * Sometimes useful as different ports may have different configurations,
+  * also every port outputs a separate image, so one could be used at one process,
+  * while another - on other process.
+  * @note Each frame from a port has a twin on another port. Use frame's timestamp to find the matchin one.
+  *       All ports are synchronised so frames are ouput sequentally.
+  *       Also note that video port is sending frames ONLY when a preview port is sending.
+*/
+typedef enum _vision_cam_port_e {
+    VCAM_PORT_ALL = 0,  /**< All port listed below. */
+    VCAM_PORT_PREVIEW,  /**< Preview port. */
+    VCAM_PORT_VIDEO,    /**< Video port. */
+
+    VCAM_PORT_MAX
+}VisionCamPort_e;
+
+/** @enum VCAM_HISTCOMPONENTTYPE
+  * Histogram types.
+  * @see VisionCamHistogram
+*/
+typedef enum VCAM_HISTCOMPONENTTYPE {
+    VCAM_HISTCOMP_Y = 0,        /**< Luminance histogram (Y) */
+    VCAM_HISTCOMP_YLOG,         /**< Logarithmic luminance histogram (Y)*/
+    VCAM_HISTCOMP_R,            /**< Red histogram component (R)*/
+    VCAM_HISTCOMP_G,            /**< Green histogram component (G)*/
+    VCAM_HISTCOMP_B,            /**< Blue histogram component (B)*/
+    VCAM_HISTCOMP_Cb,           /**< Chroma blue histogram component (Cb)*/
+    VCAM_HISTCOMP_Cr,           /**< Chroma red histogram component (Cr) */
+    VCAM_HISTCOMP_32BIT_PATCH = 0x7FFFFFFF
+}VCAM_HISTCOMPONENTTYPE;
+
+
+/** @struct VisionCamWhiteBalGains
+  * Manual white balance gain structure.
+  * Contains gain for each color channel.
+  * @see VCAM_PARAM_WB_COLOR_GAINS
+*/
+typedef struct _white_bal_gains_type{
+    uint16_t mRed;      /**< Red color channel. */
+    uint16_t mGreen_r;  /**< Difference between green and red color. */
+    uint16_t mGreen_b;  /**< Difference between green and blue color. */
+    uint16_t mBlue;     /**< Blue channel. */
+}VisionCamWhiteBalGains;
+
+/** @struct VisionCamAncillary
+  * Ancillary data type definition.
+*/
+typedef  struct _ancillary_type {
+    uint32_t             nAncillaryDataVersion;     /**< Version of the ancillary data definition implemented by the application in binary coded decimal format. */
+    uint32_t             nFrameNumber;              /**< This is a free-running counter (wraps back to zero at overflow) that is applied to each frame from the sensor whether that frame is not sent or is sent in multiple formats to the host. */
+    uint32_t             nShotNumber;               /**< Indicates the shot number in a multi-shot sequence, counting up from 1 */
+    uint16_t             nInputImageHeight;         /**< Height in pixels of the input image (i.e. from sensor or video decoder) */
+    uint16_t             nInputImageWidth;          /**< Width in pixels of the input image (i.e. from sensor or video decoder) */
+    uint16_t             nOutputImageHeight;        /**< Height in pixels of the image sent to the host */
+    uint16_t             nOutputImageWidth;         /**< Width in pixels of the image sent to the host  */
+    uint16_t             nDigitalZoomFactor;        /**< Digital zoom factor: 10 bits decimal, 6 bits fractional.
+                                                         @note Note: When non-square pixels are sent to the host, as indicated by the pixel aspect ratio ancillary data fields, the digital zoom factor applies in the direction that is the lesser of the pixel aspect ratio fields.
+                                                    */
+    int16_t               nCropCenterColumn;        /**< Defines the center of cropped region with regard to full sensor field of view.   All values are valid, 0x8000 is the left column and 0x7fff is the right column. 0 is the center column.  This is effectively a percentage ranging between +/- 50% */
+    int16_t               nCropCenterRow;           /**< Defines the center of cropped region with regard to full sensor field of view.  All values are valid, 0x8000 is the top row and 0x7fff is the bottom row. 0 is the center row.  This is effectively a percentage ranging between +/- 50%.  */
+    uint16_t             nOpticalZoomValue;         /**< Optical zoom factor: 4 bits decimal, 12 bits fractional */
+    uint8_t               nFlashConfiguration;      /**< Number Logical Flash Sources – Maximum 4 logical Flashes. For each logical flash following two fields will be filled. */
+    uint8_t               nFlashUsage;              /**< 1. Bit 0 and 1 (LSB) - Flash Light Type (00b = Not used; 01b = Xenon; 10b = LED; 11b = Other)
+                                                         2. Bits 2 and 3 – Flash Charging Status (00b = Not charging; 01b = Charging; 10b = Charged; 11b = Error)
+                                                         3. Bits 4 and 5 – Flash Strobe Detection ( 00b = Not supported; 01b = Reserved; 10b = Strobe return light not detected; 11b = Strobe return light detected)
+                                                         4. Bit 6 and 7 - Reserved1. Bit 0 and 1 (LSB) - Flash Light Type (00b = Not used; 01b = Xenon; 10b = LED; 11b = Other)
+                                                    */
+    uint32_t             nFlashStatus;              /**< 1.Bits 0 to 7 -  Flash Mode (bit variable). Flash can support more than one mode.
+                                                           Bit 0 = Capture Flash Mode
+                                                           Bit 1 = Video Light (Torch) Mode
+                                                           Bit 2 = Pre-flash Mode
+                                                           Bit 3 = AF Assist Mode
+                                                           Bit 4 = Privacy Light Mode
+                                                           Bit 5 = Red-eye Reduction Mode
+                                                           Bit 6 = Other Mode 1
+                                                           Bit 7 = Other Mode 2
+                                                        2. Bits 8 to 23 - Flash Control Mode. 2bits/Flash Light Mode
+                                                           00b = Not used
+                                                           01b = Compulsory flash firing
+                                                           10b = Compulsory flash suppression
+                                                           11b = Auto
+                                                        3. Bits 24 to 31 - Flash Intensity
+                                                           0 = Flash did not fire
+                                                           1 = 255 - Flash Intensity or Flash Intensity Identifier1.Bits 0 to 7 -  Flash
+                                                    */
+    uint8_t               nAFStatus;                /**< Auto Focus status
+                                                        FAILED is a single bit independent of the other values.
+
+                                                        The other values are mutually exclusive
+                                                        OFF=not present or N/A
+                                                        LOCKED=manual
+                                                        RUNNING=auto, active
+                                                        FROZEN=suspended
+                                                    */
+    uint8_t               nAWBStatus;               /**< Auto White Balance status. See explanation in AF status. */
+    uint8_t               nAEStatus;                /**< Auto Exposure status See explanation in AF status. */
+    uint32_t             nExposureTime;             /**< Exposure time in microseconds. */
+    uint16_t             nEVCompensation;           /**< Exposure compensation */
+    uint8_t               nDigitalGainValue;        /**< Digital gain setting */
+    uint8_t               nAnalogGainValue;         /**< Analog gain setting */
+    uint16_t             nCurrentISO;               /**< ISO setting based on reference ISO */
+    uint16_t             nReferenceISO;             /**< Reference ISO for the current sensor */
+    uint8_t               nApertureValue;           /**< Aperture setting */
+    uint8_t               nPixelRange;              /**< Indicates the range of pixel values */
+    uint16_t             nPixelAspectRatio;         /**< Indicates the width corresponding to the aspect ratio (PAR) of the pixels (samples) in the frame to which this ancillary data is attached.  The PAR always indicates the true PAR, unless otherwise indicated in the application-specific documentation. */
+    uint8_t               nCameraShake;             /**< Indicates risk of camera shake. For instance, if exposure time is greater than 1/f but less than 2/f, camera shake can be considered MEDIUM_RISK. If exposure time is greater than 2/f, camera_shake can be considered a HIGH_RISK. */
+    uint16_t             nFocalDistance;            /**< Distance in cm from the camera lens if possible (14 lsbs).  Upper 2 msbs indicate if the lens is set to: infinity (’10), macro (’01), in between (’00), or moving for AF search (’11). */
+    uint64_t             nParameterChangeFlags;     /**< A 32-bit bit mask where each bit represents a sub-set of parameters.  A bit value of ‘0’ indicates that the associated parameter set did not change from the previous frame. A bit value of ‘1’ indicates that the parameter set has changed from the previous frame.
+                                                            0: SEN_EXPOSURE (sensor exp)
+                                                            1: SEN_GAIN (sensor gain ->analogue and digital are in the same field.
+                                                            2: LSC_2D (2d lsc)
+                                                            3: VLDC (Vertical Line Defect Correction)
+                                                            4: ISIF_GAIN
+                                                            5: H3A_WB
+                                                            6: FLASH
+                                                            7: ISP_NOISE_FILTER_1 (iss noise filter)
+                                                            8: GIC (green imbalance correction)
+                                                            9: CFA
+                                                            10: GBCE
+                                                            11: YUV444TO422 (yuv444 to 422)
+                                                            12: EDGE_ENH (Edge enhancement)
+                                                            13: CAR (chromatic aberration reduction)
+                                                            14: LSC_RAD (radial based one - useless)
+                                                            15: DFS (Dark frame subtract)
+                                                            16: DPC (defect pixel correction in ipipeif)
+                                                            17: DPCM
+                                                            18: LPF_H (Low pass filter params for Horizontal resizing)
+                                                            19: LPF_V (Low pass filter params for Vertical resizing)
+                                                            20: CLAMP (ISIF black clamp configuration)
+                                                            21: WB_GAINS (wb gains)
+                                                            22: GAMMA (Gamma)
+                                                            23: RGB2RGB_1
+                                                            24: RGB2YUV
+                                                            25: 3D_LUT (3d lut)
+                                                            26: DPC LUT
+                                                            27: DPC OTF (in ipipe)
+                                                            28: RGB2RGB_2 (after gamma)
+                                                            29: ISP_NOISE_FILTER_2 (iss noise filter)
+                                                            30: CGS (Chroma gain suppression)
+                                                            31: IPIPE_IF_DPC1 (ISIF or VP)
+                                                            32: IPIPE_IF_DPC2 (from SDRAM)
+                                                            33-63: reserved
+                                                    */
+    uint8_t               nNumFacesDetected;        /**< When Face Detect is enabled, this contains the number of faces detected. When face detect is disabled, this number should be set to 0. */
+    uint8_t               nConvergenceMode;         /**< Reserved for future usage. */
+    uint8_t               nConvergenceStatus;       /**< Reserved for future usage. */
+    uint8_t               nDCCStatus;               /**< Reserved for future usage. */
+}VisionCamAncillary;
+
+/** @struct VisionCamHistogram
+  * Histogram data type definition.
+*/
+typedef struct _histogram_type{
+    uint32_t nBins;                          /**< The number of bins in the histogram */
+    VCAM_HISTCOMPONENTTYPE eComponentType;   /**< Specifies the type of the histogram bins according to enum.
+                                                 It can be selected to generate multiple component types,
+                                                 then the extradata struct is repeated for each component type */
+    uint32_t data[1];
+}VisionCamHistogram;
+
+/** @struct VisionCamMetadata
+  * Image meta data type definition.
+*/
+typedef struct _metadata_type {
+    VisionCamWhiteBalGains *mAutoWBGains;   /**< Info about auto white balance algorithm output: color gains applied by AWB. */
+    VisionCamWhiteBalGains *mManualWBGains; /**< Info about manual white balance algorithm : color gains applied by user. */
+    VisionCamAncillary     *mAncillary;     /**< Ancillary data. */
+    VisionCamHistogram     *mHistogram2D;   /**< Histogram data for 2D use cases. */
+    VisionCamHistogram     *mHistogramL;    /**< Histogram data for left channel in case of stereoscopic use cases. */
+    VisionCamHistogram     *mHistogramR;    /**< Histogram data for right channel in case of stereoscopic use cases. */
+}VisionCamMetadata;
+
+/** @struct VisionCamGammaTableType
+  * Defines the gamma table data type, that is used while setting manual gamma table coeficients.
+*/
+typedef struct _gamma_tbl_type {
+    int32_t   mTableSize;   /**< The size of the table. */
+    uint16_t *mRedTable;    /**< Address of the table with red color coeficients. */
+    uint16_t *mGreenTable;  /**< Address of the table with green color coeficients. */
+    uint16_t *mBlueTable;   /**< Address of the table with blue color coeficients. */
+}VisionCamGammaTableType;
+
+/** @struct VisionCamRectType
+  * Definition of rectangle type.
+*/
+typedef struct _rect_type {
+    int32_t mLeft;      /**< x-axis coordinate of top-left corner of a rectangle. */
+    int32_t mTop;       /**< y-axis coordinate of top-left corner of a rectangle. */
+    uint32_t mWidth;    /**< Width of a rectangle. */
+    uint32_t mHeight;   /**< Height of a rectangle. */
+}VisionCamRectType;
+
+/** @struct VisionCamFaceType
+  * Data type containing the output of face detection algorithm output.
+*/
+typedef struct _face_type {
+    /**< Detection score between 0 and 100
+         0   means unknown score,
+         1   means least certain,
+         100 means most certain the detection is correct */
+    uint32_t mScore;
+    /**< Coordinates of the face */
+    VisionCamRectType mFacesCoordinates;
+    /**< The orientation of the axis of the detected object.
+         Here roll angle is defined as the angle between the vertical axis of face and the horizontal axis.
+         All angles can have the value of -180 to 180 degree in Q16 format.
+         Some face detection algorithm may not be able to fill in the angles */
+    int32_t mOrientationRoll;
+    int32_t mOrientationYaw;
+    int32_t mOrientationPitch;
+    /**< Represents priority of each object when there are multiple objects detected */
+    uint32_t mPriority;
+}VisionCamFaceType;
+
+/** @struct VisionCamVarFramerateType
+  * Defines the minimum and maximum fps in case a variable frame rate os selected.
+  * Variable frame rate, means that expositions and respectively frame rate are recalculated at any moment.
+*/
+typedef struct _var_frame_rate_type {
+    uint32_t mMin;  /**< Minimum fps. */
+    uint32_t mMax;  /**< Maximul fps. */
+}VisionCamVarFramerateType;
+
+/** @struct VisionCamObjectRectType
+  * Definition of type, describing an area where an object is detected.
+*/
+typedef struct _vcam_object_rect_type {
+    VisionCamObjectType mObjType;   /**< The type ofthe object. */
+    int32_t mTop;                   /**< y-axis coordinate of top-left corner of a rectangle. */
+    int32_t mLeft;                  /**< x-axis coordinate of top-left corner of a rectangle. */
+    uint32_t mWidth;                /**< Width of a rectangle. */
+    uint32_t mHeight;               /**< Height of a rectangle. */
+}VisionCamObjectRectType;
+
+#ifdef __cplusplus
+/** @struct VisionCamGestureInfo
+  * Structure containing information about gesures detected inside the stream.
+*/
+struct  VisionCamGestureInfo {
+    ~VisionCamGestureInfo()
+    {
+        if( mRegions )
+            delete [] mRegions;
+    }
+    VisionCamGestureEvent_e mGestureType;   /**< Type of the gesture event. */
+    uint64_t timeStamp;                     /**< Timestamp of the frame in which this is detected. */
+    uint32_t mRegionsNum;                   /**< The number of the regions in frame, where it is detected. */
+    VisionCamObjectRectType *mRegions;      /**< Coordinateds and gesture object for each region. */
+};
+#else
+/** @struct VisionCamGestureInfo
+  * Structure containing information about gesures detected inside the stream.
+*/
+typedef struct  _vcam_gesture_info_type {
+    VisionCamGestureEvent_e mGestureType;   /**< Type of the gesture event. */
+    uint64_t timeStamp;                     /**< Timestamp of the frame in which this is detected. */
+    uint32_t mRegionsNum;                   /**< The number of the regions in frame, where it is detected. */
+    VisionCamObjectRectType *mRegions;      /**< Coordinateds and gesture object for each region. */
+} VisionCamGestureInfo;
+#endif // __cplusplus
+
+/** @class VisionCamClientNotifier
+  * User notification class.
+  * This is used to notify client when an extarnal camera event occur.
+*/
+class VisionCamClientNotifier {
+public:
+    /**< @enum VisionCamClientNotificationMsg
+      * Defines some possible events that may occur outside VisionCam.
+    */
+    typedef enum _vcam_client_notification_msg_type{
+        VCAM_MESSAGE_EMPTY,                     /**< Unknown event occur. */
+        VCAM_MESSAGE_ALLOCATE_V4L2_BUFFERS,     /**< User may allocate image resources (this is in case resources were previously freed, bacause of external event). */
+        VCAM_MESSAGE_FREE_V4L2_BUFFERS,         /**< User must free allocated resources. */
+        VCAM_MESSAGE_PREEMPT_SUSPEND_ACTIVITY,  /**< Camera has been preempted by a higher priority process, so VisionCam will suspend. This means frames will not be received for some time. */
+        VCAM_MESSAGE_PREEMPT_RESUME_ACTIVITY,   /**< VisionCam has got back its control over camera. */
+        VCAM_MESSAGE_PREEMPT_WAIT_RESOURCES,    /**<  */
+        VCAM_MESSAGE_PREAMPT_REASOURCES_READY,  /**<  */
+
+        VCAM_MESSAGE_MAX
+    }VisionCamClientNotificationMsg;
+
+    typedef void *(*_vcam_client_notification_callback_type)( _vcam_client_notification_msg_type );
+    typedef _vcam_client_notification_callback_type VisionCamClientNotifierCallback;
+
+public:
+    /// Constructor
+    VisionCamClientNotifier()
+    {
+        mNotificationCallback = NULL;
+    }
+
+    /// The notification function, that user will register.
+    VisionCamClientNotifierCallback mNotificationCallback;
+};
+
+/** @class VisionCamFrame
+  *
+  * Frame descriptor class. Holds preview a frame
+  * and carries all the data related to it.
+*/
+class VisionCamFrame
+{
+public:
+
+    /** default contrustor */
+    VisionCamFrame() {
+      clear();
+    }
+
+    /** copy constructor */
+    VisionCamFrame(const VisionCamFrame &frame) :
+        mCookie(frame.mCookie),
+        mFrameBuff(frame.mFrameBuff),
+        mExtraDataBuf(frame.mExtraDataBuf),
+        mFrameSource(frame.mFrameSource),
+        mFd(frame.mStartY),
+        mTimestamp(frame.mTimestamp),
+        mWidth(frame.mWidth),
+        mHeight(frame.mHeight),
+        mOffsetX(frame.mOffsetX),
+        mOffsetY(frame.mOffsetY),
+        mLength(frame.mLength),
+        mExtraDataLength(frame.mExtraDataLength),
+        mMetadata(frame.mMetadata),
+        mDetectedFacesNum(frame.mDetectedFacesNum)
+        {
+            if( mDetectedFacesNum )
+                memcpy( &mFaces, &frame.mFaces, mDetectedFacesNum*sizeof(VisionCamFaceType));
+            else
+                memset( &mFaces, 0, sizeof(VisionCamFaceType)*MAX_FACES_COUNT);
+        };
+
+    /** This clears all values */
+    void clear() {
+      mContext = NULL;
+      mCookie = NULL;
+      mFrameBuff = NULL;
+      mExtraDataBuf = NULL;
+      mFrameSource = VCAM_PORT_PREVIEW; // default to the common preview port
+      mFd = 0;
+      mTimestamp = 0;
+      mWidth = 0;
+      mHeight = 0;
+      mOffsetX = 0;
+      mOffsetY = 0;
+      mStartX = 0;
+      mStartY = 0;
+      mLength = 0;
+      mExtraDataLength = 0;
+      mMetadata.mAncillary = NULL;
+      mMetadata.mAutoWBGains = NULL;
+      mMetadata.mManualWBGains = NULL;
+      mDetectedFacesNum = 0;
+      memset(&mFaces, 0, sizeof(mFaces));
+    }
+
+    /** This serializes all data in the frame into a flat buffer */
+    size_t serialize(uint8_t *buffer, size_t len);
+
+    /** This unserializes all the data from a flat buffer back into the instance class object */
+    size_t unserialize(uint8_t *buffer, size_t len);
+
+    /** This returns the max possible size (as currently allocated) of the frame for the purpose of allocating flat memory for serialization */
+    size_t maxSerialLength();
+
+public:
+    void *mContext;                 /**< Indicates in which context this frame is set (which VisionCam instance at all). */
+    void *mCookie;                  /**< The cookie data. */
+    void *mFrameBuff;               /**< The image buffer. */
+    void *mExtraDataBuf;            /**< Extra data buffer. */
+    VisionCamPort_e mFrameSource;   /**< The index of the port from which this frame has arrived. */
+    int32_t mFd;                    /**<  */
+    int64_t mTimestamp;             /**< The timestamp for the frame.
+                                      * The timestanp is unique for each frame on a port
+                                      * but when multiple ports are running, the timestamp
+                                      * is the same for the matching frames on different ports.
+                                    */
+    uint32_t mWidth;                /**< Frame width. */
+    uint32_t mHeight;               /**< Frame haight. */
+    uint32_t mOffsetX;              /**< The offset in X-direction of the actual frame data inside the buffer. */
+    uint32_t mOffsetY;              /**< The offset in Y-direction of the actual frame data inside the buffer. */
+    uint32_t mStartX;               /**<  */
+    uint32_t mStartY;               /**<  */
+    uint32_t mLength;               /**< The image size in bytes. */
+    uint32_t mExtraDataLength;      /**< Size in bytes if extra data buffer. */
+    VisionCamMetadata mMetadata;    /**< Parsed meta data. */
+    uint32_t mDetectedFacesNum;     /**< Number of faces detected in this frame. */
+    VisionCamFaceType mFaces[ MAX_FACES_COUNT ];    /**< Informatin about detected faces. */
+};
+
+
+/** @class VisionCamFramePack
+  * A frame holder.
+  * This structure keeps the matching frames from all possinble sources.
+  * This is used when packaging option is enabled.
+  * Packaging is based on frame timestamp.
+*/
+class VisionCamFramePack
+{
+public:
+    VisionCamFramePack(){
+        for( int32_t i = 0; i < VCAM_PORT_MAX; i++) {
+            mFrame[i] = NULL;
+            mExpectedFrames[i] = false;
+        }
+        mTimestamp = 0;
+        mIsEmpty = true;
+    }
+
+    VisionCamFrame *mFrame[VCAM_PORT_MAX];  /**< Addresses of all the frames from all running sources */
+    int64_t         mTimestamp;             /**< Timestamp of these frames. The same for all*/
+
+    bool          mExpectedFrames[VCAM_PORT_MAX]; /**< Which frames must be written,
+                                                        corresponds to the frame sourcs state (running or not).
+                                                    */
+
+    bool          mIsEmpty;                       /**< Read only field:
+                                                        true when there is a valid data inside mFrame[]
+                                                        false when there is no valid data inside mFrame[]
+                                                    */
+};
+
+/** @typedef Frame callback type.
+*/
+typedef void (*FrameCallback_f)(VisionCamFrame *cameraFrame);
+
+/** @typedef Frame callback type,
+  * used to pass multiple frames in a single shot.
+*/
+typedef void (*FramePackCallback_f)(VisionCamFramePack *cameraFramePacket);
+
+/** @typedef Focus callback type.
+*/
+typedef void ( * FocusCallback_t )(int);
+
+/** VisionCam is a Mixin pattern which defines the abstract interface to the
+ * class which wraps the physical Camera and/or the USB/File based alternatives
+ * while implementing some of the common features of the class.
+ */
+class VisionCam
+{
+protected:
+    FrameCallback_f m_callback;             /**< The default callback for preview frames */
+    FramePackCallback_f m_pack_callback;    /**< The callback for frames received from all ports and sent in a single call to user*/
+    FocusCallback_t m_focuscallback;        /**< The default focus callback */
+    void * m_cookie;                        /**< The protected cookie data to pass to the m_callback */
+    uint32_t m_frameNum;                    /**< The current number of frames delivered since instantiation */
+public:
+    VisionCam():
+      m_callback(NULL),
+      m_pack_callback(NULL),
+      m_focuscallback(NULL),
+      m_cookie(NULL),
+      m_frameNum(0) {}
+
+    /** Deconstructor */
+    virtual ~VisionCam() {}
+
+    /** Initializing method */
+    virtual int init(void *cookie) = 0;
+
+    /** Deinitializer */
+    virtual int deinit() = 0;
+
+    /** This method informs the VisionCam to use the supplied buffer */
+    virtual int useBuffers( BufferMeta* meta, uint32_t num_images, VisionCamPort_e port = VCAM_PORT_PREVIEW) = 0;
+
+    /**  This method informs the VisionCam to stop using the supplied buffers */
+    virtual int releaseBuffers( VisionCamPort_e port = VCAM_PORT_PREVIEW ) = 0;
+
+    /** This method informs the VisionCam to recall any outstanding buffers from remote cores or to drop pending copies */
+    virtual int flushBuffers( VisionCamPort_e port = VCAM_PORT_PREVIEW ) = 0;
+
+    /** This method informs the VisionCam to execute some additional functionality */
+    virtual int sendCommand( VisionCamCmd_e cmdId, void *param = NULL, uint32_t size = 0, VisionCamPort_e port = VCAM_PORT_PREVIEW) = 0;
+
+    /** This method informs the VisionCam to configure itself with the supplied parameters */
+    virtual int setParameter( VisionCamParam_e paramId, void* param = NULL, uint32_t size = 0, VisionCamPort_e port = VCAM_PORT_PREVIEW) = 0;
+
+    /** This method informs the VisionCam to configure itself with the supplied parameters */
+    virtual int getParameter( VisionCamParam_e paramId, void* param = NULL, uint32_t size = 0, VisionCamPort_e port = VCAM_PORT_PREVIEW) = 0;
+
+    /** This method returns a used buffer to the VisionCam to use again in the future */
+    virtual int returnFrame( VisionCamFrame *cameraFrame ) = 0;
+
+public:
+    // Implemented Functions in this Mixin
+
+    /** This returns the number of frames read from the camera since initialization */
+    uint32_t GetFrameNumber();
+
+    /** This method informs the VisionCam to enable the callback to the client which informs the client about the preview frame */
+    int enablePreviewCbk(FrameCallback_f callback) {
+      int greError = 0;
+      if (m_callback == NULL) {
+        m_callback = callback;
+      } else {
+        greError = -EBADE;
+      }
+      return greError;
+    }
+
+    /** This method informs the VisionCam to enable the callback to the client which informs the client about all frames */
+    int enablePackedFramesCbk(FramePackCallback_f callback) {
+      int greError = 0;
+      if (m_pack_callback == NULL) {
+        m_pack_callback = callback;
+      } else {
+        greError = -EBADE;
+      }
+      return greError;
+    }
+
+    /** This method informs the VisionCam to disable the preview frame m_callback */
+    int disablePreviewCbk(FrameCallback_f callback) {
+    int greError = 0;
+    if (callback == m_callback) {
+      m_callback = NULL;
+    } else {
+      greError = -EBADE;
+    }
+    return greError;
+}
+
+    /** This method informs the VisionCam to disable the packed frames callback */
+    int disablePackedFramesCbk(FramePackCallback_f callback) {
+      int greError = 0;
+      if (callback == m_pack_callback) {
+        m_pack_callback = NULL;
+      } else {
+        greError = -EBADE;
+      }
+      return greError;
+    }
+
+
+    /** This method give the focus callback to camera */
+    int setFocusCallBack(FocusCallback_t callback) {
+      m_focuscallback = callback;
+      return 0;
+    }
+
+};
+
+uint32_t GetImageSize(uint32_t width, uint32_t height, uint32_t fourcc);
+
+#endif
+
diff --git a/omx_cam/VisionCamSimpleTest.cpp b/omx_cam/VisionCamSimpleTest.cpp
new file mode 100644 (file)
index 0000000..db556d6
--- /dev/null
@@ -0,0 +1,416 @@
+/** Copyright (C) 2010 Texas Instruments, Inc. All rights reserved */
+
+/** This is a simple, dumbed down version of the vcam_test which only uses
+    command line paramters and simple settings in order to test out system
+    connectivity, this is *not* intended to replace the more complicated
+    VisionCamTest.cpp. Use export VCAM_SIMPLE=1 to use this version.
+*/
+
+#include <limits.h>
+
+#include <autolock.h>
+#include <output.h>
+
+#include <OMXVisionCam.h>
+
+/** The default number of display buffers */
+#define DISPLAY_NUM_BUFFERS (5)
+
+#define STATUS_FAILED(x)    (x < 0)
+
+#define CAMERA_NAME MODULE_NAME("vcam")
+
+typedef enum _option_type_e {
+    OPTION_TYPE_BOOL,
+    OPTION_TYPE_INT,
+    OPTION_TYPE_HEX,
+    OPTION_TYPE_FLOAT,
+    OPTION_TYPE_STRING,
+} option_type_e;
+
+typedef struct _option_t {
+    option_type_e type;
+    void *datum;
+    size_t size;
+    const char *short_switch;
+    const char *long_switch;
+    const char *description;
+} option_t;
+
+size_t option_process(int argc, char *argv[], option_t *opts, size_t numOpts)
+{
+    int i;
+    size_t j,c = 0;
+    for (i = 0; i < argc; i++)
+    {
+        for (j = 0; j < numOpts; j++)
+        {
+            if ((opts[j].short_switch && strcmp(opts[j].short_switch, argv[i]) == 0) ||
+                (opts[j].long_switch && strcmp(opts[j].long_switch, argv[i]) == 0))
+            {
+                switch (opts[j].type)
+                {
+                    case OPTION_TYPE_BOOL:
+                        *(bool *)opts[j].datum = true;
+                        c++;
+                        break;
+                    case OPTION_TYPE_INT:
+                        if (i+1 < argc && opts[j].size == sizeof(int)) {
+                            i += 1;
+                            sscanf(argv[i],"%d",(int *)opts[j].datum);
+                            c++;
+                        }
+                        break;
+                    case OPTION_TYPE_HEX:
+                        if (i+1 < argc && opts[j].size == sizeof(uint32_t)) {
+                            i += 1;
+                            sscanf(argv[i],"%x",(uint32_t *)opts[j].datum);
+                            c++;
+                        }
+                        break;
+                    case OPTION_TYPE_FLOAT:
+                        if (i+1 < argc && opts[j].size == sizeof(float)) {
+                            i += 1;
+                            sscanf(argv[i],"%f",(float *)opts[j].datum);
+                            c++;
+                        }
+                        break;
+                    case OPTION_TYPE_STRING:
+                        if (i+1 < argc) {
+                            i += 1;
+                            strncpy(static_cast<char*>(opts[j].datum), argv[i], opts[j].size);
+                            c++;
+                        }
+                        break;
+                }
+                break; // process next argv
+            }
+        }
+    }
+    return c;
+}
+
+int32_t display_width;
+int32_t display_height;
+int32_t width;
+int32_t height;
+int32_t fps;
+uint32_t color;
+char fourcc_str[5];
+int32_t numImages;
+int32_t recvFrames;
+int32_t numFrames;
+int32_t sensor;
+int32_t frameLock;
+int32_t focusDepth;
+int32_t mode;
+int32_t camera_rotation;
+uint32_t screen_rotation;
+uint32_t dw,sw;
+uint32_t dh,sh;
+int32_t subsample;
+bool twoD;
+bool topBottom;
+bool file_ouput;
+char name[PATH_MAX];
+uint32_t numTimeouts;
+uint32_t white;
+uint32_t brightness;
+uint32_t iso;
+uint32_t exposure;
+bool manual;
+uint32_t repeats;
+option_t opts[] = {
+    {OPTION_TYPE_INT, &display_width, sizeof(display_width), "-dw",  "--display_width", "Width of display"},
+    {OPTION_TYPE_INT, &display_height, sizeof(display_height), "-dh",  "--display_height", "Height of display"},
+    {OPTION_TYPE_INT, &width, sizeof(width),              "-w",  "--width", "Width of image"},
+    {OPTION_TYPE_INT, &height, sizeof(height),            "-h",  "--height", "Height of image"},
+    {OPTION_TYPE_INT, &fps, sizeof(fps),                  "-f",  "--fps", "Frame Rate"},
+    {OPTION_TYPE_BOOL, &twoD, sizeof(twoD),               "-2d", "--two-d", "Use 2D buffers"},
+    {OPTION_TYPE_BOOL, &topBottom, sizeof(topBottom),     "-tb", "--topbottom", "Orient the stereo image as top/bottom"},
+    {OPTION_TYPE_STRING, &fourcc_str, sizeof(fourcc_str), "-c",  "--fourcc", "FOURCC Code as string (UYVY) "},
+    {OPTION_TYPE_STRING, name, sizeof(name),              "-n",  "--name", "Name of file to read"},
+    {OPTION_TYPE_INT, &numImages, sizeof(numImages),      "-i",  "--images", "Number of images to use"},
+    {OPTION_TYPE_INT, &numFrames, sizeof(numFrames),      "-#",  "--frames", "Number of frames to process"},
+    {OPTION_TYPE_INT, &sensor, sizeof(sensor),            "-s",  "--sensor", "Selects the sensor (0,1,2)"},
+    {OPTION_TYPE_INT, &frameLock, sizeof(frameLock),      "-l",  "--lock-after", "Locks AE/AWB after specified frame count"},
+    {OPTION_TYPE_INT, &focusDepth, sizeof(focusDepth),    "-fd", "--focus-depth", "Specific Focus Depth [0-150]"},
+    {OPTION_TYPE_INT, &mode, sizeof(mode),                "-p",  "--mode", "Capture Mode"},
+    {OPTION_TYPE_INT, &camera_rotation, sizeof(camera_rotation),"-cr", "--camera_rotation", "Rotates the captured image in the camera"},
+    {OPTION_TYPE_INT, &screen_rotation, sizeof(screen_rotation),"-sr", "--screen_rotation", "Rotates the display image"},
+    {OPTION_TYPE_INT, &subsample, sizeof(subsample),      "-sb", "--subsample", "Subsampled ratio, defaults to 1"},
+    {OPTION_TYPE_BOOL, &file_ouput, sizeof(file_ouput),   "-o",  "--out", "Write to file instead of display"},
+    {OPTION_TYPE_BOOL, &manual, sizeof(manual),           "-m",  "--manual", "Use manual settings"},
+    {OPTION_TYPE_INT, &white, sizeof(white),              "-wb", "--white", "White Balance Mode"},
+    {OPTION_TYPE_INT, &brightness, sizeof(brightness),    "-br", "--bright", "Brightness Value"},
+    {OPTION_TYPE_INT, &iso, sizeof(iso),                  "-is", "--iso", "ISO Value"},
+    {OPTION_TYPE_INT, &exposure, sizeof(exposure),        "-ex", "--exposure", "Manual Exposure Value"},
+    {OPTION_TYPE_INT, &numTimeouts, sizeof(numTimeouts),  "-to", "--timeouts", "Set the number of frame timeout which can occur before the camera halts"},
+    {OPTION_TYPE_INT, &repeats, sizeof(repeats),          "-r",  "--repeat", "Sets the number of repeat iterations, default is 1."},
+};
+
+struct CallbackData {
+  pthread_mutex_t            mutex;
+  std::list<VisionCamFrame*> frames;
+  CallbackData() {
+    pthread_mutex_init(&mutex, NULL);
+  }
+  ~CallbackData() {
+    pthread_mutex_destroy(&mutex);
+  }
+};
+
+void VisionCamTestCallback(VisionCamFrame* frame) {
+  CallbackData* cb_data = static_cast<CallbackData*>(frame->mCookie);
+
+  MSG("New frame received; offset=%ux%u", frame->mOffsetX, frame->mOffsetY);
+  AutoLock(&cb_data->mutex);
+  cb_data->frames.push_back(frame);
+}
+
+int main(int argc, char *argv[]) {
+  uint32_t r = 0;
+  int32_t i = 0;
+  VisionCamSensorSelection sensorIndex = VCAM_SENSOR_SECONDARY;
+  VisionCamCaptureMode capmode = VCAM_VIDEO_NORMAL;
+  VisionCamFlickerType flicker = FLICKER_60Hz;
+  VisionCamFocusMode focus = VCAM_FOCUS_CONTROL_AUTO;
+  VisionCamStereoInfo info;
+
+  // default values
+  white = VCAM_WHITE_BAL_CONTROL_AUTO;
+  brightness = 50; // [0-200]
+  iso = 100;       // [100-1600]
+  exposure = 50;   // [0-100]
+  manual = false;
+  recvFrames = 0;
+  display_width = 640;
+  display_height = 480;
+  width = 640;
+  height = 480;
+  fps = 30;
+  strcpy(fourcc_str, "NV12");
+  color = FOURCC_STR(fourcc_str);
+  strcpy(name, "car");
+  numImages = DISPLAY_NUM_BUFFERS;
+  sensor = OMX_TI_StereoSensor;
+  numFrames = 100;
+  frameLock = 0xFFFFFFFF;
+  focusDepth = -1;
+  mode = VCAM_VIDEO_NORMAL;
+  camera_rotation = 0;
+  screen_rotation = 0;
+  dw = 0;
+  dh = 0;
+  sw = 0;
+  sh = 0;
+  twoD = false;
+  topBottom = false;
+  subsample = 1;
+  file_ouput = false;
+  numTimeouts = 10;
+  repeats = 1;
+
+  option_process(argc, argv, opts, sizeof(opts)/sizeof(opts[0]));
+
+  // check for bad input
+  if (width <= 0) width = 160;
+  if (height <= 0) height = 120;
+  if (sw <= 0) sw = width;
+  if (sh <= 0) sh = height;
+  if (numImages <= 2) numImages = 2;
+  if (fps <= 15) fps = 15;
+  if (numFrames <= 10) numFrames = 10;
+  if (frameLock > numFrames) frameLock = -1;
+  if (focusDepth > 150) focusDepth = 75;
+  if (mode >= VCAM_CAP_MODE_MAX) mode = VCAM_GESTURE_MODE;
+  if (sensor > 2) sensor = 2;
+  if (camera_rotation != 0 && camera_rotation != 90 && camera_rotation != 180 && camera_rotation != 270)
+      camera_rotation = 0;
+  else if (camera_rotation == 90 || camera_rotation == 270)
+  {
+      uint32_t t = sw;
+      sw = sh;
+      sh = t;
+  }
+  if (subsample <= 0 || subsample > 4)
+      subsample = 1;
+  if (brightness > 200)
+      brightness = 200;
+  if (iso < 100) iso = 100;
+  if (iso > 1600) iso = 1600;
+  if (exposure > 100) exposure = 100;
+  if (repeats == 0)
+      repeats = 1;
+
+  color = FOURCC_STR(fourcc_str);
+
+  MSG("Requested Color %08x", color);
+
+  switch (sensor)
+  {
+    case 2:
+      sensorIndex = VCAM_SENSOR_STEREO;
+      mode = VCAM_STEREO_MODE;
+      memset(&info, 0, sizeof(info));
+      if (topBottom) {
+        MSG("Enabling Stereo Use Case (top/bottom)!");
+        info.layout = VCAM_STEREO_LAYOUT_TOPBOTTOM;
+        height *= 2;
+      } else {
+        MSG("Enabling Stereo Use Case (side by side)!");
+        info.layout = VCAM_STEREO_LAYOUT_LEFTRIGHT;
+        width *= 2;
+      }
+      info.subsampling = subsample;
+      if (color != FOURCC('N','V','1','2')) {
+        ERROR("Only NV12 is supported for stereo");
+        exit(1);
+      }
+      break;
+    case 1:
+      MSG("Enabling Vision Mode on Front Camera");
+      sensorIndex = VCAM_SENSOR_SECONDARY;
+      mode = VCAM_VIDEO_NORMAL;
+      break;
+    default:
+      MSG("Enabling Vision Mode on Back Camera!");
+      sensorIndex = VCAM_SENSOR_PRIMARY;
+  }
+  capmode = (VisionCamCaptureMode)mode;
+
+  // using 1 to <= so prints will make sense
+  for (r = 1; r <= repeats; r++)
+  {
+    MSG("Iteration %u of %u", r, repeats);
+    recvFrames = 0;
+    OMXVisionCam omx_cam;
+    VisionCam *pCam = &omx_cam;
+    int greError = 0;
+
+    CallbackData cb_data;
+    VCAM_RETURN_IF_FAILED(greError, pCam->init(&cb_data));
+    VCAM_COMPLAIN_IF_FAILED(greError, pCam->setParameter(VCAM_PARAM_WIDTH, &width, sizeof(width)));
+    VCAM_COMPLAIN_IF_FAILED(greError, pCam->setParameter(VCAM_PARAM_HEIGHT, &height, sizeof(height)));
+    VCAM_COMPLAIN_IF_FAILED(greError, pCam->setParameter(VCAM_PARAM_COLOR_SPACE_FOURCC, &color, sizeof(color)));
+    // Can't set ROTATION here, see below
+    VCAM_COMPLAIN_IF_FAILED(greError, pCam->setParameter(VCAM_PARAM_FPS_FIXED, &fps, sizeof(fps)));
+    VCAM_COMPLAIN_IF_FAILED(greError, pCam->setParameter(VCAM_PARAM_CAP_MODE, &capmode, sizeof(capmode)));
+    VCAM_COMPLAIN_IF_FAILED(greError, pCam->setParameter(VCAM_PARAM_SENSOR_SELECT, &sensorIndex, sizeof(sensorIndex)));
+    if (capmode == VCAM_STEREO_MODE)
+    {
+        VCAM_COMPLAIN_IF_FAILED(greError, pCam->setParameter(VCAM_PARAM_STEREO_INFO, &info, sizeof(info)));
+    }
+
+    // VCAM_PARAM_2DBUFFER_DIM should only be called after resolutions, color space, cap mode, and
+    //   optionally stereo information is set.
+    VisionCamResType res = { VCAM_RESOL_MAX, width, height };
+    VCAM_COMPLAIN_IF_FAILED(greError, pCam->getParameter(VCAM_PARAM_2DBUFFER_DIM, &res, sizeof(res)));
+    MSG("Image: %ux%u, buffer: %ux%u", width, height, res.mWidth, res.mHeight);
+
+    Output* output = new Output(display_width, display_height, width, height,
+        res.mWidth, res.mHeight, color, numImages, twoD, file_ouput);
+    if (output->open() == 0)
+    {
+        VCAM_COMPLAIN_IF_FAILED(greError, pCam->setParameter(VCAM_PARAM_FLICKER, &flicker, sizeof(flicker)));
+        VCAM_COMPLAIN_IF_FAILED(greError, pCam->setParameter(VCAM_PARAM_AWB_MODE, &white, sizeof(white)));
+        if (manual)
+        {
+            VCAM_COMPLAIN_IF_FAILED(greError, pCam->setParameter(VCAM_PARAM_BRIGHTNESS, &brightness, sizeof(brightness)));
+            VCAM_COMPLAIN_IF_FAILED(greError, pCam->setParameter(VCAM_PARAM_EXPOSURE_ISO, &iso, sizeof(iso)));
+            VCAM_COMPLAIN_IF_FAILED(greError, pCam->setParameter(VCAM_PARAM_MANUAL_EXPOSURE, &exposure, sizeof(exposure)));
+        }
+        VCAM_COMPLAIN_IF_FAILED(greError, pCam->setParameter(VCAM_PARAM_NAME, name, sizeof(name)));
+
+        struct buffer* images[numImages];
+        BufferMeta meta[numImages];
+        for (i = 0; i < numImages; i++)
+        {
+            images[i] = output->alloc(&meta[i]);
+        }
+        // tell the camera to use all the camera index buffers
+        VCAM_COMPLAIN_IF_FAILED(greError, pCam->useBuffers(meta, numImages));
+
+        /** @todo Since the OMX Camera is probably being used by
+            the VCAM_SIMPLE test, we have to understand that
+            the OMX-CAMERA has a bug in the camera_rotation when used
+            during LOADED state. We have to wait until IDLE
+            (post useBuffers) or EXECUTING (post PREVIEW)
+            before rotating. */
+        /** @todo Additionally, OMX-CAMERA STEREO mode can't handle the rotation values! */
+        if (capmode != VCAM_STEREO_MODE)
+            VCAM_COMPLAIN_IF_FAILED(greError, pCam->setParameter(VCAM_PARAM_ROTATION, &camera_rotation, sizeof(camera_rotation)));
+
+        // register the engine callback with the camera
+        VCAM_COMPLAIN_IF_FAILED(greError,  pCam->enablePreviewCbk(VisionCamTestCallback));
+        VCAM_COMPLAIN_IF_FAILED(greError,  pCam->sendCommand(VCAM_CMD_PREVIEW_START));
+
+        if (focusDepth == -1) { // begin auto-focus
+            VCAM_COMPLAIN_IF_FAILED(greError,  pCam->setParameter(VCAM_PARAM_DO_AUTOFOCUS, &focus, sizeof(focus)));
+        }
+
+        if (greError == 0)
+        {
+            uint32_t timeouts = 0;
+            usleep(1000000/fps); // wait 1 frame period.
+            MSG("VisionCam is initialized, entering queue read loop!");
+            // read from the queue and display the images
+            do {
+              if (cb_data.frames.empty()) {
+                ERROR("Timedout waiting for buffer from Camera!");
+                timeouts++;
+                usleep(1000000/fps);
+                continue;
+              }
+              VisionCamFrame* frame;
+              {
+                AutoLock(&cb_data.mutex);
+                frame = cb_data.frames.front();
+                cb_data.frames.pop_front();
+              }
+              if (frame != NULL) {
+                BufferMeta* meta = static_cast<BufferMeta*>(frame->mFrameBuff);
+                timeouts = 0;
+                output->render(meta);
+                pCam->returnFrame(frame);
+                recvFrames++;
+                if (recvFrames >= numFrames) {
+                  break;
+                }
+                if (focusDepth >= 0) {
+                  if (recvFrames == fps) { // after 1 second
+                      VCAM_COMPLAIN_IF_FAILED(greError, pCam->setParameter(VCAM_PARAM_DO_MANUALFOCUS, &focusDepth, sizeof(focusDepth)));
+                  }
+                }
+                if (frameLock > 0) {
+                  if (recvFrames == frameLock) {
+                      bool lock = true;
+                      VCAM_COMPLAIN_IF_FAILED(greError, pCam->sendCommand(VCAM_CMD_LOCK_AE, &lock, sizeof(lock)));
+                      VCAM_COMPLAIN_IF_FAILED(greError, pCam->sendCommand(VCAM_CMD_LOCK_AWB, &lock, sizeof(lock)));
+                  }
+                }
+              }
+            } while (timeouts < numTimeouts);
+        }
+        else
+        {
+            ERROR("VCAM_TEST Failed during initialization (greError = %d, 0x%08x)!", greError, greError);
+        }
+
+        // destroy the camera
+        VCAM_COMPLAIN_IF_FAILED(greError, pCam->sendCommand(VCAM_CMD_PREVIEW_STOP));
+        VCAM_COMPLAIN_IF_FAILED(greError, pCam->disablePreviewCbk(VisionCamTestCallback));
+        VCAM_COMPLAIN_IF_FAILED(greError, pCam->releaseBuffers());
+        VCAM_COMPLAIN_IF_FAILED(greError, pCam->deinit());
+
+        // free the images
+        for (i = 0; i < numImages; i++){
+            output->free(&meta[i]);
+        }
+
+        output->close();
+        delete output;
+    }
+  }
+  return 0;
+}
diff --git a/omx_cam/autolock.h b/omx_cam/autolock.h
new file mode 100644 (file)
index 0000000..7fff1c9
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ *  Copyright (C) 2009-2011 Texas Instruments, 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.
+ */
+
+#ifndef _AUTOLOCK_H
+#define _AUTOLOCK_H
+
+#include <pthread.h>
+
+class AutoLock {
+  pthread_mutex_t* m_;
+public:
+  AutoLock(pthread_mutex_t* m): m_(m) {
+    pthread_mutex_lock(m_);
+  }
+  ~AutoLock() {
+    pthread_mutex_unlock(m_);
+  }
+};
+
+#endif // _AUTOLOCK_H
diff --git a/omx_cam/output.cpp b/omx_cam/output.cpp
new file mode 100644 (file)
index 0000000..1d69c96
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ *  Copyright (C) 2009-2012 Texas Instruments, 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 <limits.h>
+
+extern "C" {
+#include <util.h>
+}
+
+#include <config.h>
+#include <output.h>
+
+int Output::open() {
+  char* argv[10];
+  int argc = 0;
+  // Prog name
+  char prog[] = "omx_cam_test";
+  argv[argc++] = prog;
+  // 2D
+  char t_option[] = "-t";
+  char t_option_value[] = "auto";
+  if (twoD_) {
+    argv[argc++] = t_option;
+    argv[argc++] = t_option_value;
+  }
+  // Single plane buffers
+  char one_option[] = "-1";
+  if (! twoD_) {
+    argv[argc++] = one_option;
+  }
+  // KMS display size (ignore by X11)
+  char s_option[] = "-s";
+  char s_option_value[32];
+  sprintf(s_option_value, "%d:%dx%d", 6, display_width_, display_height_);
+  argv[argc++] = s_option;
+  argv[argc++] = s_option_value;
+  // X11 window size (ignored by KMS)
+  char w_option[] = "-w";
+  char w_option_value[32];
+  sprintf(w_option_value, "%dx%d", image_width_, image_height_);
+  argv[argc++] = w_option;
+  argv[argc++] = w_option_value;
+  struct display* d = disp_open(argc, argv);
+  if (d == NULL) {
+    ERROR("Failed to open display");
+    return -1;
+  }
+  handle_ = d;
+  struct buffer** b = disp_get_vid_buffers(d, numBuffers_, color_,
+    buffer_width_, buffer_height_);
+  if (b == NULL) {
+    ERROR("Failed to create buffers");
+    return -1;
+  }
+  buffers_ = b;
+  // Also save to file
+  if (fd_ != NULL) {
+    char file_name[NAME_MAX + 1];
+    sprintf(file_name, "output_%dx%d_%dHz.raw", image_width_, image_height_, 30);
+    fd_ = fopen(file_name, "w");
+    if (fd_ == NULL) {
+      ERROR("%m opening file %s\n", file_name);
+      return -1;
+    }
+    MSG("Opened file %s\n", file_name);
+  }
+  return 0;
+}
+
+int Output::close() {
+  // Can't see what to call for display close
+  if (fd_ != NULL) {
+    return fclose(fd_);
+  }
+  return 0;
+}
+
+struct buffer* Output::alloc(BufferMeta* meta) {
+  struct display* d = static_cast<struct display*>(handle_);
+  struct buffer* b = disp_get_vid_buffer(d);
+  MSG(" -> buffer=%p w=%d h=%d fourcc=%x", b, b->width, b->height, b->fourcc);
+  if (meta) {
+    int p;
+    for (p = 0; p < b->nbo; ++p) {
+      meta->buffer = b;
+      meta->fd[p] = omap_bo_dmabuf(b->bo[p]);
+      meta->map[p] = omap_bo_map(b->bo[p]);
+      MSG(" ---> bo[%d]=%p pitch=%u fd=%d map=%p", p, b->bo[p], b->pitches[p],
+        meta->fd[p], meta->map[p]);
+    }
+  }
+  return b;
+}
+
+int Output::free(BufferMeta* meta) {
+  struct display* d = static_cast<struct display*>(handle_);
+  disp_put_vid_buffer(d, meta->buffer);
+  return 0;
+}
+
+int Output::render(BufferMeta* meta) {
+  struct display* d = static_cast<struct display*>(handle_);
+  int rc = disp_post_vid_buffer(d, meta->buffer, 0, 0, image_width_, image_height_);
+  if (fd_ != NULL) {
+    const char* buffer;
+    switch (meta->buffer->fourcc) {
+      case FOURCC('U','Y','V','Y'):
+      case FOURCC('Y','U','Y','V'):
+        buffer = static_cast<const char*>(meta->map[0]);
+        for (size_t y = 0; y < image_height_; ++y) {
+          size_t j = y * buffer_width_;
+          fwrite(&buffer[j], 1, image_width_ * 2, fd_);  // bpp = 16
+        }
+        break;
+      case FOURCC('N','V','1','2'):
+        buffer = static_cast<const char*>(meta->map[0]);
+        for (size_t y = 0; y < image_height_; ++y) {
+          size_t j = y * buffer_width_;
+          fwrite(&buffer[j], 1, image_width_, fd_);
+        }
+        if (meta->buffer->nbo == 1) {
+          buffer += meta->buffer->width * meta->buffer->height;
+          for (size_t y = 0; y < image_height_ / 2; ++y) {
+            size_t j = y * buffer_width_;
+            fwrite(&buffer[j], 1, image_width_, fd_);
+          }
+        } else {
+          buffer = static_cast<const char*>(meta->map[1]);
+          for (size_t y = 0; y < image_height_ / 2; ++y) {
+            size_t j = y * buffer_width_;
+            fwrite(&buffer[j], 1, image_width_, fd_);
+          }
+        }
+        break;
+      default:
+        errno = EINVAL;
+        return -1;
+    }
+  }
+  return rc;
+}
diff --git a/omx_cam/output.h b/omx_cam/output.h
new file mode 100644 (file)
index 0000000..a17574a
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ *  Copyright (C) 2009-2012 Texas Instruments, 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.
+ */
+
+#ifndef _OUTPUT_H
+#define _OUTPUT_H
+
+#include <stdio.h>
+
+extern "C" {
+#include <util.h>
+}
+
+struct BufferMeta {
+  struct buffer* buffer;
+  int fd[4];
+  void* map[4];
+  BufferMeta() {
+    for (size_t i = 0; i < 4; ++i) {
+      fd[i] = 0;
+      map[i] = NULL;
+    }
+  }
+};
+
+/*!
+ * \file output.h
+ * \brief Allocation code based on Rob's
+ * \author Hervé Fache
+ */
+
+class Output {
+protected:
+  uint32_t display_width_;
+  uint32_t display_height_;
+  uint32_t image_width_;
+  uint32_t image_height_;
+  uint32_t buffer_width_;
+  uint32_t buffer_height_;
+  uint32_t color_;
+  uint32_t numBuffers_;
+  bool     twoD_;
+  FILE*    fd_;
+  void* handle_;
+  void* buffers_;
+public:
+  /**
+  * @param display_width The width of the display, needs to be supported!
+  * @param display_height The height of the display, needs to be supported!
+  * @param image_width The width of the raw image
+  * @param image_height The height of the raw image
+  * @param buffer_width The requested width of the buffer
+  * @param buffer_height The requested height of the buffer
+  * @param color The FOURCC color space to use.
+  * @param numBuffers The number of desired buffers to internally allocate.
+  */
+  Output(
+      uint32_t display_width, uint32_t display_height,
+      uint32_t image_width, uint32_t image_height,
+      uint32_t buffer_width, uint32_t buffer_height,
+      uint32_t color, uint32_t numBuffers, bool twoD, bool save = false):
+    display_width_(display_width), display_height_(display_height),
+    image_width_(image_width), image_height_(image_height),
+    buffer_width_(buffer_width), buffer_height_(buffer_height),
+    color_(color), numBuffers_(numBuffers), twoD_(twoD),
+    fd_(save ? stdout /* does not matter, just not NULL */ : NULL) {}
+  int open();
+  int close();
+  struct buffer* alloc(BufferMeta* meta);
+  int free(BufferMeta* meta);
+  int render(BufferMeta* meta);
+};
+
+#endif // _OUTPUT_H
+