1 /*
2 * Psygnosis YOP decoder
3 *
4 * Copyright (C) 2010 Mohamed Naufal Basheer <naufal11@gmail.com>
5 * derived from the code by
6 * Copyright (C) 2009 Thomas P. Higdon <thomas.p.higdon@gmail.com>
7 *
8 * This file is part of FFmpeg.
9 *
10 * FFmpeg is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
14 *
15 * FFmpeg is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with FFmpeg; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25 #include <string.h>
26
29
33
37
41
48
49 // These tables are taken directly from:
50 // http://wiki.multimedia.cx/index.php?title=Psygnosis_YOP
51
52 /**
53 * Lookup table for painting macroblocks. Bytes 0-2 of each entry contain
54 * the macroblock positions to be painted (taken as (0, B0, B1, B2)).
55 * Byte 3 contains the number of bytes consumed on the input,
56 * equal to max(bytes 0-2) + 1.
57 */
59 {{1, 2, 3, 4}, {1, 2, 0, 3},
60 {1, 2, 1, 3}, {1, 2, 2, 3},
61 {1, 0, 2, 3}, {1, 0, 0, 2},
62 {1, 0, 1, 2}, {1, 1, 2, 3},
63 {0, 1, 2, 3}, {0, 1, 0, 2},
64 {1, 1, 0, 2}, {0, 1, 1, 2},
65 {0, 0, 1, 2}, {0, 0, 0, 1},
66 {1, 1, 1, 2},
67 };
68
69 /**
70 * Lookup table for copying macroblocks. Each entry contains the respective
71 * x and y pixel offset for the copy source.
72 */
74 {{-4, -4}, {-2, -4},
75 { 0, -4}, { 2, -4},
76 {-4, -2}, {-4, 0},
77 {-3, -3}, {-1, -3},
78 { 1, -3}, { 3, -3},
79 {-3, -1}, {-2, -2},
80 { 0, -2}, { 2, -2},
81 { 4, -2}, {-2, 0},
82 };
83
85 {
87
89
90 return 0;
91 }
92
94 {
97
102 }
103
107 }
108
110
114
115 if (
s->num_pal_colors +
s->first_color[0] > 256 ||
116 s->num_pal_colors +
s->first_color[1] > 256) {
118 "Palette parameters invalid, header probably corrupt\n");
120 }
121
125
126 return 0;
127 }
128
129 /**
130 * Paint a macroblock using the pattern in paint_lut.
131 * @param s codec context
132 * @param tag the tag that was in the nibble
133 */
135 {
139 }
140
141 s->dstptr[0] =
s->srcptr[0];
145
146 // The number of src bytes consumed is in the last part of the lut entry.
148 return 0;
149 }
150
151 /**
152 * Copy a previously painted macroblock to the current_block.
153 * @param copy_tag the tag that was in the nibble
154 */
156 {
157 uint8_t *bufptr;
158
159 // Calculate position for the copy source
162 if (bufptr < s->dstbuf) {
165 }
166
167 s->dstptr[0] = bufptr[0];
168 s->dstptr[1] = bufptr[1];
169 s->dstptr[linesize] = bufptr[linesize];
170 s->dstptr[linesize + 1] = bufptr[linesize + 1];
171
172 return 0;
173 }
174
175 /**
176 * Return the next nibble in sequence, consuming a new byte on the input
177 * only if necessary.
178 */
180 {
182
184 ret = *
s->low_nibble & 0xf;
185 s->low_nibble =
NULL;
186 }else {
187 s->low_nibble =
s->srcptr++;
188 ret = *
s->low_nibble >> 4;
189 }
191 }
192
195 {
198 int tag, firstcolor, is_odd_frame;
200 uint32_t *palette;
201
202 if (avpkt->
size < 4 + 3 *
s->num_pal_colors) {
205 }
206
209
212
213 s->dstbuf =
frame->data[0];
214 s->dstptr =
frame->data[0];
215 s->srcptr = avpkt->
data + 4;
217 s->low_nibble =
NULL;
218
219 is_odd_frame = avpkt->
data[0];
220 if(is_odd_frame>1){
223 }
224 firstcolor =
s->first_color[is_odd_frame];
225 palette = (uint32_t *)
frame->data[1];
226
227 for (
i = 0;
i <
s->num_pal_colors;
i++,
s->srcptr += 3) {
228 palette[
i + firstcolor] = (
s->srcptr[0] << 18) |
229 (
s->srcptr[1] << 10) |
231 palette[
i + firstcolor] |= 0xFF
U << 24 |
232 (palette[
i + firstcolor] >> 6) & 0x30303;
233 }
234
235 for (y = 0; y < avctx->
height; y += 2) {
236 for (x = 0; x < avctx->
width; x += 2) {
237 if (
s->srcptr - avpkt->
data >= avpkt->
size) {
240 }
241
243
248 } else {
253 }
255 }
256 s->dstptr += 2*
frame->linesize[0] - x;
257 }
258
261
262 *got_frame = 1;
264 }
265
276 };