#include "libavutil/intreadwrite.h"
#include "libavutil/imgutils.h"
#include "avcodec.h"
+#include "bytestream.h"
#include "targa.h"
typedef struct TargaContext {
}
if(colors){
- size_t pal_size;
+ int pal_size, pal_sample_size;
if((colors + first_clr) > 256){
av_log(avctx, AV_LOG_ERROR, "Incorrect palette: %i colors with offset %i\n", colors, first_clr);
return -1;
}
- if(csize != 24){
+ switch (csize) {
+ case 24: pal_sample_size = 3; break;
+ case 16:
+ case 15: pal_sample_size = 2; break;
+ default:
av_log(avctx, AV_LOG_ERROR, "Palette entry size %i bits is not supported\n", csize);
return -1;
}
- pal_size = colors * ((csize + 1) >> 3);
+ pal_size = colors * pal_sample_size;
CHECK_BUFFER_SIZE(buf, buf_end, pal_size, "color table");
if(avctx->pix_fmt != PIX_FMT_PAL8)//should not occur but skip palette anyway
buf += pal_size;
else{
- int r, g, b, t;
- int32_t *pal = ((int32_t*)p->data[1]) + first_clr;
- for(t = 0; t < colors; t++){
- r = *buf++;
- g = *buf++;
- b = *buf++;
- *pal++ = (b << 16) | (g << 8) | r;
+ int t;
+ uint32_t *pal = ((uint32_t *)p->data[1]) + first_clr;
+
+ switch (pal_sample_size) {
+ case 3:
+ /* RGB24 */
+ for (t = 0; t < colors; t++)
+ *pal++ = bytestream_get_le24(&buf);
+ break;
+ case 2:
+ /* RGB555 */
+ for (t = 0; t < colors; t++) {
+ uint32_t v = bytestream_get_le16(&buf);
+ v = ((v & 0x7C00) << 9) |
+ ((v & 0x03E0) << 6) |
+ ((v & 0x001F) << 3);
+ /* left bit replication */
+ v |= (v & 0xE0E0E0U) >> 5;
+ *pal++ = v;
+ }
+ break;
}
p->palette_has_changed = 1;
}
}
AVCodec ff_targa_decoder = {
- "targa",
- AVMEDIA_TYPE_VIDEO,
- CODEC_ID_TARGA,
- sizeof(TargaContext),
- targa_init,
- NULL,
- targa_end,
- decode_frame,
- CODEC_CAP_DR1,
- NULL,
+ .name = "targa",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = CODEC_ID_TARGA,
+ .priv_data_size = sizeof(TargaContext),
+ .init = targa_init,
+ .close = targa_end,
+ .decode = decode_frame,
+ .capabilities = CODEC_CAP_DR1,
.long_name = NULL_IF_CONFIG_SMALL("Truevision Targa image"),
};