Mercurial > libavcodec.hg
comparison qdrw.c @ 4787:94301f9f53f7 libavcodec
This codec is PAL8 so make it output PAL8 too
author | kostya |
---|---|
date | Fri, 06 Apr 2007 04:40:13 +0000 |
parents | 05e932ddaaa9 |
children | 2b72f9bc4f06 |
comparison
equal
deleted
inserted
replaced
4786:95f58f0b70fc | 4787:94301f9f53f7 |
---|---|
29 #include "mpegvideo.h" | 29 #include "mpegvideo.h" |
30 | 30 |
31 typedef struct QdrawContext{ | 31 typedef struct QdrawContext{ |
32 AVCodecContext *avctx; | 32 AVCodecContext *avctx; |
33 AVFrame pic; | 33 AVFrame pic; |
34 uint8_t palette[256*3]; | |
35 } QdrawContext; | 34 } QdrawContext; |
36 | 35 |
37 static int decode_frame(AVCodecContext *avctx, | 36 static int decode_frame(AVCodecContext *avctx, |
38 void *data, int *data_size, | 37 void *data, int *data_size, |
39 uint8_t *buf, int buf_size) | 38 uint8_t *buf, int buf_size) |
41 QdrawContext * const a = avctx->priv_data; | 40 QdrawContext * const a = avctx->priv_data; |
42 AVFrame * const p= (AVFrame*)&a->pic; | 41 AVFrame * const p= (AVFrame*)&a->pic; |
43 uint8_t* outdata; | 42 uint8_t* outdata; |
44 int colors; | 43 int colors; |
45 int i; | 44 int i; |
45 uint32_t *pal; | |
46 int r, g, b; | |
46 | 47 |
47 if(p->data[0]) | 48 if(p->data[0]) |
48 avctx->release_buffer(avctx, p); | 49 avctx->release_buffer(avctx, p); |
49 | 50 |
50 p->reference= 0; | 51 p->reference= 0; |
64 if(colors < 0 || colors > 256) { | 65 if(colors < 0 || colors > 256) { |
65 av_log(avctx, AV_LOG_ERROR, "Error color count - %i(0x%X)\n", colors, colors); | 66 av_log(avctx, AV_LOG_ERROR, "Error color count - %i(0x%X)\n", colors, colors); |
66 return -1; | 67 return -1; |
67 } | 68 } |
68 | 69 |
70 pal = (uint32_t*)p->data[1]; | |
69 for (i = 0; i <= colors; i++) { | 71 for (i = 0; i <= colors; i++) { |
70 unsigned int idx; | 72 unsigned int idx; |
71 idx = AV_RB16(buf); /* color index */ | 73 idx = AV_RB16(buf); /* color index */ |
72 buf += 2; | 74 buf += 2; |
73 | 75 |
74 if (idx > 255) { | 76 if (idx > 255) { |
75 av_log(avctx, AV_LOG_ERROR, "Palette index out of range: %u\n", idx); | 77 av_log(avctx, AV_LOG_ERROR, "Palette index out of range: %u\n", idx); |
76 buf += 6; | 78 buf += 6; |
77 continue; | 79 continue; |
78 } | 80 } |
79 a->palette[idx * 3 + 0] = *buf++; | 81 r = *buf++; |
80 buf++; | 82 buf++; |
81 a->palette[idx * 3 + 1] = *buf++; | 83 g = *buf++; |
82 buf++; | 84 buf++; |
83 a->palette[idx * 3 + 2] = *buf++; | 85 b = *buf++; |
84 buf++; | 86 buf++; |
87 pal[idx] = (r << 16) | (g << 8) | b; | |
85 } | 88 } |
89 p->palette_has_changed = 1; | |
86 | 90 |
87 buf += 18; /* skip unneeded data */ | 91 buf += 18; /* skip unneeded data */ |
88 for (i = 0; i < avctx->height; i++) { | 92 for (i = 0; i < avctx->height; i++) { |
89 int size, left, code, pix; | 93 int size, left, code, pix; |
90 uint8_t *next; | 94 uint8_t *next; |
98 left = size; | 102 left = size; |
99 next = buf + size; | 103 next = buf + size; |
100 while (left > 0) { | 104 while (left > 0) { |
101 code = *buf++; | 105 code = *buf++; |
102 if (code & 0x80 ) { /* run */ | 106 if (code & 0x80 ) { /* run */ |
103 int i; | |
104 pix = *buf++; | 107 pix = *buf++; |
105 if ((out + (257 - code) * 3) > (outdata + a->pic.linesize[0])) | 108 if ((out + (257 - code)) > (outdata + a->pic.linesize[0])) |
106 break; | 109 break; |
107 for (i = 0; i < 257 - code; i++) { | 110 memset(out, pix, 257 - code); |
108 *out++ = a->palette[pix * 3 + 0]; | 111 out += 257 - code; |
109 *out++ = a->palette[pix * 3 + 1]; | |
110 *out++ = a->palette[pix * 3 + 2]; | |
111 } | |
112 tsize += 257 - code; | 112 tsize += 257 - code; |
113 left -= 2; | 113 left -= 2; |
114 } else { /* copy */ | 114 } else { /* copy */ |
115 int i, pix; | 115 if ((out + code) > (outdata + a->pic.linesize[0])) |
116 if ((out + code * 3) > (outdata + a->pic.linesize[0])) | |
117 break; | 116 break; |
118 for (i = 0; i <= code; i++) { | 117 memcpy(out, buf, code + 1); |
119 pix = *buf++; | 118 out += code + 1; |
120 *out++ = a->palette[pix * 3 + 0]; | 119 buf += code + 1; |
121 *out++ = a->palette[pix * 3 + 1]; | |
122 *out++ = a->palette[pix * 3 + 2]; | |
123 } | |
124 left -= 2 + code; | 120 left -= 2 + code; |
125 tsize += code + 1; | 121 tsize += code + 1; |
126 } | 122 } |
127 } | 123 } |
128 buf = next; | 124 buf = next; |
140 | 136 |
141 if (avcodec_check_dimensions(avctx, avctx->width, avctx->height) < 0) { | 137 if (avcodec_check_dimensions(avctx, avctx->width, avctx->height) < 0) { |
142 return 1; | 138 return 1; |
143 } | 139 } |
144 | 140 |
145 avctx->pix_fmt= PIX_FMT_RGB24; | 141 avctx->pix_fmt= PIX_FMT_PAL8; |
146 | 142 |
147 return 0; | 143 return 0; |
148 } | 144 } |
149 | 145 |
150 AVCodec qdraw_decoder = { | 146 AVCodec qdraw_decoder = { |