1/* 2 * MQ-coder encoder 3 * Copyright (c) 2007 Kamil Nowosad 4 * 5 * This file is part of FFmpeg. 6 * 7 * FFmpeg is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * FFmpeg is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with FFmpeg; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21 22/** 23 * MQ-coder encoder 24 * @file 25 * @author Kamil Nowosad 26 */ 27 28#include "mqc.h" 29 30static void byteout(MqcState *mqc) 31{ 32retry: 33 if (*mqc->bp == 0xff){ 34 mqc->bp++; 35 *mqc->bp = mqc->c >> 20; 36 mqc->c &= 0xfffff; 37 mqc->ct = 7; 38 } else if ((mqc->c & 0x8000000)){ 39 (*mqc->bp)++; 40 mqc->c &= 0x7ffffff; 41 goto retry; 42 } else{ 43 mqc->bp++; 44 *mqc->bp = mqc->c >> 19; 45 mqc->c &= 0x7ffff; 46 mqc->ct = 8; 47 } 48} 49 50static void renorme(MqcState *mqc) 51{ 52 do{ 53 mqc->a += mqc->a; 54 mqc->c += mqc->c; 55 if (!--mqc->ct) 56 byteout(mqc); 57 } while (!(mqc->a & 0x8000)); 58} 59 60static void setbits(MqcState *mqc) 61{ 62 int tmp = mqc->c + mqc->a; 63 mqc->c |= 0xffff; 64 if (mqc->c >= tmp) 65 mqc->c -= 0x8000; 66} 67 68void ff_mqc_initenc(MqcState *mqc, uint8_t *bp) 69{ 70 ff_mqc_init_contexts(mqc); 71 mqc->a = 0x8000; 72 mqc->c = 0; 73 mqc->bp = bp-1; 74 mqc->bpstart = bp; 75 mqc->ct = 12 + (*mqc->bp == 0xff); 76} 77 78void ff_mqc_encode(MqcState *mqc, uint8_t *cxstate, int d) 79{ 80 int qe; 81 82 qe = ff_mqc_qe[*cxstate]; 83 mqc->a -= qe; 84 if ((*cxstate & 1) == d){ 85 if (!(mqc->a & 0x8000)){ 86 if (mqc->a < qe) 87 mqc->a = qe; 88 else 89 mqc->c += qe; 90 *cxstate = ff_mqc_nmps[*cxstate]; 91 renorme(mqc); 92 } else 93 mqc->c += qe; 94 } else{ 95 if (mqc->a < qe) 96 mqc->c += qe; 97 else 98 mqc->a = qe; 99 *cxstate = ff_mqc_nlps[*cxstate]; 100 renorme(mqc); 101 } 102} 103 104int ff_mqc_length(MqcState *mqc) 105{ 106 return mqc->bp - mqc->bpstart; 107} 108 109int ff_mqc_flush(MqcState *mqc) 110{ 111 setbits(mqc); 112 mqc->c = mqc->c << mqc->ct; 113 byteout(mqc); 114 mqc->c = mqc->c << mqc->ct; 115 byteout(mqc); 116 if (*mqc->bp != 0xff) 117 mqc->bp++; 118 return mqc->bp - mqc->bpstart; 119} 120