]> git.sesse.net Git - ffmpeg/blob - libavcodec/mqcenc.c
Merge remote-tracking branch 'hexene/scratchpad'
[ffmpeg] / libavcodec / mqcenc.c
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
30 static void byteout(MqcState *mqc)
31 {
32 retry:
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
50 static 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
60 static 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
68 void 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
78 void 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
104 int ff_mqc_length(MqcState *mqc)
105 {
106     return mqc->bp - mqc->bpstart;
107 }
108
109 int 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 }