annotate src/ffmpeg/libavcodec/rpza.c @ 854:aac49941ee8f trunk

[svn] statusicon 0.3: alternative right-click menu with simple playback control commands
author giacomo
date Wed, 14 Mar 2007 07:44:00 -0700
parents e8776388b02a
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
808
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
1 /*
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
2 * Quicktime Video (RPZA) Video Decoder
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
3 * Copyright (C) 2003 the ffmpeg project
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
4 *
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
5 * This file is part of FFmpeg.
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
6 *
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
7 * FFmpeg is free software; you can redistribute it and/or
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
9 * License as published by the Free Software Foundation; either
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
10 * version 2.1 of the License, or (at your option) any later version.
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
11 *
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
12 * FFmpeg is distributed in the hope that it will be useful,
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
15 * Lesser General Public License for more details.
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
16 *
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
17 * You should have received a copy of the GNU Lesser General Public
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
18 * License along with FFmpeg; if not, write to the Free Software
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
20 *
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
21 */
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
22
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
23 /**
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
24 * @file rpza.c
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
25 * QT RPZA Video Decoder by Roberto Togni <rtogni@bresciaonline.it>
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
26 * For more information about the RPZA format, visit:
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
27 * http://www.pcisys.net/~melanson/codecs/
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
28 *
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
29 * The RPZA decoder outputs RGB555 colorspace data.
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
30 *
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
31 * Note that this decoder reads big endian RGB555 pixel values from the
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
32 * bytestream, arranges them in the host's endian order, and outputs
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
33 * them to the final rendered map in the same host endian order. This is
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
34 * intended behavior as the ffmpeg documentation states that RGB555 pixels
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
35 * shall be stored in native CPU endianness.
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
36 */
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
37
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
38 #include <stdio.h>
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
39 #include <stdlib.h>
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
40 #include <string.h>
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
41 #include <unistd.h>
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
42
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
43 #include "common.h"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
44 #include "avcodec.h"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
45 #include "dsputil.h"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
46
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
47 typedef struct RpzaContext {
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
48
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
49 AVCodecContext *avctx;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
50 DSPContext dsp;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
51 AVFrame frame;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
52
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
53 unsigned char *buf;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
54 int size;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
55
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
56 } RpzaContext;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
57
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
58 #define ADVANCE_BLOCK() \
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
59 { \
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
60 pixel_ptr += 4; \
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
61 if (pixel_ptr >= width) \
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
62 { \
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
63 pixel_ptr = 0; \
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
64 row_ptr += stride * 4; \
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
65 } \
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
66 total_blocks--; \
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
67 if (total_blocks < 0) \
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
68 { \
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
69 av_log(s->avctx, AV_LOG_ERROR, "warning: block counter just went negative (this should not happen)\n"); \
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
70 return; \
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
71 } \
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
72 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
73
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
74 static void rpza_decode_stream(RpzaContext *s)
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
75 {
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
76 int width = s->avctx->width;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
77 int stride = s->frame.linesize[0] / 2;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
78 int row_inc = stride - 4;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
79 int stream_ptr = 0;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
80 int chunk_size;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
81 unsigned char opcode;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
82 int n_blocks;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
83 unsigned short colorA = 0, colorB;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
84 unsigned short color4[4];
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
85 unsigned char index, idx;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
86 unsigned short ta, tb;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
87 unsigned short *pixels = (unsigned short *)s->frame.data[0];
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
88
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
89 int row_ptr = 0;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
90 int pixel_ptr = 0;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
91 int block_ptr;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
92 int pixel_x, pixel_y;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
93 int total_blocks;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
94
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
95 /* First byte is always 0xe1. Warn if it's different */
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
96 if (s->buf[stream_ptr] != 0xe1)
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
97 av_log(s->avctx, AV_LOG_ERROR, "First chunk byte is 0x%02x instead of 0xe1\n",
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
98 s->buf[stream_ptr]);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
99
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
100 /* Get chunk size, ingnoring first byte */
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
101 chunk_size = BE_32(&s->buf[stream_ptr]) & 0x00FFFFFF;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
102 stream_ptr += 4;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
103
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
104 /* If length mismatch use size from MOV file and try to decode anyway */
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
105 if (chunk_size != s->size)
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
106 av_log(s->avctx, AV_LOG_ERROR, "MOV chunk size != encoded chunk size; using MOV chunk size\n");
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
107
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
108 chunk_size = s->size;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
109
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
110 /* Number of 4x4 blocks in frame. */
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
111 total_blocks = ((s->avctx->width + 3) / 4) * ((s->avctx->height + 3) / 4);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
112
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
113 /* Process chunk data */
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
114 while (stream_ptr < chunk_size) {
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
115 opcode = s->buf[stream_ptr++]; /* Get opcode */
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
116
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
117 n_blocks = (opcode & 0x1f) + 1; /* Extract block counter from opcode */
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
118
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
119 /* If opcode MSbit is 0, we need more data to decide what to do */
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
120 if ((opcode & 0x80) == 0) {
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
121 colorA = (opcode << 8) | (s->buf[stream_ptr++]);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
122 opcode = 0;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
123 if ((s->buf[stream_ptr] & 0x80) != 0) {
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
124 /* Must behave as opcode 110xxxxx, using colorA computed
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
125 * above. Use fake opcode 0x20 to enter switch block at
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
126 * the right place */
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
127 opcode = 0x20;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
128 n_blocks = 1;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
129 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
130 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
131
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
132 switch (opcode & 0xe0) {
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
133
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
134 /* Skip blocks */
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
135 case 0x80:
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
136 while (n_blocks--) {
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
137 ADVANCE_BLOCK();
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
138 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
139 break;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
140
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
141 /* Fill blocks with one color */
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
142 case 0xa0:
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
143 colorA = BE_16 (&s->buf[stream_ptr]);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
144 stream_ptr += 2;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
145 while (n_blocks--) {
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
146 block_ptr = row_ptr + pixel_ptr;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
147 for (pixel_y = 0; pixel_y < 4; pixel_y++) {
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
148 for (pixel_x = 0; pixel_x < 4; pixel_x++){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
149 pixels[block_ptr] = colorA;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
150 block_ptr++;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
151 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
152 block_ptr += row_inc;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
153 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
154 ADVANCE_BLOCK();
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
155 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
156 break;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
157
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
158 /* Fill blocks with 4 colors */
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
159 case 0xc0:
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
160 colorA = BE_16 (&s->buf[stream_ptr]);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
161 stream_ptr += 2;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
162 case 0x20:
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
163 colorB = BE_16 (&s->buf[stream_ptr]);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
164 stream_ptr += 2;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
165
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
166 /* sort out the colors */
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
167 color4[0] = colorB;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
168 color4[1] = 0;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
169 color4[2] = 0;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
170 color4[3] = colorA;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
171
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
172 /* red components */
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
173 ta = (colorA >> 10) & 0x1F;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
174 tb = (colorB >> 10) & 0x1F;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
175 color4[1] |= ((11 * ta + 21 * tb) >> 5) << 10;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
176 color4[2] |= ((21 * ta + 11 * tb) >> 5) << 10;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
177
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
178 /* green components */
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
179 ta = (colorA >> 5) & 0x1F;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
180 tb = (colorB >> 5) & 0x1F;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
181 color4[1] |= ((11 * ta + 21 * tb) >> 5) << 5;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
182 color4[2] |= ((21 * ta + 11 * tb) >> 5) << 5;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
183
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
184 /* blue components */
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
185 ta = colorA & 0x1F;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
186 tb = colorB & 0x1F;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
187 color4[1] |= ((11 * ta + 21 * tb) >> 5);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
188 color4[2] |= ((21 * ta + 11 * tb) >> 5);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
189
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
190 while (n_blocks--) {
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
191 block_ptr = row_ptr + pixel_ptr;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
192 for (pixel_y = 0; pixel_y < 4; pixel_y++) {
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
193 index = s->buf[stream_ptr++];
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
194 for (pixel_x = 0; pixel_x < 4; pixel_x++){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
195 idx = (index >> (2 * (3 - pixel_x))) & 0x03;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
196 pixels[block_ptr] = color4[idx];
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
197 block_ptr++;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
198 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
199 block_ptr += row_inc;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
200 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
201 ADVANCE_BLOCK();
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
202 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
203 break;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
204
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
205 /* Fill block with 16 colors */
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
206 case 0x00:
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
207 block_ptr = row_ptr + pixel_ptr;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
208 for (pixel_y = 0; pixel_y < 4; pixel_y++) {
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
209 for (pixel_x = 0; pixel_x < 4; pixel_x++){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
210 /* We already have color of upper left pixel */
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
211 if ((pixel_y != 0) || (pixel_x !=0)) {
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
212 colorA = BE_16 (&s->buf[stream_ptr]);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
213 stream_ptr += 2;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
214 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
215 pixels[block_ptr] = colorA;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
216 block_ptr++;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
217 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
218 block_ptr += row_inc;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
219 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
220 ADVANCE_BLOCK();
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
221 break;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
222
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
223 /* Unknown opcode */
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
224 default:
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
225 av_log(s->avctx, AV_LOG_ERROR, "Unknown opcode %d in rpza chunk."
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
226 " Skip remaining %d bytes of chunk data.\n", opcode,
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
227 chunk_size - stream_ptr);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
228 return;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
229 } /* Opcode switch */
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
230 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
231 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
232
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
233 static int rpza_decode_init(AVCodecContext *avctx)
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
234 {
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
235 RpzaContext *s = (RpzaContext *)avctx->priv_data;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
236
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
237 s->avctx = avctx;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
238 avctx->pix_fmt = PIX_FMT_RGB555;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
239 avctx->has_b_frames = 0;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
240 dsputil_init(&s->dsp, avctx);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
241
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
242 s->frame.data[0] = NULL;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
243
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
244 return 0;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
245 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
246
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
247 static int rpza_decode_frame(AVCodecContext *avctx,
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
248 void *data, int *data_size,
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
249 uint8_t *buf, int buf_size)
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
250 {
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
251 RpzaContext *s = (RpzaContext *)avctx->priv_data;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
252
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
253 s->buf = buf;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
254 s->size = buf_size;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
255
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
256 s->frame.reference = 1;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
257 s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
258 if (avctx->reget_buffer(avctx, &s->frame)) {
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
259 av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
260 return -1;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
261 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
262
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
263 rpza_decode_stream(s);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
264
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
265 *data_size = sizeof(AVFrame);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
266 *(AVFrame*)data = s->frame;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
267
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
268 /* always report that the buffer was completely consumed */
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
269 return buf_size;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
270 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
271
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
272 static int rpza_decode_end(AVCodecContext *avctx)
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
273 {
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
274 RpzaContext *s = (RpzaContext *)avctx->priv_data;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
275
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
276 if (s->frame.data[0])
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
277 avctx->release_buffer(avctx, &s->frame);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
278
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
279 return 0;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
280 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
281
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
282 AVCodec rpza_decoder = {
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
283 "rpza",
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
284 CODEC_TYPE_VIDEO,
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
285 CODEC_ID_RPZA,
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
286 sizeof(RpzaContext),
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
287 rpza_decode_init,
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
288 NULL,
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
289 rpza_decode_end,
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
290 rpza_decode_frame,
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
291 CODEC_CAP_DR1,
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
292 };