1 /*
2 * Mirillis FIC decoder
3 *
4 * Copyright (c) 2014 Konstantin Shishkov
5 * Copyright (c) 2014 Derek Buitenhuis
6 *
7 * This file is part of FFmpeg.
8 *
9 * FFmpeg is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * FFmpeg is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with FFmpeg; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 */
23
33
42
48
51
53
55
58
61
63 1, 2, 2, 2, 3, 3, 3, 4,
64 2, 2, 2, 3, 3, 3, 4, 4,
65 2, 2, 3, 3, 3, 4, 4, 4,
66 2, 2, 3, 3, 3, 4, 4, 5,
67 2, 3, 3, 3, 4, 4, 5, 6,
68 3, 3, 3, 4, 4, 5, 6, 7,
69 3, 3, 3, 4, 4, 5, 7, 7,
70 3, 3, 4, 4, 5, 7, 7, 7,
71 };
72
74 1, 5, 6, 7, 8, 9, 9, 11,
75 5, 5, 7, 8, 9, 9, 11, 12,
76 6, 7, 8, 9, 9, 11, 11, 12,
77 7, 7, 8, 9, 9, 11, 12, 13,
78 7, 8, 9, 9, 10, 11, 13, 16,
79 8, 9, 9, 10, 11, 13, 16, 19,
80 8, 9, 9, 11, 12, 15, 18, 23,
81 9, 9, 11, 12, 15, 18, 23, 27
82 };
83
84 static const uint8_t
fic_header[7] = { 0, 0, 1,
'F',
'I',
'C',
'V' };
85
86 #define FIC_HEADER_SIZE 27
87 #define CURSOR_OFFSET 59
88 #define CURSOR_SIZE 4096
89
91 {
96 const unsigned t4 = 5793
U * ((int)(t2 + t0 + 0x800) >> 12);
97 const unsigned t5 = 5793
U * ((int)(t3 + t1 + 0x800) >> 12);
98 const unsigned t6 = t2 - t0;
99 const unsigned t7 = t3 - t1;
100 const unsigned t8 = 17734 *
blk[2 *
step] - 42813 *
blk[6 *
step];
101 const unsigned t9 = 17734 *
blk[6 *
step] + 42814 *
blk[2 *
step];
112 }
113
115 {
117 int16_t *ptr;
118
120 fic_idct(ptr++, 8, 13, (1 << 12) + (1 << 17));
121 for (
i = 1;
i < 8;
i++) {
123 ptr++;
124 }
125
127 for (
i = 0;
i < 8;
i++) {
129 ptr += 8;
130 }
131
133 for (j = 0; j < 8; j++) {
134 for (
i = 0;
i < 8;
i++)
137 ptr += 8;
138 }
139 }
142 {
144
147
148 /* Is it a skip block? */
150 *is_p = 1;
151 return 0;
152 }
153
155
157 if (num_coeff > 64)
159
160 for (
i = 0;
i < num_coeff;
i++) {
162 if (v < -2048 || v > 2048)
166 }
167
169
170 return 0;
171 }
172
174 {
178 const uint8_t *
src = tctx->
src;
181 int y_off = tctx->
y_off;
183
187
188 for (
p = 0;
p < 3;
p++) {
191
192 for (y = 0; y < (slice_h >> !!
p); y += 8) {
193 for (x = 0; x < (
ctx->aligned_width >> !!
p); x += 8) {
195
199 }
200
202 }
203 }
204
205 return 0;
206 }
207
210 {
212
215 }
216
218 int cur_x, int cur_y)
219 {
221 const uint8_t *ptr = cursor_buf;
222 uint8_t *dstptr[3];
226
227 /* Convert to YUVA444. */
228 for (
i = 0;
i < 1024;
i++) {
229 planes[0][
i] = (( 25 * ptr[0] + 129 * ptr[1] + 66 * ptr[2]) / 255) + 16;
230 planes[1][
i] = ((-38 * ptr[0] + 112 * ptr[1] + -74 * ptr[2]) / 255) + 128;
231 planes[2][
i] = ((-18 * ptr[0] + 112 * ptr[1] + -94 * ptr[2]) / 255) + 128;
233
234 ptr += 4;
235 }
236
237 /* Subsample chroma. */
238 for (
i = 0;
i < 32;
i += 2)
239 for (j = 0; j < 32; j += 2)
240 for (
p = 0;
p < 3;
p++)
244 planes[
p + 1][32 * (
i + 1) + j + 1]) / 4;
245
246 /* Seek to x/y pos of cursor. */
247 for (
i = 0;
i < 3;
i++)
248 dstptr[
i] =
ctx->final_frame->data[
i] +
249 (
ctx->final_frame->linesize[
i] * (cur_y >> !!
i)) +
250 (cur_x >> !!
i) + !!
i;
251
252 /* Copy. */
255 int csize = lsize / 2;
256
265
266 dstptr[0] +=
ctx->final_frame->linesize[0] * 2;
267 dstptr[1] +=
ctx->final_frame->linesize[1];
268 dstptr[2] +=
ctx->final_frame->linesize[2];
269 }
270 }
271
274 {
276 const uint8_t *
src = avpkt->
data;
278 int slice, nslices;
279 int msize;
280 int tsize;
281 int cur_x, cur_y;
282 int skip_cursor =
ctx->skip_cursor;
283 const uint8_t *sdata;
284
285 /* Header + at least one slice (4) */
289 }
290
291 /* Check for header. */
294
295 /* Is it a skip frame? */
297 if (!
ctx->final_frame->data[0]) {
300 }
306 }
307
309 if (!nslices) {
312 }
313
314 /* High or Low Quality Matrix? */
316
317 /* Skip cursor data. */
321 "Packet is too small to contain cursor (%d vs %d bytes).\n",
324 }
325
327 skip_cursor = 1;
328
329 if (!skip_cursor && tsize < 32) {
331 "Cursor data too small. Skipping cursor.\n");
332 skip_cursor = 1;
333 }
334
335 /* Cursor position. */
338 if (!skip_cursor && (cur_x > avctx->
width || cur_y > avctx->
height)) {
340 "Invalid cursor position: (%d,%d). Skipping cursor.\n",
341 cur_x, cur_y);
342 skip_cursor = 1;
343 }
344
347 "Invalid cursor size. Skipping cursor.\n");
348 skip_cursor = 1;
349 }
350
352 skip_cursor = 1;
353
354 /* Slice height for all but the last slice. */
355 ctx->slice_h = 16 * (
ctx->aligned_height >> 4) / nslices;
356 if (
ctx->slice_h % 16)
358
359 /* First slice offset and remaining data. */
362
363 if (msize <= ctx->aligned_width/8 * (
ctx->aligned_height/8) / 8) {
366 }
367
368 /* Allocate slice data. */
370 nslices *
sizeof(
ctx->slice_data[0]));
371 if (!
ctx->slice_data_size) {
374 }
375 memset(
ctx->slice_data, 0, nslices *
sizeof(
ctx->slice_data[0]));
376
377 for (slice = 0; slice < nslices; slice++) {
379 unsigned slice_size;
380 int y_off =
ctx->slice_h * slice;
381 int slice_h =
ctx->slice_h;
382
383 /*
384 * Either read the slice size, or consume all data left.
385 * Also, special case the last slight height.
386 */
387 if (slice == nslices - 1) {
388 slice_size = msize;
390 } else {
392 if (slice_size < slice_off)
394 }
395
396 if (slice_size < slice_off || slice_size > msize)
397 continue;
398
399 slice_size -= slice_off;
400
401 ctx->slice_data[slice].src = sdata + slice_off;
402 ctx->slice_data[slice].src_size = slice_size;
403 ctx->slice_data[slice].slice_h = slice_h;
404 ctx->slice_data[slice].y_off = y_off;
405 }
406
409
411 NULL, nslices,
sizeof(
ctx->slice_data[0]))) < 0)
413
416 for (slice = 0; slice < nslices; slice++) {
417 if (
ctx->slice_data[slice].p_frame) {
420 break;
421 }
422 }
426
427 /* Draw cursor if needed. */
428 if (!skip_cursor) {
429 /* Make frame writable. */
433
435 }
436
440 *got_frame = 1;
441
443 }
444
446 {
448
452
453 return 0;
454 }
455
457 {
459
460 /* Initialize various context values */
464
467
472 if (!
ctx->final_frame)
474
475 return 0;
476 }
477
481 };
482
488 };
489
502 };