annotate idcinvideo.c @ 7352:c2318e551ff5 libavcodec

When picking a "high utility centroid" do not pick one that has no corresponding points. Not only it is the worst possible pick, but also the code was written without this case in mind.
author vitor
date Wed, 23 Jul 2008 03:55:37 +0000
parents e943e1409077
children bc36a075bf35
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1498
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
1 /*
6812
0d01bae8d207 cosmetics: s/Id/id/ in libavcodec where Id refers to id Software.
diego
parents: 6712
diff changeset
2 * id Quake II CIN Video Decoder
1498
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
3 * Copyright (C) 2003 the ffmpeg project
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
4 *
3947
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3036
diff changeset
5 * This file is part of FFmpeg.
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3036
diff changeset
6 *
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3036
diff changeset
7 * FFmpeg is free software; you can redistribute it and/or
1498
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
9 * License as published by the Free Software Foundation; either
3947
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3036
diff changeset
10 * version 2.1 of the License, or (at your option) any later version.
1498
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
11 *
3947
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3036
diff changeset
12 * FFmpeg is distributed in the hope that it will be useful,
1498
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
15 * Lesser General Public License for more details.
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
16 *
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
17 * You should have received a copy of the GNU Lesser General Public
3947
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3036
diff changeset
18 * License along with FFmpeg; if not, write to the Free Software
3036
0b546eab515d Update licensing information: The FSF changed postal address.
diego
parents: 2508
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1498
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
20 */
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
21
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
22 /**
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
23 * @file idcinvideo.c
6812
0d01bae8d207 cosmetics: s/Id/id/ in libavcodec where Id refers to id Software.
diego
parents: 6712
diff changeset
24 * id Quake II Cin Video Decoder by Dr. Tim Ferguson
0d01bae8d207 cosmetics: s/Id/id/ in libavcodec where Id refers to id Software.
diego
parents: 6712
diff changeset
25 * For more information about the id CIN format, visit:
1498
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
26 * http://www.csse.monash.edu.au/~timf/
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
27 *
1499
446ff1d593b0 instructions for using the decoder
tmmm
parents: 1498
diff changeset
28 * This video decoder outputs PAL8 colorspace data. Interacting with this
446ff1d593b0 instructions for using the decoder
tmmm
parents: 1498
diff changeset
29 * decoder is a little involved. During initialization, the demuxer must
446ff1d593b0 instructions for using the decoder
tmmm
parents: 1498
diff changeset
30 * transmit the 65536-byte Huffman table(s) to the decoder via extradata.
446ff1d593b0 instructions for using the decoder
tmmm
parents: 1498
diff changeset
31 * Then, whenever a palette change is encountered while demuxing the file,
446ff1d593b0 instructions for using the decoder
tmmm
parents: 1498
diff changeset
32 * the demuxer must use the same extradata space to transmit an
446ff1d593b0 instructions for using the decoder
tmmm
parents: 1498
diff changeset
33 * AVPaletteControl structure.
1498
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
34 *
6812
0d01bae8d207 cosmetics: s/Id/id/ in libavcodec where Id refers to id Software.
diego
parents: 6712
diff changeset
35 * id CIN video is purely Huffman-coded, intraframe-only codec. It achieves
1498
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
36 * a little more compression by exploiting the fact that adjacent pixels
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
37 * tend to be similar.
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
38 *
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
39 * Note that this decoder could use ffmpeg's optimized VLC facilities
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
40 * rather than naive, tree-based Huffman decoding. However, there are 256
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
41 * Huffman tables. Plus, the VLC bit coding order is right -> left instead
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
42 * or left -> right, so all of the bits would have to be reversed. Further,
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
43 * the original Quake II implementation likely used a similar naive
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
44 * decoding algorithm and it worked fine on much lower spec machines.
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
45 */
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
46
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
47 #include <stdio.h>
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
48 #include <stdlib.h>
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
49 #include <string.h>
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
50 #include <unistd.h>
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
51
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
52 #include "avcodec.h"
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
53
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
54 #define HUFFMAN_TABLE_SIZE 64 * 1024
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
55 #define HUF_TOKENS 256
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
56 #define PALETTE_COUNT 256
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
57
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
58 typedef struct
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
59 {
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
60 int count;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
61 unsigned char used;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
62 int children[2];
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
63 } hnode_t;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
64
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
65 typedef struct IdcinContext {
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
66
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
67 AVCodecContext *avctx;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
68 AVFrame frame;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
69
6218
michael
parents: 5215
diff changeset
70 const unsigned char *buf;
1498
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
71 int size;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
72
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
73 hnode_t huff_nodes[256][HUF_TOKENS*2];
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
74 int num_huff_nodes[256];
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
75
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
76 } IdcinContext;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
77
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
78 /*
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
79 * Find the lowest probability node in a Huffman table, and mark it as
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
80 * being assigned to a higher probability.
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
81 * Returns the node index of the lowest unused node, or -1 if all nodes
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
82 * are used.
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
83 */
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
84 static int huff_smallest_node(hnode_t *hnodes, int num_hnodes) {
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
85 int i;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
86 int best, best_node;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
87
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
88 best = 99999999;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
89 best_node = -1;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
90 for(i = 0; i < num_hnodes; i++) {
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
91 if(hnodes[i].used)
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
92 continue;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
93 if(!hnodes[i].count)
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
94 continue;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
95 if(hnodes[i].count < best) {
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
96 best = hnodes[i].count;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
97 best_node = i;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
98 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
99 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
100
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
101 if(best_node == -1)
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
102 return -1;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
103 hnodes[best_node].used = 1;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
104 return best_node;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
105 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
106
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
107 /*
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
108 * Build the Huffman tree using the generated/loaded probabilities histogram.
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
109 *
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
110 * On completion:
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
111 * huff_nodes[prev][i < HUF_TOKENS] - are the nodes at the base of the tree.
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
112 * huff_nodes[prev][i >= HUF_TOKENS] - are used to construct the tree.
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
113 * num_huff_nodes[prev] - contains the index to the root node of the tree.
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
114 * That is: huff_nodes[prev][num_huff_nodes[prev]] is the root node.
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
115 */
6517
48759bfbd073 Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents: 6484
diff changeset
116 static av_cold void huff_build_tree(IdcinContext *s, int prev) {
1498
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
117 hnode_t *node, *hnodes;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
118 int num_hnodes, i;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
119
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
120 num_hnodes = HUF_TOKENS;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
121 hnodes = s->huff_nodes[prev];
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
122 for(i = 0; i < HUF_TOKENS * 2; i++)
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
123 hnodes[i].used = 0;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
124
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
125 while (1) {
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
126 node = &hnodes[num_hnodes]; /* next free node */
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
127
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
128 /* pick two lowest counts */
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
129 node->children[0] = huff_smallest_node(hnodes, num_hnodes);
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
130 if(node->children[0] == -1)
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
131 break; /* reached the root node */
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
132
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
133 node->children[1] = huff_smallest_node(hnodes, num_hnodes);
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
134 if(node->children[1] == -1)
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
135 break; /* reached the root node */
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
136
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
137 /* combine nodes probability for new node */
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
138 node->count = hnodes[node->children[0]].count +
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
139 hnodes[node->children[1]].count;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
140 num_hnodes++;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
141 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
142
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
143 s->num_huff_nodes[prev] = num_hnodes - 1;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
144 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
145
6517
48759bfbd073 Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents: 6484
diff changeset
146 static av_cold int idcin_decode_init(AVCodecContext *avctx)
1498
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
147 {
4827
b3ee9a1526b0 Get rid of unnecessary pointer casts.
diego
parents: 4801
diff changeset
148 IdcinContext *s = avctx->priv_data;
1498
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
149 int i, j, histogram_index = 0;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
150 unsigned char *histograms;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
151
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
152 s->avctx = avctx;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
153 avctx->pix_fmt = PIX_FMT_PAL8;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
154
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
155 /* make sure the Huffman tables make it */
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
156 if (s->avctx->extradata_size != HUFFMAN_TABLE_SIZE) {
6812
0d01bae8d207 cosmetics: s/Id/id/ in libavcodec where Id refers to id Software.
diego
parents: 6712
diff changeset
157 av_log(s->avctx, AV_LOG_ERROR, " id CIN video: expected extradata size of %d\n", HUFFMAN_TABLE_SIZE);
1498
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
158 return -1;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
159 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
160
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
161 /* build the 256 Huffman decode trees */
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
162 histograms = (unsigned char *)s->avctx->extradata;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
163 for (i = 0; i < 256; i++) {
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
164 for(j = 0; j < HUF_TOKENS; j++)
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
165 s->huff_nodes[i][j].count = histograms[histogram_index++];
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
166 huff_build_tree(s, i);
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
167 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
168
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
169 s->frame.data[0] = NULL;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
170
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
171 return 0;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
172 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
173
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
174 static void idcin_decode_vlcs(IdcinContext *s)
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
175 {
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
176 hnode_t *hnodes;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
177 long x, y;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
178 int prev;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
179 unsigned char v = 0;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
180 int bit_pos, node_num, dat_pos;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
181
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
182 prev = bit_pos = dat_pos = 0;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
183 for (y = 0; y < (s->frame.linesize[0] * s->avctx->height);
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
184 y += s->frame.linesize[0]) {
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
185 for (x = y; x < y + s->avctx->width; x++) {
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
186 node_num = s->num_huff_nodes[prev];
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
187 hnodes = s->huff_nodes[prev];
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
188
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
189 while(node_num >= HUF_TOKENS) {
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
190 if(!bit_pos) {
2508
b0ec6f51b5bd Off-by-one bug in libavcodec/idcinvideo.c, caused
michael
parents: 1598
diff changeset
191 if(dat_pos >= s->size) {
1598
932d306bf1dc av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents: 1585
diff changeset
192 av_log(s->avctx, AV_LOG_ERROR, "Huffman decode error.\n");
1498
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
193 return;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
194 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
195 bit_pos = 8;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
196 v = s->buf[dat_pos++];
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
197 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
198
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
199 node_num = hnodes[node_num].children[v & 0x01];
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
200 v = v >> 1;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
201 bit_pos--;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
202 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
203
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
204 s->frame.data[0][x] = node_num;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
205 prev = node_num;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
206 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
207 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
208 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
209
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
210 static int idcin_decode_frame(AVCodecContext *avctx,
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
211 void *data, int *data_size,
6218
michael
parents: 5215
diff changeset
212 const uint8_t *buf, int buf_size)
1498
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
213 {
4827
b3ee9a1526b0 Get rid of unnecessary pointer casts.
diego
parents: 4801
diff changeset
214 IdcinContext *s = avctx->priv_data;
1585
6b224ca24033 revised palette API, courtesy of Roberto Togni (rtogni at freemail.it)
melanson
parents: 1499
diff changeset
215 AVPaletteControl *palette_control = avctx->palctrl;
1498
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
216
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
217 s->buf = buf;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
218 s->size = buf_size;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
219
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
220 if (s->frame.data[0])
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
221 avctx->release_buffer(avctx, &s->frame);
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
222
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
223 if (avctx->get_buffer(avctx, &s->frame)) {
6812
0d01bae8d207 cosmetics: s/Id/id/ in libavcodec where Id refers to id Software.
diego
parents: 6712
diff changeset
224 av_log(avctx, AV_LOG_ERROR, " id CIN Video: get_buffer() failed\n");
1498
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
225 return -1;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
226 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
227
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
228 idcin_decode_vlcs(s);
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
229
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
230 /* make the palette available on the way out */
1585
6b224ca24033 revised palette API, courtesy of Roberto Togni (rtogni at freemail.it)
melanson
parents: 1499
diff changeset
231 memcpy(s->frame.data[1], palette_control->palette, PALETTE_COUNT * 4);
6b224ca24033 revised palette API, courtesy of Roberto Togni (rtogni at freemail.it)
melanson
parents: 1499
diff changeset
232 /* If palette changed inform application*/
6b224ca24033 revised palette API, courtesy of Roberto Togni (rtogni at freemail.it)
melanson
parents: 1499
diff changeset
233 if (palette_control->palette_changed) {
6b224ca24033 revised palette API, courtesy of Roberto Togni (rtogni at freemail.it)
melanson
parents: 1499
diff changeset
234 palette_control->palette_changed = 0;
6b224ca24033 revised palette API, courtesy of Roberto Togni (rtogni at freemail.it)
melanson
parents: 1499
diff changeset
235 s->frame.palette_has_changed = 1;
6b224ca24033 revised palette API, courtesy of Roberto Togni (rtogni at freemail.it)
melanson
parents: 1499
diff changeset
236 }
1498
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
237
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
238 *data_size = sizeof(AVFrame);
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
239 *(AVFrame*)data = s->frame;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
240
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
241 /* report that the buffer was completely consumed */
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
242 return buf_size;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
243 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
244
6517
48759bfbd073 Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents: 6484
diff changeset
245 static av_cold int idcin_decode_end(AVCodecContext *avctx)
1498
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
246 {
4827
b3ee9a1526b0 Get rid of unnecessary pointer casts.
diego
parents: 4801
diff changeset
247 IdcinContext *s = avctx->priv_data;
1498
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
248
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
249 if (s->frame.data[0])
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
250 avctx->release_buffer(avctx, &s->frame);
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
251
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
252 return 0;
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
253 }
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
254
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
255 AVCodec idcin_decoder = {
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
256 "idcinvideo",
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
257 CODEC_TYPE_VIDEO,
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
258 CODEC_ID_IDCIN,
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
259 sizeof(IdcinContext),
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
260 idcin_decode_init,
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
261 NULL,
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
262 idcin_decode_end,
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
263 idcin_decode_frame,
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
264 CODEC_CAP_DR1,
7040
e943e1409077 Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents: 6812
diff changeset
265 .long_name = NULL_IF_CONFIG_SMALL("id Quake II CIN video"),
1498
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
266 };
9eb9b77cf418 implemented Id Quake II CIN support
tmmm
parents:
diff changeset
267