mirror of
				https://git.ffmpeg.org/ffmpeg.git
				synced 2025-10-31 07:40:55 +00:00 
			
		
		
		
	
		
			
	
	
		
			94 lines
		
	
	
	
		
			2.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			94 lines
		
	
	
	
		
			2.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|   | /*
 | ||
|  |  * MQ-coder decoder | ||
|  |  * Copyright (c) 2007 Kamil Nowosad | ||
|  |  * | ||
|  |  * This file is part of FFmpeg. | ||
|  |  * | ||
|  |  * FFmpeg is free software; you can redistribute it and/or | ||
|  |  * modify it under the terms of the GNU Lesser General Public | ||
|  |  * License as published by the Free Software Foundation; either | ||
|  |  * version 2.1 of the License, or (at your option) any later version. | ||
|  |  * | ||
|  |  * FFmpeg is distributed in the hope that it will be useful, | ||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | ||
|  |  * Lesser General Public License for more details. | ||
|  |  * | ||
|  |  * You should have received a copy of the GNU Lesser General Public | ||
|  |  * License along with FFmpeg; if not, write to the Free Software | ||
|  |  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
|  |  */ | ||
|  | 
 | ||
|  | /**
 | ||
|  |  * MQ-coder decoder | ||
|  |  * @file | ||
|  |  * @author Kamil Nowosad | ||
|  |  */ | ||
|  | 
 | ||
|  | #include "mqc.h"
 | ||
|  | 
 | ||
|  | static void bytein(MqcState *mqc) | ||
|  | { | ||
|  |     if (*mqc->bp == 0xff){ | ||
|  |         if (*(mqc->bp+1) > 0x8f) | ||
|  |             mqc->c++; | ||
|  |         else{ | ||
|  |             mqc->bp++; | ||
|  |             mqc->c += 2 + 0xfe00 - (*mqc->bp << 9); | ||
|  |         } | ||
|  |     } else{ | ||
|  |         mqc->bp++; | ||
|  |         mqc->c += 1 + 0xff00 - (*mqc->bp << 8); | ||
|  |     } | ||
|  | } | ||
|  | 
 | ||
|  | static int exchange(MqcState *mqc, uint8_t *cxstate, int lps) | ||
|  | { | ||
|  |     int d; | ||
|  |     if ((mqc->a < ff_mqc_qe[*cxstate]) ^ (!lps)){ | ||
|  |         if (lps) | ||
|  |             mqc->a = ff_mqc_qe[*cxstate]; | ||
|  |         d = *cxstate & 1; | ||
|  |         *cxstate = ff_mqc_nmps[*cxstate]; | ||
|  |     } else{ | ||
|  |         if (lps) | ||
|  |             mqc->a = ff_mqc_qe[*cxstate]; | ||
|  |         d = 1 - (*cxstate & 1); | ||
|  |         *cxstate = ff_mqc_nlps[*cxstate]; | ||
|  |     } | ||
|  |     // renormd:
 | ||
|  |     do{ | ||
|  |         if (!(mqc->c & 0xff)){ | ||
|  |             mqc->c -= 0x100; | ||
|  |             bytein(mqc); | ||
|  |         } | ||
|  |         mqc->a += mqc->a; | ||
|  |         mqc->c += mqc->c; | ||
|  |     } while (!(mqc->a & 0x8000)); | ||
|  |     return d; | ||
|  | } | ||
|  | 
 | ||
|  | void ff_mqc_initdec(MqcState *mqc, uint8_t *bp) | ||
|  | { | ||
|  |     ff_mqc_init_contexts(mqc); | ||
|  |     mqc->bp = bp; | ||
|  |     mqc->c = (*mqc->bp ^ 0xff) << 16; | ||
|  |     bytein(mqc); | ||
|  |     mqc->c = mqc->c << 7; | ||
|  |     mqc->a = 0x8000; | ||
|  | } | ||
|  | 
 | ||
|  | int ff_mqc_decode(MqcState *mqc, uint8_t *cxstate) | ||
|  | { | ||
|  |     mqc->a -= ff_mqc_qe[*cxstate]; | ||
|  |     if ((mqc->c >> 16) < mqc->a){ | ||
|  |         if (mqc->a & 0x8000) | ||
|  |             return *cxstate & 1; | ||
|  |         else | ||
|  |             return exchange(mqc, cxstate, 0); | ||
|  |     } else { | ||
|  |         mqc->c -= mqc->a << 16; | ||
|  |         return exchange(mqc, cxstate, 1); | ||
|  |     } | ||
|  | } |