/*****************************************************************************
Copyright (c) 2000-2003 Analog Devices. All Rights Reserved.

Developed by Analog Devices Australia - Unit 3, 97 Lewis Road,
Wantirna, Victoria, Australia, 3152. Email: ada.info@analog.com

THIS SOFTWARE IS PROPRIETARY & CONFIDENTIAL. By using this module you
agree to the terms of the associated Analog Devices License Agreement.
******************************************************************************

$RCSfile: JPEG_BitsBuffer.c,v $
$Revision: 1.1 $
$Date: 2008/03/17 14:26:45 $

Project:	JPEG IMAGE CODEC
Title:		Example BitsBuffer module
Author(s):	D. George, A. Sarumpaet, PSSBK Gupta
Revised by:

Description:
Bitstream Data Buffer Managing Module

References:

******************************************************************************
Tab Setting:			4
Target Processor:		Blackfin 
Target Tools Revision:	VDSP++ 3.5
******************************************************************************

Modification History:
====================
$Log: JPEG_BitsBuffer.c,v $
Revision 1.1  2008/03/17 14:26:45  gstephan
Updates for SDK 3.00

Revision 1.7  2004/08/30 02:17:18  sto
Checkin of all decoder related files from Conrad Jakob

Revision 1.5  2004/06/04 05:24:50  sto
jpeg encoder/decoder integrated

Revision 1.4  2004/05/28 02:50:10  sto
minor clean up

Revision 1.3  2004/05/27 22:42:51  sto
debugged for encoder operation

Revision 1.2  2004/05/20 01:06:03  sto
Checkin of Ver 0.3 delivered by Adrian Sarumpaet

Revision 2.0  2004/02/18 01:01:01  A. Sarumpaet
Added decoder bits buffer functions.
Replaced all tPutBitsBuffer with tBitsBuffer.

Revision 1.3  2003/11/18 01:01:01  D. George
Added DMA support

Revision 1.2  2003/11/06 01:01:01  D. George
Replaced all tBitBufferJpegEnc's with tPutBitsBuffer. Moved to standard template.

Revision 1.1  2003/09/18 01:01:01  A. Sarumpaet
BitsBuffer additions

Revision 1.0  2003/03/03 01:01:01  PSSBK Gupta
Initial code

******************************************************************************/

#include <stdlib.h>				// For NULL
#include <stdio.h>              // For fread()
#include <string.h>             // For memset()

#include "IMG_Common.h"             // common JPEG definitions
#include "JPEG_api_common.h"		// 
#include "JPEG_memalloc.h"		    // User defined function prototypes
#include "JPEG_bitsbuffer.h"		// User defined typedefs

/* Bits Buffer functions: */
 tBitsBuffer      *JPEG_BitsBuffer_NEW(void);
 int              JPEG_BitsBuffer_CONFIG(tBitsBuffer *handle, eBitsBuf_config item, unsigned int value);
 int              JPEG_BitsBuffer_INIT(tBitsBuffer *handle);
 void             JPEG_BitsBuffer_DELETE(tBitsBuffer *handle);
 int              JPEG_BitsBuffer_RESET(tBitsBuffer *handle);

/* Encoder Bits Buffer functions: */
 unsigned char    *JPEG_BitsBuffer_REQUEST(tBitsBuffer *handle);
 int              JPEG_BitsBuffer_WRITE(tBitsBuffer *handle, int numBytes);
 int              JPEG_BitsBuffer_FLUSH(tBitsBuffer *handle);

/* Decoder Bits Buffer functions: */
 int				JPEG_BitsBuffer_READ (tBitsBuffer *handle);
// extern unsigned char	*JPEG_BitsBuffer_PROCESS (tBitsBuffer *handle);
 unsigned char    *JPEG_BitsBuffer_PROCESS(tBitsBuffer *handle, int *pNumBytes);
 void				JPEG_BitsBuffer_RELEASE (tBitsBuffer *handle);


#if USE_DMA
#include "BitsBufferDMA.h"		// DMA prototypes
#endif // USE_DMA

#define BITSTREAM_FILE_BUFFER_SIZE 1000000 /* approx 1 MB */
#define DECODER_SINGLE_BUFFERED /* This implementation is ONLY single buffered for DECODER */
/* The double buffer mode is currently broken for the decoder */

/****************************************************************************
 *		Local variables													    *
 ****************************************************************************/
/* Bitstream Constants: */

static const int    BITS_BUF_DESBUF_SIZE = 1024;    /* Size of each buffer */

/****************************************************************************
 * 		Function Declarations												*
 ****************************************************************************/


/*
********************************************************************************
** Function:		JPEG_BitsBuffer_NEW
**
** Description:		Creates a new instance of Bit Stream buffer object.
**                  Used in JPEG ENCODER & DECODER.
**
** Arguments:		None
**
** Outputs:
**
** Return value:	Handle to new Bit Stream buffer instance
********************************************************************************
*/
tBitsBuffer *JPEG_BitsBuffer_NEW(void)
{
	tBitsBuffer		*bitsbuf = NULL;
	MemObjHandle    *MemObj; 

    // Note: previous code had the TempBuffers (PROGRESSIVE) being 1024 large, and the
    // LOSSLESS buffers being dependent on the following formula:
    //	lTemp = (int32)(imageEncParam->maxXDimension * 1.5);
    //	if(lTemp < 2048)
    //		lTemp = 2048;

	MemObj = JPEG_MemAlloc_NEW(1, sizeof(tBitsBuffer), MEM_TYPE_OBJECT);
	if (MemObj==NULL)
		return NULL;

	bitsbuf = (tBitsBuffer *)JPEG_MemAlloc_ADDRESS(MemObj);

	// Reset bitsbuffer to zero - good for second and subsequent calls
	memset (bitsbuf,  0, sizeof(tBitsBuffer));

    // Save pointer to the tBitsBuffer's own memory allocation object
	bitsbuf->ThisMemObj = MemObj;

	MemObj = NULL;
	bitsbuf->desBuffer1 = NULL;

	MemObj = JPEG_MemAlloc_NEW(1, BITS_BUF_DESBUF_SIZE * sizeof(uint8), MEM_TYPE_DATA);
	if (MemObj==NULL)
	{
    // Deallocate previously allocated memory
		JPEG_MemAlloc_DELETE(bitsbuf->ThisMemObj);
		return NULL;
	}

	bitsbuf->desBuffer1 = (uint8 *)JPEG_MemAlloc_ADDRESS(MemObj);

    // Save pointer to desBuffer1's memory allocation object
	bitsbuf->BufferMemObjs[0] = MemObj;

	MemObj = NULL;
	bitsbuf->desBuffer2 = NULL;

	MemObj = JPEG_MemAlloc_NEW(1, BITS_BUF_DESBUF_SIZE * sizeof(uint8), MEM_TYPE_DATA);
	if (MemObj==NULL)
	{
    // Deallocate previously allocated memory
		JPEG_MemAlloc_DELETE(bitsbuf->BufferMemObjs[0]);
		JPEG_MemAlloc_DELETE(bitsbuf->ThisMemObj);
		return NULL;
	}

	bitsbuf->desBuffer2 = (uint8 *)JPEG_MemAlloc_ADDRESS(MemObj);

    // Save pointer to desBuffer1's memory allocation object
	bitsbuf->BufferMemObjs[1] = MemObj;
	
	
	return bitsbuf;
}

/*
********************************************************************************
** Function:		JPEG_BitsBuffer_DELETE
**
** Description:		This function deletes the Bit Stream buffer object.
**                  Used in JPEG ENCODER & DECODER.
**
** Arguments:
**	bitsbuf [IN]	Handle to the Bit Stream data access instance.
**
** Outputs:
**
** Return value:	None
********************************************************************************
*/
void JPEG_BitsBuffer_DELETE (tBitsBuffer *bitsbuf)
{
	// Deallocate buffer memory objects
	JPEG_MemAlloc_DELETE(bitsbuf->BufferMemObjs[1]);
	JPEG_MemAlloc_DELETE(bitsbuf->BufferMemObjs[0]);
	
	// Deallocate Bit Stream Buffer memory object
//	if(!bitsbuf->is_encoder) /* only for decoder */
//    {
//     	JPEG_MemAlloc_DELETE(bitsbuf->DecodeBitStreamMemObj);
//    }

	// Deallocate tBitsBuffer memory object last
	JPEG_MemAlloc_DELETE(bitsbuf->ThisMemObj);
}

/*
********************************************************************************
** Function:		JPEG_BitsBuffer_CONFIG
**
** Description:		This function configures the instance of a Bit Stream
**					buffer object with the given configuration value.
**                  Called in both JPEG ENCODER & DECODER, but only has
**                  functionality in Encoder at this stage.
**
** Arguments:
**	bitsbuf [IN]	Handle to the Bit Stream data access instance.
**	item [IN]		item to configure.
**	value[IN]		Configuration value.
**
** Outputs:
**
** Return value:	1 if successful; 0 otherwise
********************************************************************************
*/
int JPEG_BitsBuffer_CONFIG(tBitsBuffer *bitsbuf, eBitsBuf_config item, unsigned int value)
{
	switch(item)
	{
		case BITSBUF_ENCODER:
			bitsbuf->is_encoder = value;
			break;
		
		case BITSBUF_POINTER:
		    /* Encoder instance uses this: */
			bitsbuf->externalBuffer = (unsigned char *)value;
			
			/* Decoder instance uses this: */
			bitsbuf->ptrFile = (tIMG_BufferInfo *)value;
			break;
			
		default:
			return 0;
	}

	return 1;
}

/*
********************************************************************************
** Function:		JPEG_BitsBuffer_INIT
**
** Description:		This function initialises the instance of an bit stream data
**					access object, allocating any memory. JPEG_BitsBuffer_CONFIG
**					must have been called before calling this function.
**                  Used in JPEG ENCODER & DECODER.
**
** Arguments:
**	bitsbuf [IN]	Handle to the Bit Stream data access instance.
**
** Outputs:
**
** Return value:	1 if successful; 0 otherwise
********************************************************************************
*/
int JPEG_BitsBuffer_INIT(tBitsBuffer *bitsbuf)
{
	MemObjHandle    *MemObj;
	int     error_code=0; 

	if(bitsbuf->is_encoder) /* Encoder specific initialisation */
	{
    	bitsbuf->numberOfBuffers = 2; /* double buffering scheme */
    	
    	error_code=1;
    }
    else /* Decoder specific initialisation */
	{
    	bitsbuf->numberOfBuffers = 1; /* single buffering scheme */

//    	MemObj = JPEG_MemAlloc_NEW(1, (BITSTREAM_FILE_BUFFER_SIZE+4) * sizeof(uint8), MEM_TYPE_DATA);
//    	if (MemObj!=NULL)
//    	{
//    
//        	bitsbuf->InputBitstreamFile = (uint8 *)JPEG_MemAlloc_ADDRESS(MemObj);
//        
//            // Save pointer to desBuffer1's memory allocation object
//        	bitsbuf->DecodeBitStreamMemObj = MemObj;
//        
//        	bitsbuf->BitStreamFileSize = fread(bitsbuf->InputBitstreamFile, 1, BITSTREAM_FILE_BUFFER_SIZE, bitsbuf->ptrFile);
//        
//            if (!feof(bitsbuf->ptrFile))
//            {
//                printf("Input file is too big!\n");
//            }
//            else
//                 error_code=1;
//        }
        bitsbuf->BitStreamFileSize = bitsbuf->ptrFile->Length;
        bitsbuf->InputBitstreamFile = bitsbuf->ptrFile->Pointer;
        error_code=1;
    }
    
	return error_code;
}

/*
********************************************************************************
** Function:		JPEG_BitsBuffer_RESET
**
** Description:		This function resets the instance of a bit stream data access
**					object, setting all fields to default starting values.
**                  Used in JPEG ENCODER & DECODER.
** Arguments:
**	bitsbuf [IN]	Handle to the Bit Stream data access instance.
**
** Outputs:
**
** Return value:	1 if successful; 0 otherwise
********************************************************************************
*/
int JPEG_BitsBuffer_RESET(tBitsBuffer *bitsbuf)
{
	/* Encoder-only: */
	bitsbuf->dmaInitiateThreshold = 256;
	bitsbuf->externalBufferIndex = 0;

	bitsbuf->numberOfEmptyBuffers = bitsbuf->numberOfBuffers;
	bitsbuf->writeBufferCount = 0;
	bitsbuf->nextBuffer = 1;			// to select a new buffer
	bitsbuf->firstOrsecondBuffer = 1;	// first new buffer will be 0.

	bitsbuf->numBytes = 0;
	
	/* Decoder-only: */
	bitsbuf->end_of_file = 0;
	
	bitsbuf->numBytesBuf_1 = 0;
	bitsbuf->numBytesBuf_2 = 0;
    
    bitsbuf->InputFilePosition = 0;

	return 1;
}

/*
********************************************************************************
** Function:		JPEG_BitsBuffer_REQUEST
**
** Description:		This function is used to obtain the next available Bit
**					Stream buffer about to be filled by the processed output
**					data.
**                  Used in JPEG ENCODER only.
** Arguments:
**	bitsbuf [IN]	Handle to the Bit Stream data access instance.
**
** Outputs:
**
** Return value:	Pointer to a empty data buffer ready for storing the
**					processing output.
********************************************************************************
*/
unsigned char *JPEG_BitsBuffer_REQUEST (tBitsBuffer *bitsbuf)
{
	unsigned char	*lPointer;

	if(bitsbuf->nextBuffer == 1)
	{
#if USE_DMA
#else
// check if there are some free buffers
		if(bitsbuf->numberOfEmptyBuffers > 0)
		{
			bitsbuf->numberOfEmptyBuffers--;
#endif // USE_DMA

			bitsbuf->firstOrsecondBuffer++;
			if(bitsbuf->firstOrsecondBuffer >= bitsbuf->numberOfBuffers)
			{
				bitsbuf->firstOrsecondBuffer = 0;
			}

			bitsbuf->nextBuffer = 0;

#if USE_DMA
// wait until buffer is ready...
// only need to check once 'numberOfBuffers' (ie 2) have been read.
// the first buffers are assumed to be "empty".
			if (bitsbuf->writeBufferCount >= bitsbuf->numberOfBuffers)
				dma_done(bitsbuf->dmaIDs[bitsbuf->firstOrsecondBuffer]);
#else
		}
		else
		{
			return (NULL);
		}
#endif // USE_DMA
	}

	if(bitsbuf->firstOrsecondBuffer == 0)
	{
		lPointer = bitsbuf->desBuffer1;
	}
	else
	{
		lPointer = bitsbuf->desBuffer2;
	}

	lPointer = lPointer + bitsbuf->numBytes;

	return(lPointer);
}

/*
********************************************************************************
** Function:		JPEG_BitsBuffer_WRITE
**
** Description:		This function is used to empty a data buffer after
**					processing.
**                  Used in JPEG ENCODER only.
**
** Arguments:
**	bitsbuf [IN]	Handle to the Bit Stream data access instance.
**	numBytes [IN]	Number of Bytes written into the buffer.
**
** Outputs:
**
** Return value:	E_TRUE or E_FALSE
********************************************************************************
*/
int JPEG_BitsBuffer_WRITE (tBitsBuffer *bitsbuf, int numBytes)
{
	int		lCount;

	bitsbuf->numBytes += numBytes;

	if(bitsbuf->numBytes > bitsbuf->dmaInitiateThreshold)
	{
		if(bitsbuf->firstOrsecondBuffer == 0)
		{
#if USE_DMA
			bitsbuf->dmaIDs[bitsbuf->firstOrsecondBuffer] = DMA_BitsBuffer(&bitsbuf->externalBuffer[bitsbuf->externalBufferIndex],
				bitsbuf->desBuffer1, bitsbuf->numBytes);
			bitsbuf->externalBufferIndex += bitsbuf->numBytes;
#else
			for(lCount = 0; lCount < bitsbuf->numBytes ; lCount++)
			{
				bitsbuf->externalBuffer[bitsbuf->externalBufferIndex++] =
					bitsbuf->desBuffer1[lCount];
			}
#endif // USE_DMA
//			bitsbuf->firstOrsecondBuffer = 1;
		}
		else
		{
#if USE_DMA
			bitsbuf->dmaIDs[bitsbuf->firstOrsecondBuffer] = DMA_BitsBuffer(&bitsbuf->externalBuffer[bitsbuf->externalBufferIndex],
				bitsbuf->desBuffer2, bitsbuf->numBytes);
			bitsbuf->externalBufferIndex += bitsbuf->numBytes;
#else
			for(lCount = 0; lCount < bitsbuf->numBytes ; lCount++)
			{
				bitsbuf->externalBuffer[bitsbuf->externalBufferIndex++] =
					bitsbuf->desBuffer2[lCount];
			}
#endif // USE_DMA
//			bitsbuf->firstOrsecondBuffer = 0;
		}
		bitsbuf->numBytes = 0;
		bitsbuf->nextBuffer = 1;
		bitsbuf->writeBufferCount++;

		bitsbuf->numberOfEmptyBuffers++;
	}

	return (E_TRUE);
}

/*
********************************************************************************
** Function:		JPEG_BitsBuffer_FLUSH
**
** Description:		This function flushes all the data buffers.
**                  Used in JPEG ENCODER only.
**
** Arguments:
**	bitsbuf [IN]	Handle to the Bit Stream data access instance.
**
** Outputs:
**
** Return value:	The number of bytes written (zero if unsuccessful).
********************************************************************************
*/
int JPEG_BitsBuffer_FLUSH (tBitsBuffer *bitsbuf)
{
	int	 lCount;

	if(bitsbuf->numBytes > 0)
	{
		if(bitsbuf->firstOrsecondBuffer == 0)
		{
#if USE_DMA
			bitsbuf->dmaIDs[bitsbuf->firstOrsecondBuffer] = DMA_BitsBuffer(&bitsbuf->externalBuffer[bitsbuf->externalBufferIndex],
				bitsbuf->desBuffer1, bitsbuf->numBytes);
			bitsbuf->externalBufferIndex += bitsbuf->numBytes;
#else
			for(lCount = 0; lCount < bitsbuf->numBytes ; lCount++)
			{
				bitsbuf->externalBuffer[bitsbuf->externalBufferIndex++] =
					bitsbuf->desBuffer1[lCount];
			}
#endif // USE_DMA
//			bitsbuf->firstOrsecondBuffer = 1;
		}
		else
		{
#if USE_DMA
			bitsbuf->dmaIDs[bitsbuf->firstOrsecondBuffer] = DMA_BitsBuffer(&bitsbuf->externalBuffer[bitsbuf->externalBufferIndex],
				bitsbuf->desBuffer2, bitsbuf->numBytes);
			bitsbuf->externalBufferIndex += bitsbuf->numBytes;
#else
			for(lCount = 0; lCount < bitsbuf->numBytes ; lCount++)
			{
				bitsbuf->externalBuffer[bitsbuf->externalBufferIndex++] =
					bitsbuf->desBuffer2[lCount];
			}
#endif // USE_DMA
//			bitsbuf->firstOrsecondBuffer = 0;
		}
		bitsbuf->numBytes = 0;
		bitsbuf->nextBuffer = 1;

		bitsbuf->numberOfEmptyBuffers++;
	}

	return bitsbuf->externalBufferIndex;
}

/*
********************************************************************************
Function Name: JPEG_BitsBuffer_READ
Parameters: 
	handle [IN]: Handle to Bit Stream Buffer data access instance.
Return Value: int : TRUE(1) or FALSE(0).
Description: This function is used to preload a data buffer for processing. 
			 FALSE is returned if there are no empty data buffers available for
			 filling.  This must be called at least once before calling the 
			 function JPEG_BitsBuffer_PROCESS.
             Used in JPEG DECODER only.
********************************************************************************
*/
int JPEG_BitsBuffer_READ(tBitsBuffer *bitsbuf)
{
    uint8           *pbuffer;
    int             *pBytesRead;
    int             lCnt;
    unsigned int    *lBuffWord,*pInput;
    
    // unsigned int    a[1024];

    if(bitsbuf->numberOfEmptyBuffers==0)
    {
        return E_FALSE;
    }
    
    if(bitsbuf->end_of_file)
    {
    	return E_TRUE;
    }
    
    /* Select the buffer to be filled: */   
#ifdef DECODER_SINGLE_BUFFERED
    pbuffer = bitsbuf->desBuffer1;
    pBytesRead = &bitsbuf->numBytesBuf_1;
#else
	if(bitsbuf->firstOrsecondBuffer == 0)
	{
	    pbuffer = bitsbuf->desBuffer1;
        pBytesRead = &bitsbuf->numBytesBuf_1;
		bitsbuf->firstOrsecondBuffer = 1;
	}
	else
	{
	    pbuffer = bitsbuf->desBuffer2;
        pBytesRead = &bitsbuf->numBytesBuf_2;
		bitsbuf->firstOrsecondBuffer = 0;
	}
#endif
	
	/* check if "end of file" has been reached*/
	if(bitsbuf->InputFilePosition >= bitsbuf->BitStreamFileSize)
	{
        bitsbuf->end_of_file = 1;
    	return E_TRUE;
	}

	/* Fill the buffer with a single block of data from the input file: */
	lCnt = bitsbuf->BitStreamFileSize - bitsbuf->InputFilePosition;
	*pBytesRead = (lCnt<BITS_BUF_DESBUF_SIZE) ? lCnt : BITS_BUF_DESBUF_SIZE;
	
	/* Reverse byte order for little-endian Blackfin processors */
	/* Copied from original Pre-Alpha function */
	lBuffWord = (unsigned int *)pbuffer;

	pInput = (unsigned int *)(bitsbuf->InputBitstreamFile + bitsbuf->InputFilePosition);
    bitsbuf->InputFilePosition += *pBytesRead;
    
	for(lCnt=0; lCnt<((*pBytesRead+3) >>2); lCnt++) /* the +3 is to make sure we round up when divide by 4 */
	{
		lBuffWord[lCnt] = SWAP_BYTE(pInput[lCnt]);
	}
	
	bitsbuf->numberOfEmptyBuffers--;

	return E_TRUE;	// success
}

/*
********************************************************************************
Function Name: JPEG_BitsBuffer_PROCESS
Parameters: 
	handle [IN]: Handle to Bit Stream Buffer data access instance.
Return Value: char * :      Pointer to the data buffer containing data ready for 
					        processing.
		      *pNumBytes:   Number of bytes available in buffer.
Description:This function is used to indicate to the system that the next 
			available Bit Stream buffer is about to be processed. 
			The Bit Stream data buffer must previously have been filled by a 
			call to the function JPEG_BitsBuffer_READ. When processing is 
			finished, the user must call JPEG_BitsBuffer_RELEASE to release the 
			data buffer. NULL is returned if there is no valid data buffer 
			available for processing.
            Used in JPEG DECODER only.
********************************************************************************
*/
unsigned char *JPEG_BitsBuffer_PROCESS(tBitsBuffer *bitsbuf, int *pNumBytes)
{
    uint8   *pbuffer;
    
    if(bitsbuf->numberOfEmptyBuffers==bitsbuf->numberOfBuffers)
    {
        return NULL;
    }

    if(bitsbuf->end_of_file)
    {
    	return NULL;
    }

    /* Process opposite buffer to buffer previously filled */
#ifdef DECODER_SINGLE_BUFFERED
    pbuffer = bitsbuf->desBuffer1;
	*pNumBytes = bitsbuf->numBytesBuf_1;
#else
	if(bitsbuf->firstOrsecondBuffer == 0)
	{
	    pbuffer = bitsbuf->desBuffer1;
	    *pNumBytes = bitsbuf->numBytesBuf_1;
	}
	else
	{
	    pbuffer = bitsbuf->desBuffer2;
	    *pNumBytes = bitsbuf->numBytesBuf_2;
	}
#endif

	return pbuffer;
}

/*
********************************************************************************
Function Name: JPEG_BitsBuffer_RELEASE 
Parameters:         handle [IN]: Handle to Bit Stream Buffer data access instance.
Return Value:       none.
Description: This function is used to release a data buffer that is currently 
			 being processed. This must be called after calling the function 
			 JPEG_BitsBuffer_PROCESS.
             Used in JPEG DECODER only.
********************************************************************************
*/
void JPEG_BitsBuffer_RELEASE(tBitsBuffer *bitsbuf)
{
    /* Release buffer that was last processed: */
    if(bitsbuf->end_of_file)
    {
    	return;
    }

    
#ifndef DECODER_SINGLE_BUFFERED   
	if(bitsbuf->firstOrsecondBuffer == 0)
	{
		bitsbuf->numBytesBuf_1 = 0;
		bitsbuf->firstOrsecondBuffer = 1;
	}
	else
	{
		bitsbuf->numBytesBuf_2 = 0;
		bitsbuf->firstOrsecondBuffer = 0;
	}
#endif
	bitsbuf->numberOfEmptyBuffers++;
}


/*
********************************************************************************
** Function:		JPEG_TempBuffer_CAT
**
** Description:		Concatenates a Temporary buffer and a Bits Buffer.
**                  For general use.
**
** Arguments:
**	src [IN]		Pointer to Temporary Bit Stream data access instance.
**	dest [OUT]		Pointer to Bit Stream data access instance.
**					NOTE: The destination Bit Stream memory must be
**					large enough to hold the concatenated data.
**
** Outputs:
**
** Return value:	None
********************************************************************************
*/

void JPEG_TempBuffer_CAT(tBitsBuffer *dest_buf, const tBitsBuffer *src_buf)
{
	unsigned char	*src_pointer = src_buf->externalBuffer;
	unsigned char	*dest_pointer = dest_buf->externalBuffer
											+ dest_buf->externalBufferIndex;
	int				i;

#if USE_DMA
	ulong			dmaID;				// dma identifier

	/* Copy source to end of destination buffer */
	dmaID = DMA_BitsBuffer(dest_pointer,
		src_pointer, src_buf->externalBufferIndex);

    // no processing done in the background, make sure DMA is completed now.
	dma_done(dmaID);

	dest_buf->externalBufferIndex += src_buf->externalBufferIndex;
#else
	/* Copy source to end of destination buffer */
	for(i=0; i<src_buf->externalBufferIndex; i++)
	{
		dest_pointer[i] = src_pointer[i];
		dest_buf->externalBufferIndex++;
	}
#endif // USE_DMA
}


 tBitsBuffer *JPEG_TempBuffer_NEW(void)
{
    return (tBitsBuffer *)JPEG_BitsBuffer_NEW();
}

 int JPEG_TempBuffer_CONFIG(tBitsBuffer *handle, eBitsBuf_config item, int value)
{
    return JPEG_BitsBuffer_CONFIG((tBitsBuffer *)handle, item, value);
}

 int JPEG_TempBuffer_INIT(tBitsBuffer *handle)
{
    return JPEG_BitsBuffer_INIT((tBitsBuffer *)handle);
}

 void JPEG_TempBuffer_DELETE(tBitsBuffer *handle)
{
    JPEG_BitsBuffer_DELETE((tBitsBuffer *)handle);
}

 int JPEG_TempBuffer_RESET(tBitsBuffer *handle)
{
    return JPEG_BitsBuffer_RESET((tBitsBuffer *)handle);
}

 unsigned char *JPEG_TempBuffer_REQUEST(tBitsBuffer *handle)
{
    return JPEG_BitsBuffer_REQUEST((tBitsBuffer *)handle);
}

 int JPEG_TempBuffer_WRITE(tBitsBuffer *handle, int numBytes)
{
    return JPEG_BitsBuffer_WRITE((tBitsBuffer *)handle, numBytes);
}

 int JPEG_TempBuffer_FLUSH(tBitsBuffer *handle)
{
    return JPEG_BitsBuffer_FLUSH((tBitsBuffer *)handle);
}

