Mercurial > libavcodec.hg
comparison xan.c @ 1585:6b224ca24033 libavcodec
revised palette API, courtesy of Roberto Togni (rtogni at freemail.it)
author | melanson |
---|---|
date | Thu, 30 Oct 2003 05:40:58 +0000 |
parents | 72e115e94673 |
children | 932d306bf1dc |
comparison
equal
deleted
inserted
replaced
1584:3615999a7284 | 1585:6b224ca24033 |
---|---|
113 int i; | 113 int i; |
114 | 114 |
115 s->avctx = avctx; | 115 s->avctx = avctx; |
116 | 116 |
117 if ((avctx->codec->id == CODEC_ID_XAN_WC3) && | 117 if ((avctx->codec->id == CODEC_ID_XAN_WC3) && |
118 (s->avctx->extradata_size != sizeof(AVPaletteControl))) { | 118 (s->avctx->palctrl == NULL)) { |
119 printf (" WC3 Xan video: expected extradata_size of %d\n", | 119 printf (" WC3 Xan video: palette expected.\n"); |
120 sizeof(AVPaletteControl)); | |
121 return -1; | 120 return -1; |
122 } | 121 } |
123 | 122 |
124 avctx->pix_fmt = PIX_FMT_PAL8; | 123 avctx->pix_fmt = PIX_FMT_PAL8; |
125 avctx->has_b_frames = 0; | 124 avctx->has_b_frames = 0; |
251 size = opcode & 3; | 250 size = opcode & 3; |
252 bytecopy(dest, src, size); dest += size; src += size; | 251 bytecopy(dest, src, size); dest += size; src += size; |
253 } | 252 } |
254 | 253 |
255 static void inline xan_wc3_build_palette(XanContext *s, | 254 static void inline xan_wc3_build_palette(XanContext *s, |
256 unsigned char *palette_data) | 255 unsigned int *palette_data) |
257 { | 256 { |
258 int i; | 257 int i; |
259 unsigned char r, g, b; | 258 unsigned char r, g, b; |
260 unsigned short *palette16; | 259 unsigned short *palette16; |
261 unsigned int *palette32; | 260 unsigned int *palette32; |
261 unsigned int pal_elem; | |
262 | 262 |
263 /* transform the palette passed through the palette control structure | 263 /* transform the palette passed through the palette control structure |
264 * into the necessary internal format depending on colorspace */ | 264 * into the necessary internal format depending on colorspace */ |
265 | 265 |
266 switch (s->avctx->pix_fmt) { | 266 switch (s->avctx->pix_fmt) { |
267 | 267 |
268 case PIX_FMT_RGB555: | 268 case PIX_FMT_RGB555: |
269 palette16 = (unsigned short *)s->palette; | 269 palette16 = (unsigned short *)s->palette; |
270 for (i = 0; i < PALETTE_COUNT; i++) { | 270 for (i = 0; i < PALETTE_COUNT; i++) { |
271 r = *palette_data++; | 271 pal_elem = palette_data[i]; |
272 g = *palette_data++; | 272 r = (pal_elem >> 16) & 0xff; |
273 b = *palette_data++; | 273 g = (pal_elem >> 8) & 0xff; |
274 b = pal_elem & 0xff; | |
274 palette16[i] = | 275 palette16[i] = |
275 ((r >> 3) << 10) | | 276 ((r >> 3) << 10) | |
276 ((g >> 3) << 5) | | 277 ((g >> 3) << 5) | |
277 ((b >> 3) << 0); | 278 ((b >> 3) << 0); |
278 } | 279 } |
279 break; | 280 break; |
280 | 281 |
281 case PIX_FMT_RGB565: | 282 case PIX_FMT_RGB565: |
282 palette16 = (unsigned short *)s->palette; | 283 palette16 = (unsigned short *)s->palette; |
283 for (i = 0; i < PALETTE_COUNT; i++) { | 284 for (i = 0; i < PALETTE_COUNT; i++) { |
284 r = *palette_data++; | 285 pal_elem = palette_data[i]; |
285 g = *palette_data++; | 286 r = (pal_elem >> 16) & 0xff; |
286 b = *palette_data++; | 287 g = (pal_elem >> 8) & 0xff; |
288 b = pal_elem & 0xff; | |
287 palette16[i] = | 289 palette16[i] = |
288 ((r >> 3) << 11) | | 290 ((r >> 3) << 11) | |
289 ((g >> 2) << 5) | | 291 ((g >> 2) << 5) | |
290 ((b >> 3) << 0); | 292 ((b >> 3) << 0); |
291 } | 293 } |
292 break; | 294 break; |
293 | 295 |
294 case PIX_FMT_RGB24: | 296 case PIX_FMT_RGB24: |
295 for (i = 0; i < PALETTE_COUNT; i++) { | 297 for (i = 0; i < PALETTE_COUNT; i++) { |
296 s->palette[i * 4 + 0] = *palette_data++; | 298 pal_elem = palette_data[i]; |
297 s->palette[i * 4 + 1] = *palette_data++; | 299 r = (pal_elem >> 16) & 0xff; |
298 s->palette[i * 4 + 2] = *palette_data++; | 300 g = (pal_elem >> 8) & 0xff; |
301 b = pal_elem & 0xff; | |
302 s->palette[i * 4 + 0] = r; | |
303 s->palette[i * 4 + 1] = g; | |
304 s->palette[i * 4 + 2] = b; | |
299 } | 305 } |
300 break; | 306 break; |
301 | 307 |
302 case PIX_FMT_BGR24: | 308 case PIX_FMT_BGR24: |
303 for (i = 0; i < PALETTE_COUNT; i++) { | 309 for (i = 0; i < PALETTE_COUNT; i++) { |
304 r = *palette_data++; | 310 pal_elem = palette_data[i]; |
305 g = *palette_data++; | 311 r = (pal_elem >> 16) & 0xff; |
306 b = *palette_data++; | 312 g = (pal_elem >> 8) & 0xff; |
313 b = pal_elem & 0xff; | |
307 s->palette[i * 4 + 0] = b; | 314 s->palette[i * 4 + 0] = b; |
308 s->palette[i * 4 + 1] = g; | 315 s->palette[i * 4 + 1] = g; |
309 s->palette[i * 4 + 2] = r; | 316 s->palette[i * 4 + 2] = r; |
310 } | 317 } |
311 break; | 318 break; |
312 | 319 |
313 case PIX_FMT_PAL8: | 320 case PIX_FMT_PAL8: |
314 case PIX_FMT_RGBA32: | 321 case PIX_FMT_RGBA32: |
315 palette32 = (unsigned int *)s->palette; | 322 palette32 = (unsigned int *)s->palette; |
316 for (i = 0; i < PALETTE_COUNT; i++) { | 323 memcpy (palette32, palette_data, PALETTE_COUNT * sizeof(unsigned int)); |
317 r = *palette_data++; | |
318 g = *palette_data++; | |
319 b = *palette_data++; | |
320 palette32[i] = (r << 16) | (g << 8) | (b); | |
321 } | |
322 break; | 324 break; |
323 | 325 |
324 case PIX_FMT_YUV444P: | 326 case PIX_FMT_YUV444P: |
325 for (i = 0; i < PALETTE_COUNT; i++) { | 327 for (i = 0; i < PALETTE_COUNT; i++) { |
326 r = *palette_data++; | 328 pal_elem = palette_data[i]; |
327 g = *palette_data++; | 329 r = (pal_elem >> 16) & 0xff; |
328 b = *palette_data++; | 330 g = (pal_elem >> 8) & 0xff; |
331 b = pal_elem & 0xff; | |
329 s->palette[i * 4 + 0] = COMPUTE_Y(r, g, b); | 332 s->palette[i * 4 + 0] = COMPUTE_Y(r, g, b); |
330 s->palette[i * 4 + 1] = COMPUTE_U(r, g, b); | 333 s->palette[i * 4 + 1] = COMPUTE_U(r, g, b); |
331 s->palette[i * 4 + 2] = COMPUTE_V(r, g, b); | 334 s->palette[i * 4 + 2] = COMPUTE_V(r, g, b); |
332 } | 335 } |
333 break; | 336 break; |
728 } | 731 } |
729 } | 732 } |
730 } | 733 } |
731 | 734 |
732 /* for PAL8, make the palette available on the way out */ | 735 /* for PAL8, make the palette available on the way out */ |
733 if (s->avctx->pix_fmt == PIX_FMT_PAL8) | 736 if (s->avctx->pix_fmt == PIX_FMT_PAL8) { |
734 memcpy(s->current_frame.data[1], s->palette, PALETTE_COUNT * 4); | 737 memcpy(s->current_frame.data[1], s->palette, PALETTE_COUNT * 4); |
738 s->current_frame.palette_has_changed = 1; | |
739 s->avctx->palctrl->palette_changed = 0; | |
740 } | |
735 } | 741 } |
736 | 742 |
737 static void xan_wc4_decode_frame(XanContext *s) { | 743 static void xan_wc4_decode_frame(XanContext *s) { |
738 } | 744 } |
739 | 745 |
740 static int xan_decode_frame(AVCodecContext *avctx, | 746 static int xan_decode_frame(AVCodecContext *avctx, |
741 void *data, int *data_size, | 747 void *data, int *data_size, |
742 uint8_t *buf, int buf_size) | 748 uint8_t *buf, int buf_size) |
743 { | 749 { |
744 XanContext *s = avctx->priv_data; | 750 XanContext *s = avctx->priv_data; |
745 AVPaletteControl *palette_control = (AVPaletteControl *)avctx->extradata; | 751 AVPaletteControl *palette_control = avctx->palctrl; |
746 int keyframe = 0; | 752 int keyframe = 0; |
747 | 753 |
748 if (palette_control->palette_changed) { | 754 if (palette_control->palette_changed) { |
749 /* load the new palette and reset the palette control */ | 755 /* load the new palette and reset the palette control */ |
750 xan_wc3_build_palette(s, palette_control->palette); | 756 xan_wc3_build_palette(s, palette_control->palette); |
751 palette_control->palette_changed = 0; | 757 /* If pal8 we clear flag when we copy palette */ |
758 if (s->avctx->pix_fmt != PIX_FMT_PAL8) | |
759 palette_control->palette_changed = 0; | |
752 keyframe = 1; | 760 keyframe = 1; |
753 } | 761 } |
754 | 762 |
755 if (avctx->get_buffer(avctx, &s->current_frame)) { | 763 if (avctx->get_buffer(avctx, &s->current_frame)) { |
756 printf (" Xan Video: get_buffer() failed\n"); | 764 printf (" Xan Video: get_buffer() failed\n"); |