Mercurial > libavcodec.hg
comparison qpeg.c @ 2979:bfabfdf9ce55 libavcodec
COSMETICS: tabs --> spaces, some prettyprinting
author | diego |
---|---|
date | Thu, 22 Dec 2005 01:10:11 +0000 |
parents | ef2149182f1c |
children | 0b546eab515d |
comparison
equal
deleted
inserted
replaced
2978:403183bbb505 | 2979:bfabfdf9ce55 |
---|---|
31 AVFrame pic; | 31 AVFrame pic; |
32 uint8_t *refdata; | 32 uint8_t *refdata; |
33 } QpegContext; | 33 } QpegContext; |
34 | 34 |
35 static void qpeg_decode_intra(uint8_t *src, uint8_t *dst, int size, | 35 static void qpeg_decode_intra(uint8_t *src, uint8_t *dst, int size, |
36 int stride, int width, int height) | 36 int stride, int width, int height) |
37 { | 37 { |
38 int i; | 38 int i; |
39 int code; | 39 int code; |
40 int c0, c1; | 40 int c0, c1; |
41 int run, copy; | 41 int run, copy; |
45 rows_to_go = height; | 45 rows_to_go = height; |
46 height--; | 46 height--; |
47 dst = dst + height * stride; | 47 dst = dst + height * stride; |
48 | 48 |
49 while((size > 0) && (rows_to_go > 0)) { | 49 while((size > 0) && (rows_to_go > 0)) { |
50 code = *src++; | 50 code = *src++; |
51 size--; | 51 size--; |
52 run = copy = 0; | 52 run = copy = 0; |
53 if(code == 0xFC) /* end-of-picture code */ | 53 if(code == 0xFC) /* end-of-picture code */ |
54 break; | 54 break; |
55 if(code >= 0xF8) { /* very long run */ | 55 if(code >= 0xF8) { /* very long run */ |
56 c0 = *src++; | 56 c0 = *src++; |
57 c1 = *src++; | 57 c1 = *src++; |
58 size -= 2; | 58 size -= 2; |
59 run = ((code & 0x7) << 16) + (c0 << 8) + c1 + 2; | 59 run = ((code & 0x7) << 16) + (c0 << 8) + c1 + 2; |
60 } else if (code >= 0xF0) { /* long run */ | 60 } else if (code >= 0xF0) { /* long run */ |
61 c0 = *src++; | 61 c0 = *src++; |
62 size--; | 62 size--; |
63 run = ((code & 0xF) << 8) + c0 + 2; | 63 run = ((code & 0xF) << 8) + c0 + 2; |
64 } else if (code >= 0xE0) { /* short run */ | 64 } else if (code >= 0xE0) { /* short run */ |
65 run = (code & 0x1F) + 2; | 65 run = (code & 0x1F) + 2; |
66 } else if (code >= 0xC0) { /* very long copy */ | 66 } else if (code >= 0xC0) { /* very long copy */ |
67 c0 = *src++; | 67 c0 = *src++; |
68 c1 = *src++; | 68 c1 = *src++; |
69 size -= 2; | 69 size -= 2; |
70 copy = ((code & 0x3F) << 16) + (c0 << 8) + c1 + 1; | 70 copy = ((code & 0x3F) << 16) + (c0 << 8) + c1 + 1; |
71 } else if (code >= 0x80) { /* long copy */ | 71 } else if (code >= 0x80) { /* long copy */ |
72 c0 = *src++; | 72 c0 = *src++; |
73 size--; | 73 size--; |
74 copy = ((code & 0x7F) << 8) + c0 + 1; | 74 copy = ((code & 0x7F) << 8) + c0 + 1; |
75 } else { /* short copy */ | 75 } else { /* short copy */ |
76 copy = code + 1; | 76 copy = code + 1; |
77 } | 77 } |
78 | 78 |
79 /* perform actual run or copy */ | 79 /* perform actual run or copy */ |
80 if(run) { | 80 if(run) { |
81 int p; | 81 int p; |
82 | 82 |
83 p = *src++; | 83 p = *src++; |
84 size--; | 84 size--; |
85 for(i = 0; i < run; i++) { | 85 for(i = 0; i < run; i++) { |
86 dst[filled++] = p; | 86 dst[filled++] = p; |
87 if (filled >= width) { | 87 if (filled >= width) { |
88 filled = 0; | 88 filled = 0; |
89 dst -= stride; | 89 dst -= stride; |
90 rows_to_go--; | 90 rows_to_go--; |
91 if(rows_to_go <= 0) | 91 if(rows_to_go <= 0) |
92 break; | 92 break; |
93 } | 93 } |
94 } | 94 } |
95 } else { | 95 } else { |
96 size -= copy; | 96 size -= copy; |
97 for(i = 0; i < copy; i++) { | 97 for(i = 0; i < copy; i++) { |
98 dst[filled++] = *src++; | 98 dst[filled++] = *src++; |
99 if (filled >= width) { | 99 if (filled >= width) { |
100 filled = 0; | 100 filled = 0; |
101 dst -= stride; | 101 dst -= stride; |
102 rows_to_go--; | 102 rows_to_go--; |
103 if(rows_to_go <= 0) | 103 if(rows_to_go <= 0) |
104 break; | 104 break; |
105 } | 105 } |
106 } | 106 } |
107 } | 107 } |
108 } | 108 } |
109 } | 109 } |
110 | 110 |
111 static int qpeg_table_h[16] = | 111 static int qpeg_table_h[16] = |
112 { 0x00, 0x20, 0x20, 0x20, 0x18, 0x10, 0x10, 0x20, 0x10, 0x08, 0x18, 0x08, 0x08, 0x18, 0x10, 0x04}; | 112 { 0x00, 0x20, 0x20, 0x20, 0x18, 0x10, 0x10, 0x20, 0x10, 0x08, 0x18, 0x08, 0x08, 0x18, 0x10, 0x04}; |
113 static int qpeg_table_w[16] = | 113 static int qpeg_table_w[16] = |
114 { 0x00, 0x20, 0x18, 0x08, 0x18, 0x10, 0x20, 0x10, 0x08, 0x10, 0x20, 0x20, 0x08, 0x10, 0x18, 0x04}; | 114 { 0x00, 0x20, 0x18, 0x08, 0x18, 0x10, 0x20, 0x10, 0x08, 0x10, 0x20, 0x20, 0x08, 0x10, 0x18, 0x04}; |
115 | 115 |
116 /* Decodes delta frames */ | 116 /* Decodes delta frames */ |
117 static void qpeg_decode_inter(uint8_t *src, uint8_t *dst, int size, | 117 static void qpeg_decode_inter(uint8_t *src, uint8_t *dst, int size, |
118 int stride, int width, int height, | 118 int stride, int width, int height, |
119 int delta, uint8_t *ctable, uint8_t *refdata) | 119 int delta, uint8_t *ctable, uint8_t *refdata) |
120 { | 120 { |
121 int i, j; | 121 int i, j; |
122 int code; | 122 int code; |
123 int filled = 0; | 123 int filled = 0; |
124 int orig_height; | 124 int orig_height; |
125 uint8_t *blkdata; | 125 uint8_t *blkdata; |
126 | 126 |
127 /* copy prev frame */ | 127 /* copy prev frame */ |
128 for(i = 0; i < height; i++) | 128 for(i = 0; i < height; i++) |
129 memcpy(refdata + (i * width), dst + (i * stride), width); | 129 memcpy(refdata + (i * width), dst + (i * stride), width); |
130 | 130 |
131 orig_height = height; | 131 orig_height = height; |
132 blkdata = src - 0x86; | 132 blkdata = src - 0x86; |
133 height--; | 133 height--; |
134 dst = dst + height * stride; | 134 dst = dst + height * stride; |
135 | 135 |
136 while((size > 0) && (height >= 0)) { | 136 while((size > 0) && (height >= 0)) { |
137 code = *src++; | 137 code = *src++; |
138 size--; | 138 size--; |
139 | 139 |
140 if(delta) { | 140 if(delta) { |
141 /* motion compensation */ | 141 /* motion compensation */ |
142 while((code & 0xF0) == 0xF0) { | 142 while((code & 0xF0) == 0xF0) { |
143 if(delta == 1) { | 143 if(delta == 1) { |
144 int me_idx; | 144 int me_idx; |
145 int me_w, me_h, me_x, me_y; | 145 int me_w, me_h, me_x, me_y; |
146 uint8_t *me_plane; | 146 uint8_t *me_plane; |
147 int corr, val; | 147 int corr, val; |
148 | 148 |
149 /* get block size by index */ | 149 /* get block size by index */ |
150 me_idx = code & 0xF; | 150 me_idx = code & 0xF; |
151 me_w = qpeg_table_w[me_idx]; | 151 me_w = qpeg_table_w[me_idx]; |
152 me_h = qpeg_table_h[me_idx]; | 152 me_h = qpeg_table_h[me_idx]; |
153 | 153 |
154 /* extract motion vector */ | 154 /* extract motion vector */ |
155 corr = *src++; | 155 corr = *src++; |
156 size--; | 156 size--; |
157 | 157 |
158 val = corr >> 4; | 158 val = corr >> 4; |
159 if(val > 7) | 159 if(val > 7) |
160 val -= 16; | 160 val -= 16; |
161 me_x = val; | 161 me_x = val; |
162 | 162 |
163 val = corr & 0xF; | 163 val = corr & 0xF; |
164 if(val > 7) | 164 if(val > 7) |
165 val -= 16; | 165 val -= 16; |
166 me_y = val; | 166 me_y = val; |
167 | 167 |
168 /* check motion vector */ | 168 /* check motion vector */ |
169 if ((me_x + filled < 0) || (me_x + me_w + filled > width) || | 169 if ((me_x + filled < 0) || (me_x + me_w + filled > width) || |
170 (height - me_y - me_h < 0) || (height - me_y > orig_height) || | 170 (height - me_y - me_h < 0) || (height - me_y > orig_height) || |
171 (filled + me_w > width) || (height - me_h < 0)) | 171 (filled + me_w > width) || (height - me_h < 0)) |
176 me_plane = refdata + (filled + me_x) + (height - me_y) * width; | 176 me_plane = refdata + (filled + me_x) + (height - me_y) * width; |
177 for(j = 0; j < me_h; j++) { | 177 for(j = 0; j < me_h; j++) { |
178 for(i = 0; i < me_w; i++) | 178 for(i = 0; i < me_w; i++) |
179 dst[filled + i - (j * stride)] = me_plane[i - (j * width)]; | 179 dst[filled + i - (j * stride)] = me_plane[i - (j * width)]; |
180 } | 180 } |
181 } | 181 } |
182 } | 182 } |
183 code = *src++; | 183 code = *src++; |
184 size--; | 184 size--; |
185 } | 185 } |
186 } | 186 } |
187 | 187 |
188 if(code == 0xE0) /* end-of-picture code */ | 188 if(code == 0xE0) /* end-of-picture code */ |
189 break; | 189 break; |
190 if(code > 0xE0) { /* run code: 0xE1..0xFF */ | 190 if(code > 0xE0) { /* run code: 0xE1..0xFF */ |
191 int p; | 191 int p; |
192 | 192 |
193 code &= 0x1F; | 193 code &= 0x1F; |
194 p = *src++; | 194 p = *src++; |
195 size--; | 195 size--; |
196 for(i = 0; i <= code; i++) { | 196 for(i = 0; i <= code; i++) { |
197 dst[filled++] = p; | 197 dst[filled++] = p; |
198 if(filled >= width) { | 198 if(filled >= width) { |
199 filled = 0; | 199 filled = 0; |
200 dst -= stride; | 200 dst -= stride; |
201 height--; | 201 height--; |
202 } | 202 } |
203 } | 203 } |
204 } else if(code >= 0xC0) { /* copy code: 0xC0..0xDF */ | 204 } else if(code >= 0xC0) { /* copy code: 0xC0..0xDF */ |
205 code &= 0x1F; | 205 code &= 0x1F; |
206 | 206 |
207 for(i = 0; i <= code; i++) { | 207 for(i = 0; i <= code; i++) { |
208 dst[filled++] = *src++; | 208 dst[filled++] = *src++; |
209 if(filled >= width) { | 209 if(filled >= width) { |
210 filled = 0; | 210 filled = 0; |
211 dst -= stride; | 211 dst -= stride; |
212 height--; | 212 height--; |
213 } | 213 } |
214 } | 214 } |
215 size -= code + 1; | 215 size -= code + 1; |
216 } else if(code >= 0x80) { /* skip code: 0x80..0xBF */ | 216 } else if(code >= 0x80) { /* skip code: 0x80..0xBF */ |
217 int skip; | 217 int skip; |
218 | 218 |
219 code &= 0x3F; | 219 code &= 0x3F; |
220 /* codes 0x80 and 0x81 are actually escape codes, | 220 /* codes 0x80 and 0x81 are actually escape codes, |
221 skip value minus constant is in the next byte */ | 221 skip value minus constant is in the next byte */ |
222 if(!code) | 222 if(!code) |
223 skip = (*src++) + 64; | 223 skip = (*src++) + 64; |
224 else if(code == 1) | 224 else if(code == 1) |
225 skip = (*src++) + 320; | 225 skip = (*src++) + 320; |
226 else | 226 else |
227 skip = code; | 227 skip = code; |
228 filled += skip; | 228 filled += skip; |
229 while( filled >= width) { | 229 while( filled >= width) { |
230 filled -= width; | 230 filled -= width; |
231 dst -= stride; | 231 dst -= stride; |
232 height--; | 232 height--; |
233 if(height < 0) | 233 if(height < 0) |
234 break; | 234 break; |
235 } | 235 } |
236 } else { | 236 } else { |
237 /* zero code treated as one-pixel skip */ | 237 /* zero code treated as one-pixel skip */ |
238 if(code) | 238 if(code) |
239 dst[filled++] = ctable[code & 0x7F]; | 239 dst[filled++] = ctable[code & 0x7F]; |
240 else | 240 else |
241 filled++; | 241 filled++; |
242 if(filled >= width) { | 242 if(filled >= width) { |
243 filled = 0; | 243 filled = 0; |
244 dst -= stride; | 244 dst -= stride; |
245 height--; | 245 height--; |
246 } | 246 } |
247 } | 247 } |
248 } | 248 } |
249 } | 249 } |
250 | 250 |
251 static int decode_frame(AVCodecContext *avctx, | 251 static int decode_frame(AVCodecContext *avctx, |
252 void *data, int *data_size, | 252 void *data, int *data_size, |
265 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | 265 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); |
266 return -1; | 266 return -1; |
267 } | 267 } |
268 outdata = a->pic.data[0]; | 268 outdata = a->pic.data[0]; |
269 if(buf[0x85] == 0x10) { | 269 if(buf[0x85] == 0x10) { |
270 qpeg_decode_intra(buf+0x86, outdata, buf_size - 0x86, a->pic.linesize[0], avctx->width, avctx->height); | 270 qpeg_decode_intra(buf+0x86, outdata, buf_size - 0x86, a->pic.linesize[0], avctx->width, avctx->height); |
271 } else { | 271 } else { |
272 delta = buf[0x85]; | 272 delta = buf[0x85]; |
273 qpeg_decode_inter(buf+0x86, outdata, buf_size - 0x86, a->pic.linesize[0], avctx->width, avctx->height, delta, buf + 4, a->refdata); | 273 qpeg_decode_inter(buf+0x86, outdata, buf_size - 0x86, a->pic.linesize[0], avctx->width, avctx->height, delta, buf + 4, a->refdata); |
274 } | 274 } |
275 | 275 |
276 /* make the palette available on the way out */ | 276 /* make the palette available on the way out */ |
277 memcpy(a->pic.data[1], a->avctx->palctrl->palette, AVPALETTE_SIZE); | 277 memcpy(a->pic.data[1], a->avctx->palctrl->palette, AVPALETTE_SIZE); |
278 if (a->avctx->palctrl->palette_changed) { | 278 if (a->avctx->palctrl->palette_changed) { |