../../../ffmpeg/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
114 / 136
83.8%
Branches:
57 / 83
68.7%
Functions:
8 / 8
100.0%

libavcodec/tiertexseqv.c
Line Branch Exec Source
1 /*
2 * Tiertex Limited SEQ Video Decoder
3 * Copyright (c) 2006 Gregory Montoir (cyx@users.sourceforge.net)
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 * @file
24 * Tiertex Limited SEQ video decoder
25 */
26
27 #define BITSTREAM_READER_LE
28 #include "avcodec.h"
29 #include "codec_internal.h"
30 #include "decode.h"
31 #include "get_bits.h"
32
33
34 typedef struct SeqVideoContext {
35 AVCodecContext *avctx;
36 AVFrame *frame;
37 } SeqVideoContext;
38
39
40 2508 static const unsigned char *seq_unpack_rle_block(const unsigned char *src,
41 const unsigned char *src_end,
42 unsigned char *dst, int dst_size)
43 {
44 int i, len, sz;
45 GetBitContext gb;
46 int code_table[64];
47
48 /* get the rle codes */
49 2508 init_get_bits(&gb, src, (src_end - src) * 8);
50
3/4
✓ Branch 9 → 10 taken 53386 times.
✗ Branch 9 → 11 not taken.
✓ Branch 10 → 4 taken 50878 times.
✓ Branch 10 → 11 taken 2508 times.
53386 for (i = 0, sz = 0; i < 64 && sz < dst_size; i++) {
51
1/2
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 50878 times.
50878 if (get_bits_left(&gb) < 4)
52 ✗ return NULL;
53 50878 code_table[i] = get_sbits(&gb, 4);
54 50878 sz += FFABS(code_table[i]);
55 }
56 2508 src += (get_bits_count(&gb) + 7) / 8;
57
58 /* do the rle unpacking */
59
3/4
✓ Branch 21 → 22 taken 53386 times.
✗ Branch 21 → 23 not taken.
✓ Branch 22 → 13 taken 50878 times.
✓ Branch 22 → 23 taken 2508 times.
53386 for (i = 0; i < 64 && dst_size > 0; i++) {
60 50878 len = code_table[i];
61
1/2
✓ Branch 13 → 14 taken 50878 times.
✗ Branch 13 → 17 not taken.
50878 if (len < 0) {
62 50878 len = -len;
63
1/2
✗ Branch 14 → 15 not taken.
✓ Branch 14 → 16 taken 50878 times.
50878 if (src_end - src < 1)
64 ✗ return NULL;
65 50878 memset(dst, *src++, FFMIN(len, dst_size));
66 } else {
67
0/2
✗ Branch 17 → 18 not taken.
✗ Branch 17 → 19 not taken.
✗ if (src_end - src < len)
68 ✗ return NULL;
69 ✗ memcpy(dst, src, FFMIN(len, dst_size));
70 ✗ src += len;
71 }
72 50878 len = FFMIN(len, dst_size);
73 50878 dst += len;
74 50878 dst_size -= len;
75 }
76
1/2
✗ Branch 23 → 24 not taken.
✓ Branch 23 → 25 taken 2508 times.
2508 if (dst_size > 0)
77 ✗ return NULL;
78 2508 return src;
79 }
80
81 6758 static const unsigned char *seq_decode_op1(SeqVideoContext *seq,
82 const unsigned char *src,
83 const unsigned char *src_end,
84 unsigned char *dst)
85 {
86 const unsigned char *color_table;
87 int b, i, len, bits;
88 GetBitContext gb;
89 unsigned char block[8 * 8];
90
91
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 6758 times.
6758 if (src_end - src < 1)
92 ✗ return NULL;
93 6758 len = *src++;
94
2/2
✓ Branch 4 → 5 taken 2508 times.
✓ Branch 4 → 24 taken 4250 times.
6758 if (len & 0x80) {
95
2/3
✓ Branch 5 → 6 taken 1099 times.
✓ Branch 5 → 13 taken 1409 times.
✗ Branch 5 → 23 not taken.
2508 switch (len & 3) {
96 1099 case 1:
97 1099 src = seq_unpack_rle_block(src, src_end, block, sizeof(block));
98
1/2
✗ Branch 7 → 8 not taken.
✓ Branch 7 → 9 taken 1099 times.
1099 if (!src)
99 ✗ return NULL;
100
2/2
✓ Branch 11 → 10 taken 8792 times.
✓ Branch 11 → 12 taken 1099 times.
9891 for (b = 0; b < 8; b++) {
101 8792 memcpy(dst, &block[b * 8], 8);
102 8792 dst += seq->frame->linesize[0];
103 }
104 1099 break;
105 1409 case 2:
106 1409 src = seq_unpack_rle_block(src, src_end, block, sizeof(block));
107
1/2
✗ Branch 14 → 15 not taken.
✓ Branch 14 → 16 taken 1409 times.
1409 if (!src)
108 ✗ return NULL;
109
2/2
✓ Branch 21 → 17 taken 11272 times.
✓ Branch 21 → 22 taken 1409 times.
12681 for (i = 0; i < 8; i++) {
110
2/2
✓ Branch 19 → 18 taken 90176 times.
✓ Branch 19 → 20 taken 11272 times.
101448 for (b = 0; b < 8; b++)
111 90176 dst[b * seq->frame->linesize[0]] = block[i * 8 + b];
112 11272 ++dst;
113 }
114 1409 break;
115 }
116 } else {
117
1/2
✗ Branch 24 → 25 not taken.
✓ Branch 24 → 26 taken 4250 times.
4250 if (len <= 0)
118 ✗ return NULL;
119 4250 bits = ff_log2_tab[len - 1] + 1;
120
1/2
✗ Branch 26 → 27 not taken.
✓ Branch 26 → 28 taken 4250 times.
4250 if (src_end - src < len + 8 * bits)
121 ✗ return NULL;
122 4250 color_table = src;
123 4250 src += len;
124 4250 init_get_bits(&gb, src, bits * 8 * 8); src += bits * 8;
125
2/2
✓ Branch 35 → 30 taken 34000 times.
✓ Branch 35 → 36 taken 4250 times.
38250 for (b = 0; b < 8; b++) {
126
2/2
✓ Branch 33 → 31 taken 272000 times.
✓ Branch 33 → 34 taken 34000 times.
306000 for (i = 0; i < 8; i++)
127 272000 dst[i] = color_table[get_bits(&gb, bits)];
128 34000 dst += seq->frame->linesize[0];
129 }
130 }
131
132 6758 return src;
133 }
134
135 197 static const unsigned char *seq_decode_op2(SeqVideoContext *seq,
136 const unsigned char *src,
137 const unsigned char *src_end,
138 unsigned char *dst)
139 {
140 int i;
141
142
1/2
✗ Branch 2 → 3 not taken.
✓ Branch 2 → 4 taken 197 times.
197 if (src_end - src < 8 * 8)
143 ✗ return NULL;
144
145
2/2
✓ Branch 6 → 5 taken 1576 times.
✓ Branch 6 → 7 taken 197 times.
1773 for (i = 0; i < 8; i++) {
146 1576 memcpy(dst, src, 8);
147 1576 src += 8;
148 1576 dst += seq->frame->linesize[0];
149 }
150
151 197 return src;
152 }
153
154 595 static const unsigned char *seq_decode_op3(SeqVideoContext *seq,
155 const unsigned char *src,
156 const unsigned char *src_end,
157 unsigned char *dst)
158 {
159 int pos, offset;
160
161 do {
162
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 3101 times.
3101 if (src_end - src < 2)
163 ✗ return NULL;
164 3101 pos = *src++;
165 3101 offset = ((pos >> 3) & 7) * seq->frame->linesize[0] + (pos & 7);
166 3101 dst[offset] = *src++;
167
2/2
✓ Branch 5 → 6 taken 2506 times.
✓ Branch 5 → 7 taken 595 times.
3101 } while (!(pos & 0x80));
168
169 595 return src;
170 }
171
172 21 static int seqvideo_decode(SeqVideoContext *seq, const unsigned char *data, int data_size)
173 {
174 21 const unsigned char *data_end = data + data_size;
175 GetBitContext gb;
176 int flags, i, j, x, y, op;
177 unsigned char c[3];
178 unsigned char *dst;
179 uint32_t *palette;
180
181 21 flags = *data++;
182
183
1/2
✓ Branch 2 → 3 taken 21 times.
✗ Branch 2 → 11 not taken.
21 if (flags & 1) {
184 21 palette = (uint32_t *)seq->frame->data[1];
185
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 21 times.
21 if (data_end - data < 256 * 3)
186 ✗ return AVERROR_INVALIDDATA;
187
2/2
✓ Branch 10 → 6 taken 5376 times.
✓ Branch 10 → 11 taken 21 times.
5397 for (i = 0; i < 256; i++) {
188
2/2
✓ Branch 8 → 7 taken 16128 times.
✓ Branch 8 → 9 taken 5376 times.
21504 for (j = 0; j < 3; j++, data++)
189 16128 c[j] = (*data << 2) | (*data >> 4);
190 5376 palette[i] = 0xFFU << 24 | AV_RB24(c);
191 }
192 }
193
194
1/2
✓ Branch 11 → 12 taken 21 times.
✗ Branch 11 → 31 not taken.
21 if (flags & 2) {
195
1/2
✗ Branch 12 → 13 not taken.
✓ Branch 12 → 14 taken 21 times.
21 if (data_end - data < 128)
196 ✗ return AVERROR_INVALIDDATA;
197 21 init_get_bits(&gb, data, 128 * 8); data += 128;
198
2/2
✓ Branch 30 → 16 taken 336 times.
✓ Branch 30 → 31 taken 21 times.
357 for (y = 0; y < 128; y += 8)
199
2/2
✓ Branch 28 → 17 taken 10752 times.
✓ Branch 28 → 29 taken 336 times.
11088 for (x = 0; x < 256; x += 8) {
200 10752 dst = &seq->frame->data[0][y * seq->frame->linesize[0] + x];
201 10752 op = get_bits(&gb, 2);
202
4/4
✓ Branch 18 → 19 taken 6758 times.
✓ Branch 18 → 21 taken 197 times.
✓ Branch 18 → 23 taken 595 times.
✓ Branch 18 → 25 taken 3202 times.
10752 switch (op) {
203 6758 case 1:
204 6758 data = seq_decode_op1(seq, data, data_end, dst);
205 6758 break;
206 197 case 2:
207 197 data = seq_decode_op2(seq, data, data_end, dst);
208 197 break;
209 595 case 3:
210 595 data = seq_decode_op3(seq, data, data_end, dst);
211 595 break;
212 }
213
1/2
✗ Branch 25 → 26 not taken.
✓ Branch 25 → 27 taken 10752 times.
10752 if (!data)
214 ✗ return AVERROR_INVALIDDATA;
215 }
216 }
217 21 return 0;
218 }
219
220 2 static av_cold int seqvideo_decode_init(AVCodecContext *avctx)
221 {
222 2 SeqVideoContext *seq = avctx->priv_data;
223 int ret;
224
225 2 seq->avctx = avctx;
226 2 avctx->pix_fmt = AV_PIX_FMT_PAL8;
227
228 2 ret = ff_set_dimensions(avctx, 256, 128);
229
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 2 times.
2 if (ret < 0)
230 ✗ return ret;
231
232 2 seq->frame = av_frame_alloc();
233
1/2
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 2 times.
2 if (!seq->frame)
234 ✗ return AVERROR(ENOMEM);
235
236 2 return 0;
237 }
238
239 21 static int seqvideo_decode_frame(AVCodecContext *avctx, AVFrame *rframe,
240 int *got_frame, AVPacket *avpkt)
241 {
242 21 const uint8_t *buf = avpkt->data;
243 21 int buf_size = avpkt->size;
244 int ret;
245
246 21 SeqVideoContext *seq = avctx->priv_data;
247
248
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 21 times.
21 if ((ret = ff_reget_buffer(avctx, seq->frame, 0)) < 0)
249 ✗ return ret;
250
251
1/2
✗ Branch 6 → 7 not taken.
✓ Branch 6 → 8 taken 21 times.
21 if (seqvideo_decode(seq, buf, buf_size))
252 ✗ return AVERROR_INVALIDDATA;
253
254
1/2
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 11 taken 21 times.
21 if ((ret = av_frame_ref(rframe, seq->frame)) < 0)
255 ✗ return ret;
256 21 *got_frame = 1;
257
258 21 return buf_size;
259 }
260
261 2 static av_cold int seqvideo_decode_end(AVCodecContext *avctx)
262 {
263 2 SeqVideoContext *seq = avctx->priv_data;
264
265 2 av_frame_free(&seq->frame);
266
267 2 return 0;
268 }
269
270 const FFCodec ff_tiertexseqvideo_decoder = {
271 .p.name = "tiertexseqvideo",
272 CODEC_LONG_NAME("Tiertex Limited SEQ video"),
273 .p.type = AVMEDIA_TYPE_VIDEO,
274 .p.id = AV_CODEC_ID_TIERTEXSEQVIDEO,
275 .priv_data_size = sizeof(SeqVideoContext),
276 .init = seqvideo_decode_init,
277 .close = seqvideo_decode_end,
278 FF_CODEC_DECODE_CB(seqvideo_decode_frame),
279 .p.capabilities = AV_CODEC_CAP_DR1,
280 };
281