int read_jpeg_data(int fd,jpeg_data_t  *jpeg_data,int op_max,jpegdec_config_t *config,int thumbprefor,int fd_jpegdec)
{
    struct am_io_param vb_info;
	int  read_num;
	unsigned int decState;
	int fd_amport=jpeg_data->fd_amport;
	
	lseek(fd ,0, SEEK_SET);  //seek device head .
	if(jpeg_data->buffer==NULL||fd_amport<0) return 0;
  	
	int  op_step=DEC_STAT_INFOCONFIG ;
	int  result=0;;
	int  read_unit=HEADER_SIZE;
	int total_size =0 ;
	int file_read_end = 0;
//	QDateTime time1;
//	QDateTime time2;			
	int wait_info_count  =0 ;
	int wait_timeout = 0 ;
//    time1= QDateTime::currentDateTime();  
    int time_start = time((time_t*)NULL) ;
    int time_cur;
    int time_poll;
    
	ALOGD("decoder start\n");
	while(op_step < op_max)
	{
		decState=get_decoder_state( fd_jpegdec);
		result = decState;
		if (decState & JPEGDEC_STAT_ERROR) {	    
			ALOGD("jpegdec error\n");
			break;
		}

		if (decState & JPEGDEC_STAT_UNSUPPORT) {	    
			ALOGD("jpegdec unsupported format\n");	
			break;
		}

		if (decState & JPEGDEC_STAT_DONE) {	    
			ALOGD("jpegdec done\n");	
			break;
		}
		ioctl(fd_amport, AMSTREAM_IOC_VB_STATUS,&vb_info);		
		if((!file_read_end)&&(vb_info.status.data_len < ((4*vb_info.status.size)/5))&&(decState & JPEGDEC_STAT_WAIT_DATA)){
			if(total_size == 0 ){
				memset(jpeg_data->buffer,0,HEADER_SIZE);
				 write( fd_amport, jpeg_data->buffer, HEADER_SIZE); 				
			}			
			read_num=read(fd,jpeg_data->buffer,read_unit );
			total_size += read_num;
			if(read_num<0)
			{		    
				ALOGD("can't read data from jpeg device");  	
				result= 0;
				break;
			}
			read_unit=MAX_BUFFER_SIZE;//expand buffer size to read real data.
			if(read_num==0) //file end then fill padding data into buffer.
			{
			    file_read_end = 1;
				read_num=read_unit=HEADER_SIZE;
				memset(jpeg_data->buffer,0,read_unit);
			}
			int ret = write( fd_amport, jpeg_data->buffer, read_num); 
			
		}	
		switch(op_step)
		{
			case DEC_STAT_INFOCONFIG:
			ioctl( fd_jpegdec, JPEGDEC_IOC_INFOCONFIG, decoder_opt);
			op_step=DEC_STAT_INFO;
			break;
			case DEC_STAT_INFO:
			if (decState & JPEGDEC_STAT_INFO_READY) {
				ioctl( fd_jpegdec, JPEGDEC_IOC_INFO, &jpeg_data->info);			
				ALOGD("++jpeg informations:w:%d,h:%d\r\n",jpeg_data->info.width,jpeg_data->info.height);			
				op_step=DEC_STAT_DECCONFIG;
				
			}else{
			    wait_info_count++;
			    if(wait_info_count > 100){
			        wait_info_count = 0 ;		        	
                    time_cur = time((time_t*)NULL) ;
                    wait_timeout = time_cur - time_start;			        	        	
			        ALOGD("current timeout is %d!!!\n",wait_timeout);	        		        		        	        		        
			    }
			    if(wait_timeout > 1){
			        op_step = op_max;  			        
			        ALOGD("timeout for get jpeg info!!!\n");		        
			        result =0;
			        break;  			        
			    }		    
				ALOGD("in jpeg decoding process\n");			
				result =0;
			}
			break;
			case DEC_STAT_DECCONFIG:
			if(config)
			{
				if (rebuild_jpg_config_para(jpeg_data,config)<0) {
					ALOGD("get mem info failed\n");
					op_step = op_max;
					result =0;
					continue;
				}
				jpeg_dec_mem.angle=config->angle;
				jpeg_dec_mem.dec_w=config->dec_w;
				jpeg_dec_mem.dec_h=config->dec_h;
				if(ioctl(fd_jpegdec, JPEGDEC_G_MEM_INFO, &jpeg_dec_mem)<0) {
					ALOGD("get mem info failed\n");
					op_step = op_max;
					result =0;
					continue;
				}
				if (set_jpeg_dec_mem(jpeg_data,config)<0||ioctl(fd_jpegdec, JPEGDEC_IOC_DECCONFIG, config)<0) {			    
					ALOGD("decoder config failed\n");			
					op_step = op_max;
					result =0;
					continue;
				}
				
			}
			op_step =DEC_STAT_RUN;
			break;
			default:
			break;	
		}
		time_poll = time((time_t*)NULL) ;
		if((time_poll - time_start) > 8){
			op_step = op_max;  			        
			ALOGD("it's a corrupted jpeg\n");		        
			result =0;  			
		}
	}
	ALOGD("decoder exit\n");
	ALOGD("total read bytes is %d",total_size);
	
	return result;
		
}
int read_jpeg_data(int fd,jpeg_data_t  *jpeg_data,int op_max,jpegdec_config_t *config)
{
    struct am_io_param vb_info;
	int  read_num;
	unsigned int decState;
	int fd_jpegdec;
	int fd_amport=jpeg_data->fd_amport;
	
	lseek(fd ,0, SEEK_SET);  //seek device head .
	if(jpeg_data->buffer==NULL||fd_amport<0) return 0;
   
    fd_jpegdec= open(FILE_NAME_JPEGDEC, O_RDWR);
#ifdef JPEG_DBG     
    printf("fd_jpegdec= open(%s, O_RDWR)\n",FILE_NAME_JPEGDEC); 
#endif
    if(fd_jpegdec <0 ){
        perror("open amjpec device error\r\n")	;
        // 	  	printf("can't open jpeg relative device %s",qPrintable(dev));  	
        return 0;
    }	
	int  op_step=DEC_STAT_INFOCONFIG ;
	int  result=0;;
	int  read_unit=HEADER_SIZE;
	int total_size =0 ;
	int file_read_end = 0;
//	QDateTime time1;
//	QDateTime time2;			
	int wait_info_count  =0 ;
	int wait_timeout = 0 ;
//    time1= QDateTime::currentDateTime();
#ifdef JPEG_DBG     
	printf("decoder start\n");
#endif
	while(op_step < op_max)
	{
		decState=get_decoder_state( fd_jpegdec);
		result = decState;
		if (decState & JPEGDEC_STAT_ERROR) {
#ifdef JPEG_DBG 		    
			printf("jpegdec error\n");
#endif
			break;
		}

		if (decState & JPEGDEC_STAT_UNSUPPORT) {
#ifdef JPEG_DBG 		    
			printf("jpegdec unsupported format\n");
#endif			
			break;
		}

		if (decState & JPEGDEC_STAT_DONE) {
#ifdef JPEG_DBG 		    
			printf("jpegdec done\n");
#endif			
			break;
		}
		ioctl(fd_amport, AMSTREAM_IOC_VB_STATUS,&vb_info);		
		if((!file_read_end)&&(vb_info.status.data_len < ((4*vb_info.status.size)/5))&&(decState & JPEGDEC_STAT_WAIT_DATA)){
			read_num=read(fd,jpeg_data->buffer,read_unit );
			total_size += read_num;
			if(read_num<0)
			{
#ifdef JPEG_DBG 			    
				printf("can't read data from jpeg device");  
#endif				
				result= 0;
				break;
			}
			read_unit=MAX_BUFFER_SIZE;//expand buffer size to read real data.
			if(read_num==0) //file end then fill padding data into buffer.
			{
			    file_read_end = 1;
				read_num=read_unit=HEADER_SIZE;
				memset(jpeg_data->buffer,0,read_unit);
			}
			int ret = write( fd_amport, jpeg_data->buffer, read_num); 
			
		}	
		switch(op_step)
		{
			case DEC_STAT_INFOCONFIG:
			ioctl( fd_jpegdec, JPEGDEC_IOC_INFOCONFIG, decoder_opt);
			op_step=DEC_STAT_INFO;
			break;
			case DEC_STAT_INFO:
			if (decState & JPEGDEC_STAT_INFO_READY) {
				ioctl( fd_jpegdec, JPEGDEC_IOC_INFO, &jpeg_data->info);
#ifdef JPEG_DBG 				
				printf("++jpeg informations:w:%d,h:%d\r\n",jpeg_data->info.width,jpeg_data->info.height);
#endif				
				op_step=DEC_STAT_DECCONFIG;
				
			}else{
			    wait_info_count++;
			    if(wait_info_count > 5){
			        wait_info_count = 0 ;
//			        time2= QDateTime::currentDateTime(); 
//			        wait_timeout = abs(time2.secsTo(time1));		
#ifdef JPEG_DBG 			        	
			        printf("current timeout is %d!!!\n",wait_timeout);	        		        
#endif			        	        		        
			    }
			    if(wait_timeout > 3){
			        op_step = op_max;  
#ifdef JPEG_DBG 			        
			        printf("timeout for get jpeg info!!!\n");
#endif			        
			        break;  			        
			    }
#ifdef JPEG_DBG 			    
				printf("in jpeg decoding process\n");
#endif				
				result =0;
			}
			break;
			case DEC_STAT_DECCONFIG:
			if(config)
			{
				// first request mem from cmem.
				if(rebuild_jpg_config_para(jpeg_data,config)<0)
				{
#ifdef JPEG_DBG 				    
					printf("rebuild_cmem_config_para error");
#endif					
					op_step = op_max;
					result=0;
					continue;
				}
//#ifdef JPEG_DBG 				
//				printf("sending jpeg decoding config (%d-%d-%d-%d), planes(0x%x, 0x%x, 0x%x).\n",
//					config->dec_x, config->dec_y, config->dec_w, config->dec_h,
//					config->addr_y, config->addr_u, config->addr_v);
//#endif	
				if (ioctl(fd_jpegdec, JPEGDEC_IOC_DECCONFIG, config)<0) {
#ifdef JPEG_DBG 				    
					printf("decoder config failed\n");
#endif					
					op_step = op_max;
					result =0;
					continue;
				}	
				
			}
			op_step =DEC_STAT_RUN;
			break;
			default:
			break;	
		}
	}
#ifdef JPEG_DBG 	
	printf("decoder exit\n");
	printf("total read bytes is %d",total_size);  
#endif
	if( fd_jpegdec >0)
	{
		close(  fd_jpegdec);
		fd_jpegdec=-1;
	}
	
	return result;
		
}