Commit 2a2bbcb0 authored by Mike Melanson's avatar Mike Melanson

revised palette API, courtesy of Roberto Togni (rtogni at freemail.it)

Originally committed as revision 2451 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent 9df1d249
...@@ -453,7 +453,13 @@ typedef struct AVPanScan{ ...@@ -453,7 +453,13 @@ typedef struct AVPanScan{
* - decoding: set by lavc\ * - decoding: set by lavc\
*/\ */\
AVPanScan *pan_scan;\ AVPanScan *pan_scan;\
\
/**\
* tell user application that palette has changed from previous frame.\
* - encoding: ??? (no palette-enabled encoder yet)\
* - decoding: set by lavc (default 0)\
*/\
int palette_has_changed;\
#define FF_QSCALE_TYPE_MPEG1 0 #define FF_QSCALE_TYPE_MPEG1 0
#define FF_QSCALE_TYPE_MPEG2 1 #define FF_QSCALE_TYPE_MPEG2 1
...@@ -1345,6 +1351,13 @@ typedef struct AVCodecContext { ...@@ -1345,6 +1351,13 @@ typedef struct AVCodecContext {
* - decoding: unused * - decoding: unused
*/ */
int lmax; int lmax;
/**
* Palette control structure
* - encoding: ??? (no palette-enabled encoder yet)
* - decoding: set by user.
*/
struct AVPaletteControl *palctrl;
} AVCodecContext; } AVCodecContext;
...@@ -1426,17 +1439,18 @@ typedef struct AVPicture { ...@@ -1426,17 +1439,18 @@ typedef struct AVPicture {
* This structure defines a method for communicating palette changes * This structure defines a method for communicating palette changes
* between and demuxer and a decoder. * between and demuxer and a decoder.
*/ */
#define AVPALETTE_SIZE 256
typedef struct AVPaletteControl { typedef struct AVPaletteControl {
/* demuxer sets this to 1 to indicate the palette has changed; /* demuxer sets this to 1 to indicate the palette has changed;
* decoder resets to 0 */ * decoder resets to 0 */
int palette_changed; int palette_changed;
/* 256 3-byte RGB palette entries; the components should be /* 4-byte ARGB palette entries, stored in native byte order; note that
* formatted in the buffer as "RGBRGB..." and should be scaled to * the individual palette components should be on a 8-bit scale; if
* 8 bits if they originally represented 6-bit VGA palette * the palette data comes from a IBM VGA native format, the component
* components */ * data is probably 6 bits in size and needs to be scaled */
unsigned char palette[256 * 3]; unsigned int palette[AVPALETTE_SIZE];
} AVPaletteControl; } AVPaletteControl;
......
...@@ -72,8 +72,6 @@ typedef struct IdcinContext { ...@@ -72,8 +72,6 @@ typedef struct IdcinContext {
unsigned char *buf; unsigned char *buf;
int size; int size;
unsigned char palette[PALETTE_COUNT * 4];
hnode_t huff_nodes[256][HUF_TOKENS*2]; hnode_t huff_nodes[256][HUF_TOKENS*2];
int num_huff_nodes[256]; int num_huff_nodes[256];
...@@ -218,27 +216,11 @@ static int idcin_decode_frame(AVCodecContext *avctx, ...@@ -218,27 +216,11 @@ static int idcin_decode_frame(AVCodecContext *avctx,
uint8_t *buf, int buf_size) uint8_t *buf, int buf_size)
{ {
IdcinContext *s = (IdcinContext *)avctx->priv_data; IdcinContext *s = (IdcinContext *)avctx->priv_data;
AVPaletteControl *palette_control = AVPaletteControl *palette_control = avctx->palctrl;
(AVPaletteControl *)avctx->extradata;
int i;
unsigned int *palette32;
int palette_index = 0;
unsigned char r, g, b;
s->buf = buf; s->buf = buf;
s->size = buf_size; s->size = buf_size;
if (palette_control->palette_changed) {
palette32 = (unsigned int *)s->palette;
for (i = 0; i < PALETTE_COUNT; i++) {
r = palette_control->palette[palette_index++] * 1;
g = palette_control->palette[palette_index++] * 1;
b = palette_control->palette[palette_index++] * 1;
palette32[i] = (r << 16) | (g << 8) | (b);
}
palette_control->palette_changed = 0;
}
if (s->frame.data[0]) if (s->frame.data[0])
avctx->release_buffer(avctx, &s->frame); avctx->release_buffer(avctx, &s->frame);
...@@ -250,7 +232,12 @@ static int idcin_decode_frame(AVCodecContext *avctx, ...@@ -250,7 +232,12 @@ static int idcin_decode_frame(AVCodecContext *avctx,
idcin_decode_vlcs(s); idcin_decode_vlcs(s);
/* make the palette available on the way out */ /* make the palette available on the way out */
memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4); memcpy(s->frame.data[1], palette_control->palette, PALETTE_COUNT * 4);
/* If palette changed inform application*/
if (palette_control->palette_changed) {
palette_control->palette_changed = 0;
s->frame.palette_has_changed = 1;
}
*data_size = sizeof(AVFrame); *data_size = sizeof(AVFrame);
*(AVFrame*)data = s->frame; *(AVFrame*)data = s->frame;
......
...@@ -65,8 +65,6 @@ typedef struct IpvideoContext { ...@@ -65,8 +65,6 @@ typedef struct IpvideoContext {
unsigned char *buf; unsigned char *buf;
int size; int size;
unsigned char palette[PALETTE_COUNT * 4];
unsigned char *stream_ptr; unsigned char *stream_ptr;
unsigned char *stream_end; unsigned char *stream_end;
unsigned char *pixel_ptr; unsigned char *pixel_ptr;
...@@ -83,21 +81,6 @@ typedef struct IpvideoContext { ...@@ -83,21 +81,6 @@ typedef struct IpvideoContext {
return -1; \ return -1; \
} }
static void ipvideo_new_palette(IpvideoContext *s, unsigned char *palette) {
int i;
unsigned char r, g, b;
unsigned int *palette32;
palette32 = (unsigned int *)s->palette;
for (i = 0; i < PALETTE_COUNT; i++) {
r = *palette++;
g = *palette++;
b = *palette++;
palette32[i] = (r << 16) | (g << 8) | (b);
}
}
#define COPY_FROM_CURRENT() \ #define COPY_FROM_CURRENT() \
motion_offset = current_offset; \ motion_offset = current_offset; \
motion_offset += y * s->stride; \ motion_offset += y * s->stride; \
...@@ -828,7 +811,7 @@ static void ipvideo_decode_opcodes(IpvideoContext *s) ...@@ -828,7 +811,7 @@ static void ipvideo_decode_opcodes(IpvideoContext *s)
code_counts[x] = 0; code_counts[x] = 0;
/* this is PAL8, so make the palette available */ /* this is PAL8, so make the palette available */
memcpy(s->current_frame.data[1], s->palette, PALETTE_COUNT * 4); memcpy(s->current_frame.data[1], s->avctx->palctrl->palette, PALETTE_COUNT * 4);
s->stride = s->current_frame.linesize[0]; s->stride = s->current_frame.linesize[0];
s->stream_ptr = s->buf + 14; /* data starts 14 bytes in */ s->stream_ptr = s->buf + 14; /* data starts 14 bytes in */
...@@ -874,9 +857,8 @@ static int ipvideo_decode_init(AVCodecContext *avctx) ...@@ -874,9 +857,8 @@ static int ipvideo_decode_init(AVCodecContext *avctx)
s->avctx = avctx; s->avctx = avctx;
if (s->avctx->extradata_size != sizeof(AVPaletteControl)) { if (s->avctx->palctrl == NULL) {
printf (" Interplay video: expected extradata_size of %d\n", printf (" Interplay video: palette expected.\n");
(int)sizeof(AVPaletteControl));
return -1; return -1;
} }
...@@ -916,13 +898,7 @@ static int ipvideo_decode_frame(AVCodecContext *avctx, ...@@ -916,13 +898,7 @@ static int ipvideo_decode_frame(AVCodecContext *avctx,
uint8_t *buf, int buf_size) uint8_t *buf, int buf_size)
{ {
IpvideoContext *s = avctx->priv_data; IpvideoContext *s = avctx->priv_data;
AVPaletteControl *palette_control = (AVPaletteControl *)avctx->extradata; AVPaletteControl *palette_control = avctx->palctrl;
if (palette_control->palette_changed) {
/* load the new palette and reset the palette control */
ipvideo_new_palette(s, palette_control->palette);
palette_control->palette_changed = 0;
}
s->decoding_map = buf; s->decoding_map = buf;
s->buf = buf + s->decoding_map_size; s->buf = buf + s->decoding_map_size;
...@@ -936,6 +912,11 @@ static int ipvideo_decode_frame(AVCodecContext *avctx, ...@@ -936,6 +912,11 @@ static int ipvideo_decode_frame(AVCodecContext *avctx,
ipvideo_decode_opcodes(s); ipvideo_decode_opcodes(s);
if (palette_control->palette_changed) {
palette_control->palette_changed = 0;
s->current_frame.palette_has_changed = 1;
}
*data_size = sizeof(AVFrame); *data_size = sizeof(AVFrame);
*(AVFrame*)data = s->current_frame; *(AVFrame*)data = s->current_frame;
......
...@@ -318,6 +318,7 @@ void avcodec_get_context_defaults(AVCodecContext *s){ ...@@ -318,6 +318,7 @@ void avcodec_get_context_defaults(AVCodecContext *s){
s->intra_quant_bias= FF_DEFAULT_QUANT_BIAS; s->intra_quant_bias= FF_DEFAULT_QUANT_BIAS;
s->inter_quant_bias= FF_DEFAULT_QUANT_BIAS; s->inter_quant_bias= FF_DEFAULT_QUANT_BIAS;
s->palctrl = NULL;
} }
/** /**
......
...@@ -120,7 +120,7 @@ typedef struct VqaContext { ...@@ -120,7 +120,7 @@ typedef struct VqaContext {
unsigned char *buf; unsigned char *buf;
int size; int size;
unsigned char palette[PALETTE_COUNT * 4]; unsigned int palette[PALETTE_COUNT];
int width; /* width of a frame */ int width; /* width of a frame */
int height; /* height of a frame */ int height; /* height of a frame */
...@@ -311,7 +311,6 @@ static void vqa_decode_chunk(VqaContext *s) ...@@ -311,7 +311,6 @@ static void vqa_decode_chunk(VqaContext *s)
unsigned int index = 0; unsigned int index = 0;
int i; int i;
unsigned char r, g, b; unsigned char r, g, b;
unsigned int *palette32;
int index_shift; int index_shift;
int cbf0_chunk = -1; int cbf0_chunk = -1;
...@@ -407,13 +406,12 @@ static void vqa_decode_chunk(VqaContext *s) ...@@ -407,13 +406,12 @@ static void vqa_decode_chunk(VqaContext *s)
return; return;
} }
cpl0_chunk += CHUNK_PREAMBLE_SIZE; cpl0_chunk += CHUNK_PREAMBLE_SIZE;
palette32 = (unsigned int *)s->palette;
for (i = 0; i < chunk_size / 3; i++) { for (i = 0; i < chunk_size / 3; i++) {
/* scale by 4 to transform 6-bit palette -> 8-bit */ /* scale by 4 to transform 6-bit palette -> 8-bit */
r = s->buf[cpl0_chunk++] * 4; r = s->buf[cpl0_chunk++] * 4;
g = s->buf[cpl0_chunk++] * 4; g = s->buf[cpl0_chunk++] * 4;
b = s->buf[cpl0_chunk++] * 4; b = s->buf[cpl0_chunk++] * 4;
palette32[i] = (r << 16) | (g << 8) | (b); s->palette[i] = (r << 16) | (g << 8) | (b);
} }
} }
...@@ -583,6 +581,7 @@ static int vqa_decode_frame(AVCodecContext *avctx, ...@@ -583,6 +581,7 @@ static int vqa_decode_frame(AVCodecContext *avctx,
/* make the palette available on the way out */ /* make the palette available on the way out */
memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4); memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4);
s->frame.palette_has_changed = 1;
*data_size = sizeof(AVFrame); *data_size = sizeof(AVFrame);
*(AVFrame*)data = s->frame; *(AVFrame*)data = s->frame;
......
...@@ -115,9 +115,8 @@ static int xan_decode_init(AVCodecContext *avctx) ...@@ -115,9 +115,8 @@ static int xan_decode_init(AVCodecContext *avctx)
s->avctx = avctx; s->avctx = avctx;
if ((avctx->codec->id == CODEC_ID_XAN_WC3) && if ((avctx->codec->id == CODEC_ID_XAN_WC3) &&
(s->avctx->extradata_size != sizeof(AVPaletteControl))) { (s->avctx->palctrl == NULL)) {
printf (" WC3 Xan video: expected extradata_size of %d\n", printf (" WC3 Xan video: palette expected.\n");
sizeof(AVPaletteControl));
return -1; return -1;
} }
...@@ -253,12 +252,13 @@ static void xan_unpack(unsigned char *dest, unsigned char *src) ...@@ -253,12 +252,13 @@ static void xan_unpack(unsigned char *dest, unsigned char *src)
} }
static void inline xan_wc3_build_palette(XanContext *s, static void inline xan_wc3_build_palette(XanContext *s,
unsigned char *palette_data) unsigned int *palette_data)
{ {
int i; int i;
unsigned char r, g, b; unsigned char r, g, b;
unsigned short *palette16; unsigned short *palette16;
unsigned int *palette32; unsigned int *palette32;
unsigned int pal_elem;
/* transform the palette passed through the palette control structure /* transform the palette passed through the palette control structure
* into the necessary internal format depending on colorspace */ * into the necessary internal format depending on colorspace */
...@@ -268,9 +268,10 @@ static void inline xan_wc3_build_palette(XanContext *s, ...@@ -268,9 +268,10 @@ static void inline xan_wc3_build_palette(XanContext *s,
case PIX_FMT_RGB555: case PIX_FMT_RGB555:
palette16 = (unsigned short *)s->palette; palette16 = (unsigned short *)s->palette;
for (i = 0; i < PALETTE_COUNT; i++) { for (i = 0; i < PALETTE_COUNT; i++) {
r = *palette_data++; pal_elem = palette_data[i];
g = *palette_data++; r = (pal_elem >> 16) & 0xff;
b = *palette_data++; g = (pal_elem >> 8) & 0xff;
b = pal_elem & 0xff;
palette16[i] = palette16[i] =
((r >> 3) << 10) | ((r >> 3) << 10) |
((g >> 3) << 5) | ((g >> 3) << 5) |
...@@ -281,9 +282,10 @@ static void inline xan_wc3_build_palette(XanContext *s, ...@@ -281,9 +282,10 @@ static void inline xan_wc3_build_palette(XanContext *s,
case PIX_FMT_RGB565: case PIX_FMT_RGB565:
palette16 = (unsigned short *)s->palette; palette16 = (unsigned short *)s->palette;
for (i = 0; i < PALETTE_COUNT; i++) { for (i = 0; i < PALETTE_COUNT; i++) {
r = *palette_data++; pal_elem = palette_data[i];
g = *palette_data++; r = (pal_elem >> 16) & 0xff;
b = *palette_data++; g = (pal_elem >> 8) & 0xff;
b = pal_elem & 0xff;
palette16[i] = palette16[i] =
((r >> 3) << 11) | ((r >> 3) << 11) |
((g >> 2) << 5) | ((g >> 2) << 5) |
...@@ -293,17 +295,22 @@ static void inline xan_wc3_build_palette(XanContext *s, ...@@ -293,17 +295,22 @@ static void inline xan_wc3_build_palette(XanContext *s,
case PIX_FMT_RGB24: case PIX_FMT_RGB24:
for (i = 0; i < PALETTE_COUNT; i++) { for (i = 0; i < PALETTE_COUNT; i++) {
s->palette[i * 4 + 0] = *palette_data++; pal_elem = palette_data[i];
s->palette[i * 4 + 1] = *palette_data++; r = (pal_elem >> 16) & 0xff;
s->palette[i * 4 + 2] = *palette_data++; g = (pal_elem >> 8) & 0xff;
b = pal_elem & 0xff;
s->palette[i * 4 + 0] = r;
s->palette[i * 4 + 1] = g;
s->palette[i * 4 + 2] = b;
} }
break; break;
case PIX_FMT_BGR24: case PIX_FMT_BGR24:
for (i = 0; i < PALETTE_COUNT; i++) { for (i = 0; i < PALETTE_COUNT; i++) {
r = *palette_data++; pal_elem = palette_data[i];
g = *palette_data++; r = (pal_elem >> 16) & 0xff;
b = *palette_data++; g = (pal_elem >> 8) & 0xff;
b = pal_elem & 0xff;
s->palette[i * 4 + 0] = b; s->palette[i * 4 + 0] = b;
s->palette[i * 4 + 1] = g; s->palette[i * 4 + 1] = g;
s->palette[i * 4 + 2] = r; s->palette[i * 4 + 2] = r;
...@@ -313,19 +320,15 @@ static void inline xan_wc3_build_palette(XanContext *s, ...@@ -313,19 +320,15 @@ static void inline xan_wc3_build_palette(XanContext *s,
case PIX_FMT_PAL8: case PIX_FMT_PAL8:
case PIX_FMT_RGBA32: case PIX_FMT_RGBA32:
palette32 = (unsigned int *)s->palette; palette32 = (unsigned int *)s->palette;
for (i = 0; i < PALETTE_COUNT; i++) { memcpy (palette32, palette_data, PALETTE_COUNT * sizeof(unsigned int));
r = *palette_data++;
g = *palette_data++;
b = *palette_data++;
palette32[i] = (r << 16) | (g << 8) | (b);
}
break; break;
case PIX_FMT_YUV444P: case PIX_FMT_YUV444P:
for (i = 0; i < PALETTE_COUNT; i++) { for (i = 0; i < PALETTE_COUNT; i++) {
r = *palette_data++; pal_elem = palette_data[i];
g = *palette_data++; r = (pal_elem >> 16) & 0xff;
b = *palette_data++; g = (pal_elem >> 8) & 0xff;
b = pal_elem & 0xff;
s->palette[i * 4 + 0] = COMPUTE_Y(r, g, b); s->palette[i * 4 + 0] = COMPUTE_Y(r, g, b);
s->palette[i * 4 + 1] = COMPUTE_U(r, g, b); s->palette[i * 4 + 1] = COMPUTE_U(r, g, b);
s->palette[i * 4 + 2] = COMPUTE_V(r, g, b); s->palette[i * 4 + 2] = COMPUTE_V(r, g, b);
...@@ -730,8 +733,11 @@ static void xan_wc3_decode_frame(XanContext *s) { ...@@ -730,8 +733,11 @@ static void xan_wc3_decode_frame(XanContext *s) {
} }
/* for PAL8, make the palette available on the way out */ /* for PAL8, make the palette available on the way out */
if (s->avctx->pix_fmt == PIX_FMT_PAL8) if (s->avctx->pix_fmt == PIX_FMT_PAL8) {
memcpy(s->current_frame.data[1], s->palette, PALETTE_COUNT * 4); memcpy(s->current_frame.data[1], s->palette, PALETTE_COUNT * 4);
s->current_frame.palette_has_changed = 1;
s->avctx->palctrl->palette_changed = 0;
}
} }
static void xan_wc4_decode_frame(XanContext *s) { static void xan_wc4_decode_frame(XanContext *s) {
...@@ -742,13 +748,15 @@ static int xan_decode_frame(AVCodecContext *avctx, ...@@ -742,13 +748,15 @@ static int xan_decode_frame(AVCodecContext *avctx,
uint8_t *buf, int buf_size) uint8_t *buf, int buf_size)
{ {
XanContext *s = avctx->priv_data; XanContext *s = avctx->priv_data;
AVPaletteControl *palette_control = (AVPaletteControl *)avctx->extradata; AVPaletteControl *palette_control = avctx->palctrl;
int keyframe = 0; int keyframe = 0;
if (palette_control->palette_changed) { if (palette_control->palette_changed) {
/* load the new palette and reset the palette control */ /* load the new palette and reset the palette control */
xan_wc3_build_palette(s, palette_control->palette); xan_wc3_build_palette(s, palette_control->palette);
palette_control->palette_changed = 0; /* If pal8 we clear flag when we copy palette */
if (s->avctx->pix_fmt != PIX_FMT_PAL8)
palette_control->palette_changed = 0;
keyframe = 1; keyframe = 1;
} }
......
...@@ -90,8 +90,7 @@ typedef struct IdcinDemuxContext { ...@@ -90,8 +90,7 @@ typedef struct IdcinDemuxContext {
int64_t pts; int64_t pts;
/* keep reference to extradata but never free it */ AVPaletteControl palctrl;
void *extradata;
} IdcinDemuxContext; } IdcinDemuxContext;
static int idcin_probe(AVProbeData *p) static int idcin_probe(AVProbeData *p)
...@@ -175,7 +174,7 @@ static int idcin_read_header(AVFormatContext *s, ...@@ -175,7 +174,7 @@ static int idcin_read_header(AVFormatContext *s,
HUFFMAN_TABLE_SIZE) HUFFMAN_TABLE_SIZE)
return -EIO; return -EIO;
/* save a reference in order to transport the palette */ /* save a reference in order to transport the palette */
idcin->extradata = st->codec.extradata; st->codec.palctrl = &idcin->palctrl;
/* if sample rate is 0, assume no audio */ /* if sample rate is 0, assume no audio */
if (sample_rate) { if (sample_rate) {
...@@ -227,9 +226,10 @@ static int idcin_read_packet(AVFormatContext *s, ...@@ -227,9 +226,10 @@ static int idcin_read_packet(AVFormatContext *s,
unsigned int chunk_size; unsigned int chunk_size;
IdcinDemuxContext *idcin = (IdcinDemuxContext *)s->priv_data; IdcinDemuxContext *idcin = (IdcinDemuxContext *)s->priv_data;
ByteIOContext *pb = &s->pb; ByteIOContext *pb = &s->pb;
AVPaletteControl *palette_control = (AVPaletteControl *)idcin->extradata;
int i; int i;
int palette_scale; int palette_scale;
unsigned char r, g, b;
unsigned char palette_buffer[768];
if (url_feof(&s->pb)) if (url_feof(&s->pb))
return -EIO; return -EIO;
...@@ -240,20 +240,23 @@ static int idcin_read_packet(AVFormatContext *s, ...@@ -240,20 +240,23 @@ static int idcin_read_packet(AVFormatContext *s,
return -EIO; return -EIO;
} else if (command == 1) { } else if (command == 1) {
/* trigger a palette change */ /* trigger a palette change */
palette_control->palette_changed = 1; idcin->palctrl.palette_changed = 1;
if (get_buffer(pb, palette_control->palette, 768) != 768) if (get_buffer(pb, palette_buffer, 768) != 768)
return -EIO; return -EIO;
/* scale the palette as necessary */ /* scale the palette as necessary */
palette_scale = 2; palette_scale = 2;
for (i = 0; i < 768; i++) for (i = 0; i < 768; i++)
if (palette_control->palette[i] > 63) { if (palette_buffer[i] > 63) {
palette_scale = 0; palette_scale = 0;
break; break;
} }
if (palette_scale) for (i = 0; i < 256; i++) {
for (i = 0; i < 768; i++) r = palette_buffer[i * 3 ] << palette_scale;
palette_control->palette[i] <<= palette_scale; g = palette_buffer[i * 3 + 1] << palette_scale;
b = palette_buffer[i * 3 + 2] << palette_scale;
idcin->palctrl.palette[i] = (r << 16) | (g << 8) | (b);
}
} }
chunk_size = get_le32(pb); chunk_size = get_le32(pb);
...@@ -293,6 +296,7 @@ static int idcin_read_packet(AVFormatContext *s, ...@@ -293,6 +296,7 @@ static int idcin_read_packet(AVFormatContext *s,
static int idcin_read_close(AVFormatContext *s) static int idcin_read_close(AVFormatContext *s)
{ {
return 0; return 0;
} }
......
...@@ -232,6 +232,7 @@ static int process_ipmovie_chunk(IPMVEContext *s, ByteIOContext *pb, ...@@ -232,6 +232,7 @@ static int process_ipmovie_chunk(IPMVEContext *s, ByteIOContext *pb,
int i, j; int i, j;
int first_color, last_color; int first_color, last_color;
int audio_flags; int audio_flags;
unsigned char r, g, b;
/* see if there are any pending packets */ /* see if there are any pending packets */
chunk_type = load_ipmovie_packet(s, pb, pkt); chunk_type = load_ipmovie_packet(s, pb, pkt);
...@@ -463,9 +464,10 @@ static int process_ipmovie_chunk(IPMVEContext *s, ByteIOContext *pb, ...@@ -463,9 +464,10 @@ static int process_ipmovie_chunk(IPMVEContext *s, ByteIOContext *pb,
for (i = first_color; i <= last_color; i++) { for (i = first_color; i <= last_color; i++) {
/* the palette is stored as a 6-bit VGA palette, thus each /* the palette is stored as a 6-bit VGA palette, thus each
* component is shifted up to a 8-bit range */ * component is shifted up to a 8-bit range */
s->palette_control.palette[i * 3 + 0] = scratch[j++] * 4; r = scratch[j++] * 4;
s->palette_control.palette[i * 3 + 1] = scratch[j++] * 4; g = scratch[j++] * 4;
s->palette_control.palette[i * 3 + 2] = scratch[j++] * 4; b = scratch[j++] * 4;
s->palette_control.palette[i] = (r << 16) | (g << 8) | (b);
} }
/* indicate a palette change */ /* indicate a palette change */
s->palette_control.palette_changed = 1; s->palette_control.palette_changed = 1;
...@@ -573,8 +575,7 @@ static int ipmovie_read_header(AVFormatContext *s, ...@@ -573,8 +575,7 @@ static int ipmovie_read_header(AVFormatContext *s,
st->codec.height = ipmovie->video_height; st->codec.height = ipmovie->video_height;
/* palette considerations */ /* palette considerations */
st->codec.extradata_size = sizeof(AVPaletteControl); st->codec.palctrl = &ipmovie->palette_control;
st->codec.extradata = &ipmovie->palette_control;
if (ipmovie->audio_type) { if (ipmovie->audio_type) {
st = av_new_stream(s, 0); st = av_new_stream(s, 0);
......
...@@ -258,8 +258,7 @@ static int wc3_read_header(AVFormatContext *s, ...@@ -258,8 +258,7 @@ static int wc3_read_header(AVFormatContext *s,
st->codec.height = wc3->height; st->codec.height = wc3->height;
/* palette considerations */ /* palette considerations */
st->codec.extradata_size = sizeof(AVPaletteControl); st->codec.palctrl = &wc3->palette_control;
st->codec.extradata = &wc3->palette_control;
st = av_new_stream(s, 0); st = av_new_stream(s, 0);
if (!st) if (!st)
...@@ -294,6 +293,9 @@ static int wc3_read_packet(AVFormatContext *s, ...@@ -294,6 +293,9 @@ static int wc3_read_packet(AVFormatContext *s,
unsigned char preamble[WC3_PREAMBLE_SIZE]; unsigned char preamble[WC3_PREAMBLE_SIZE];
unsigned char text[1024]; unsigned char text[1024];
unsigned int palette_number; unsigned int palette_number;
int i;
unsigned char r, g, b;
int base_palette_index;
while (!packet_read) { while (!packet_read) {
...@@ -319,9 +321,13 @@ static int wc3_read_packet(AVFormatContext *s, ...@@ -319,9 +321,13 @@ static int wc3_read_packet(AVFormatContext *s,
palette_number = LE_32(&preamble[0]); palette_number = LE_32(&preamble[0]);
if (palette_number >= wc3->palette_count) if (palette_number >= wc3->palette_count)
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
memcpy(wc3->palette_control.palette, base_palette_index = palette_number * PALETTE_COUNT * 3;
&wc3->palettes[palette_number * PALETTE_COUNT * 3], for (i = 0; i < PALETTE_COUNT; i++) {
PALETTE_COUNT * 3); r = wc3->palettes[base_palette_index + i * 3 + 0];
g = wc3->palettes[base_palette_index + i * 3 + 1];
b = wc3->palettes[base_palette_index + i * 3 + 2];
wc3->palette_control.palette[i] = (r << 16) | (g << 8) | (b);
}
wc3->palette_control.palette_changed = 1; wc3->palette_control.palette_changed = 1;
break; break;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment