text: /* Copyright Statement:
   *
   * This software/firmware and related documentation ("MediaTek Software") are
   * protected under relevant copyright laws. The information contained herein is
   * confidential and proprietary to MediaTek Inc. and/or its licensors. Without
   * the prior written permission of MediaTek inc. and/or its licensors, any
   * reproduction, modification, use or disclosure of MediaTek Software, and
   * information contained herein, in whole or in part, shall be strictly
   * prohibited.
   * 
   * MediaTek Inc. (C) 2010. All rights reserved.
   * 
   * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
   * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
   * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
   * ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL
   * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
   * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
   * NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH
   * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
   * INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES
   * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
   * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
   * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK
   * SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE
   * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
   * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S
   * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE
   * RELEASED HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE
   * MEDIATEK SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
   * CHARGE PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
   */
  /*
   * Copyright (C) 2008 The Android Open Source Project
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  /* ---- includes ----------------------------------------------------------- */
  
  #include "SDK_Internal.h"
  #include "b_BasicEm/Functions.h"
  
  /* ------------------------------------------------------------------------- */
  
  /* ========================================================================= */
  /*                                                                           */
  /* ---- functions ---------------------------------------------------------- */
  /*                                                                           */
  /* ========================================================================= */
  
  /* ------------------------------------------------------------------------- */
  
  void btk_SDK_init( struct btk_SDK* ptrA )
  {
  	bbs_Context_init( &ptrA->contextE );
  	ptrA->hidE = btk_HID_SDK;
  	ptrA->refCtrE = 0;
  	ptrA->mallocFPtrE = NULL;
  	ptrA->freeFPtrE = NULL;
  	ptrA->errorFPtrE = NULL;
  	ptrA->maxImageWidthE = 0;
  	ptrA->maxImageHeightE = 0;
  }
  
  /* ------------------------------------------------------------------------- */
  
  void btk_SDK_exit( struct btk_SDK* ptrA )
  {
  	bbs_Context_exit( &ptrA->contextE );
  	ptrA->hidE = btk_HID_SDK;
  	ptrA->refCtrE = 0;
  	ptrA->mallocFPtrE = NULL;
  	ptrA->freeFPtrE = NULL;
  	ptrA->errorFPtrE = NULL;
  	ptrA->maxImageWidthE = 0;
  	ptrA->maxImageHeightE = 0;
  }
  
  /* ------------------------------------------------------------------------- */
  
  /* malloc wrapper */
  void* btk_malloc( struct bbs_Context* cpA,
  				  const struct bbs_MemSeg* memSegPtrA,
  				  uint32 sizeA )
  {
  	btk_HSDK hsdkL = ( btk_HSDK )cpA;
  	if( hsdkL->mallocFPtrE != NULL )
  	{
  		return hsdkL->mallocFPtrE( sizeA );
  	}
  	else
  	{
  		return NULL;
  	}
  }
  
  /* ------------------------------------------------------------------------- */
  
  /** error handler wrapper */
  void btk_error( struct bbs_Context* cpA )
  {
  	btk_HSDK hsdkL = ( btk_HSDK )cpA;
  	if( hsdkL->errorFPtrE != NULL )
  	{
  		hsdkL->errorFPtrE( hsdkL );
  	}
  }
  
  /* ------------------------------------------------------------------------- */
  
  btk_SDKCreateParam btk_SDK_defaultParam()
  {
  	btk_SDKCreateParam paramL;
  	paramL.fpError = NULL;
  	paramL.fpMalloc = NULL;
  	paramL.fpFree = NULL;
  	paramL.pExMem = NULL;
  	paramL.sizeExMem = 0;
  	paramL.pShMem = NULL;
  	paramL.sizeShMem = 0;
  	paramL.licenseKey = NULL;
  	paramL.maxImageWidth = 0;
  	paramL.maxImageHeight = 0;
  	return paramL;
  }
  
  /* ------------------------------------------------------------------------- */
  
  btk_Status btk_SDK_create( const btk_SDKCreateParam* pCreateParamA,
  						   btk_HSDK* hpsdkA )
  {
  	btk_HSDK hsdkL = NULL;
  	if( hpsdkA == NULL )	return btk_STATUS_INVALID_HANDLE;
  	if( *hpsdkA != NULL )	return btk_STATUS_INVALID_HANDLE;
  
  	if( pCreateParamA->fpMalloc != NULL )
  	{
  		if( pCreateParamA->fpFree == NULL ) return btk_STATUS_INVALID_HANDLE;
  
  		/* allocate context */
  		hsdkL = ( btk_HSDK )pCreateParamA->fpMalloc( bbs_SIZEOF8( struct btk_SDK ) );
  		if( hsdkL == NULL ) return btk_STATUS_INVALID_HANDLE;
  
  		btk_SDK_init( hsdkL );
  
  		/* initialize SDK context */
  		hsdkL->mallocFPtrE	= pCreateParamA->fpMalloc;
  		hsdkL->freeFPtrE	= pCreateParamA->fpFree;
  		hsdkL->errorFPtrE	= pCreateParamA->fpError;
  
  		/* initialize core context */
  		bbs_Context_quickInit( &hsdkL->contextE, btk_malloc, pCreateParamA->fpFree, btk_error );
  		if( bbs_Context_error( &hsdkL->contextE ) ) return btk_STATUS_ERROR;
  	}
  	else
  	{
  		uint16* exMemPtrL = ( uint16* )pCreateParamA->pExMem;
  		uint32 exMemSizeL = pCreateParamA->sizeExMem >> 1;
  
  		if( pCreateParamA->pExMem == NULL )					 return btk_STATUS_INVALID_HANDLE;
  		if( pCreateParamA->pShMem == NULL )					 return btk_STATUS_INVALID_HANDLE;
  		if( pCreateParamA->pExMem == pCreateParamA->pShMem ) return btk_STATUS_INVALID_HANDLE;
  
  		if( pCreateParamA->sizeExMem < bbs_SIZEOF16( struct btk_SDK ) ) return btk_STATUS_INVALID_HANDLE;
  
  		/* allocate context */
  		hsdkL = ( btk_HSDK )exMemPtrL;
  		exMemPtrL  += bbs_SIZEOF16( struct btk_SDK );
  		exMemSizeL -= bbs_SIZEOF16( struct btk_SDK );
  
  		btk_SDK_init( hsdkL );
  
  		hsdkL->errorFPtrE	= pCreateParamA->fpError;
  		hsdkL->contextE.errorHandlerE = btk_error;
  
  		/* initialize core context */
  		bbs_Context_addStaticSeg( &hsdkL->contextE, exMemPtrL, exMemSizeL, FALSE, 0 );
  		bbs_Context_addStaticSeg( &hsdkL->contextE, pCreateParamA->pShMem, pCreateParamA->sizeShMem >> 1, TRUE, 0 );
  	}
  
  	hsdkL->maxImageWidthE = pCreateParamA->maxImageWidth;
  	hsdkL->maxImageHeightE = pCreateParamA->maxImageHeight;
  
  	*hpsdkA = hsdkL;
  	return btk_STATUS_OK;
  }
  
  /* ------------------------------------------------------------------------- */
  
  btk_Status btk_SDK_close( btk_HSDK hsdkA )
  {
  	const char* fNameL = "btk_SDK_close";
  
  	if( hsdkA == NULL )							return btk_STATUS_INVALID_HANDLE;
  	if( hsdkA->hidE != btk_HID_SDK )			return btk_STATUS_INVALID_HANDLE;
  	if( bbs_Context_error( &hsdkA->contextE ) ) return btk_STATUS_PREEXISTING_ERROR;
  
  	if( hsdkA->refCtrE > 0 )
  	{
  		bbs_Context_pushError( &hsdkA->contextE,
  			                   bbs_Error_create( bbs_ERR_ERROR, 0, NULL, "%s:\nThis SDK context is still in use by %i objects!\n"
  							                                             "Close all instances of the context scope first.\n",
  																		  fNameL,
  																		  hsdkA->refCtrE ) );
  
  		return btk_STATUS_ERROR;
  	}
  
  	if( hsdkA->freeFPtrE )
  	{
  		btk_fpFree freeFPtrL = hsdkA->freeFPtrE;
  		btk_SDK_exit( hsdkA );
  		freeFPtrL( hsdkA );
  	}
  	else
  	{
  		btk_SDK_exit( hsdkA );
  	}
  
  	/* btk_SDK_exit clears error stack and does not produce an error condition */
  
  	return btk_STATUS_OK;
  }
  
  /* ------------------------------------------------------------------------- */
  
  btk_Error btk_SDK_getError( btk_HSDK hsdkA, char* msgBufA, u32 msgBufSizeA )
  {
  	if( hsdkA == NULL )					return btk_ERR_CORRUPT_DATA;
  	if( hsdkA->hidE != btk_HID_SDK )	return btk_STATUS_INVALID_HANDLE;
  
  	if( bbs_Context_error( &hsdkA->contextE ) )
  	{
  		struct bbs_Error errL = bbs_Context_popError( &hsdkA->contextE );
  		if( msgBufA != NULL ) bbs_strncpy( msgBufA, errL.textE, msgBufSizeA );
  		switch( errL.errorE )
  		{
  			case bbs_ERR_OUT_OF_MEMORY:		return btk_ERR_MEMORY;
  			case bbs_ERR_MEMORY_OVERFLOW:	return btk_ERR_MEMORY;
  			case bbs_ERR_WRONG_VERSION:		return btk_ERR_VERSION;
  			case bbs_ERR_CORRUPT_DATA:		return btk_ERR_CORRUPT_DATA;
  			default:						return btk_ERR_INTERNAL;
  		}
  	}
  
  	return btk_ERR_NO_ERROR;
  }
  
  /* ------------------------------------------------------------------------- */
  
  u32 btk_SDK_exAllocSize( btk_HSDK hsdkA )
  {
  	if( hsdkA == NULL )					return 0;
  	if( hsdkA->hidE != btk_HID_SDK )	return 0;
  	return ( bbs_Context_exclAllocSize( &hsdkA->contextE, 0 ) * 2 ) + bbs_SIZEOF8( struct btk_SDK );
  }
  
  /* ------------------------------------------------------------------------- */
  
  u32 btk_SDK_shAllocSize( btk_HSDK hsdkA )
  {
  	if( hsdkA == NULL )					return 0;
  	if( hsdkA->hidE != btk_HID_SDK )	return 0;
  	return bbs_Context_shrdAllocSize( &hsdkA->contextE, 0 ) * 2;
  }
  
  /* ------------------------------------------------------------------------- */
  
  u32 btk_SDK_allocSize( btk_HSDK hsdkA )
  {
  	return  btk_SDK_exAllocSize( hsdkA ) + btk_SDK_shAllocSize( hsdkA );
  }
  
  /* ------------------------------------------------------------------------- */
  
  btk_Status btk_SDK_paramConsistencyTest( struct btk_SDK* hsdkA,
  										 const void* memPtrA,
  										 u32 memSizeA,
  										 const char* fNameA )
  {
  	const uint16* memPtrL = ( uint16* )memPtrA;
  	uint32 memSizeL;
  	uint32 iL;
  	uint16 sumL = 0;
  
  	if( memSizeA < sizeof( memSizeL ) )
  	{
  		bbs_Context_pushError( &hsdkA->contextE,
  							   bbs_Error_create( bbs_ERR_ERROR, 0, NULL,
  					               "%s:\nCorrupt parameter data.", fNameA ) );
  		return btk_STATUS_ERROR;
  	}
  
  	memPtrL += bbs_memRead32( &memSizeL, memPtrL );
  
  	if( memSizeA < ( memSizeL << 1 ) )
  	{
  		bbs_Context_pushError( &hsdkA->contextE,
  							   bbs_Error_create( bbs_ERR_ERROR, 0, NULL,
  					               "%s:\nCorrupt parameter data.", fNameA ) );
  		return btk_STATUS_ERROR;
  	}
  
  	memPtrL = ( uint16* )memPtrA;
  
  	for( iL = 0; iL < memSizeL; iL++ )
  	{
  		uint16 valL = 0;
  		memPtrL += bbs_memRead16( &valL, memPtrL );
  		sumL += valL;
  	}
  
      if( sumL != 0xFFFF )
  	{
  		bbs_Context_pushError( &hsdkA->contextE,
  							   bbs_Error_create( bbs_ERR_ERROR, 0, NULL,
  					               "%s:\nChecksum error; corrupt parameter data.", fNameA ) );
  		return btk_STATUS_ERROR;
  	}
  
  	return btk_STATUS_OK;
  }
  
  /* ------------------------------------------------------------------------- */
  
  /* ========================================================================= */
  