/*
********************************************************************************
** 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; 
	uint8						marker_hi = 0;
	uint8						marker_lo = 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;

		marker_hi = *((uint8 *)(bitsbuf->ptrFile->Pointer + bitsbuf->ptrFile->Length - 2));
		marker_lo = *((uint8 *)(bitsbuf->ptrFile->Pointer + bitsbuf->ptrFile->Length - 1));

		// if last two bytes are not EOI
		if((marker_hi != 0xff) || (marker_lo != 0xd9))  
		{
			*((uint8 *)(bitsbuf->ptrFile->Pointer + bitsbuf->ptrFile->Length - 2)) = 0xff;
			*((uint8 *)(bitsbuf->ptrFile->Pointer + bitsbuf->ptrFile->Length - 1)) = 0xd9;
			printf("Last two bytes in buffer = %x %x\n", marker_hi, marker_lo);
			printf("Warning:  No End_of_Image marker 0xFFD9 found\n");
			printf("Replacing last two bytes with EOI [0xffd9]\n");
		}

        error_code=1;
    }
    
	return error_code;
}

/*
********************************************************************************
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;
    }
    
    
    /* 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
	
	lBuffWord = (unsigned int *)pbuffer;
    
	/* check if "end of file" has been reached*/
	/* if so we fill the next bitsbuffer array to 4 dummy bytes which are EOI markers */
	if(bitsbuf->InputFilePosition >= bitsbuf->BitStreamFileSize)
	{
    	lBuffWord[0] = 0xffd9ffd9;
    	*pBytesRead = 4;
	}
    else
    {
    	/* 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 */

    	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
}

