10712
|
1 /*
|
|
2 *
|
|
3 * QuickTime 8BPS decoder for Mplayer
|
|
4 * (c) 2003 Roberto Togni
|
|
5 *
|
|
6 * Fourcc: 8BPS
|
|
7 *
|
|
8 * Supports 8bpp (paletted), 24bpp and 32bpp (4th plane ignored)
|
|
9 *
|
|
10 */
|
|
11
|
|
12 #include <stdio.h>
|
|
13 #include <stdlib.h>
|
|
14
|
|
15 #include "config.h"
|
|
16 #include "bswap.h"
|
|
17
|
|
18 #include "mp_msg.h"
|
|
19
|
|
20 #include "vd_internal.h"
|
|
21
|
|
22
|
|
23 static vd_info_t info = {
|
|
24 "8BPS Video decoder",
|
|
25 "qt8bps",
|
|
26 "Roberto Togni",
|
|
27 "Roberto Togni",
|
|
28 "native codec"
|
|
29 };
|
|
30
|
|
31 LIBVD_EXTERN(qt8bps)
|
|
32
|
|
33
|
|
34 /*
|
|
35 * Decoder context
|
|
36 */
|
|
37 typedef struct {
|
|
38 unsigned char planes;
|
|
39 unsigned char planemap[4];
|
|
40 unsigned char *palette;
|
|
41 } qt8bps_context_t;
|
|
42
|
|
43
|
|
44 /*
|
|
45 * Internal function prototypes
|
|
46 */
|
|
47
|
|
48
|
|
49 // to set/get/query special features/parameters
|
|
50 static int control(sh_video_t *sh,int cmd,void* arg,...)
|
|
51 {
|
|
52 qt8bps_context_t *hc = (qt8bps_context_t *) sh->context; // Decoder context
|
|
53
|
|
54 if (cmd == VDCTRL_QUERY_FORMAT)
|
|
55 switch (hc->planes) {
|
|
56 case 1:
|
|
57 if (*((int*)arg) == IMGFMT_BGR8)
|
|
58 return CONTROL_TRUE;
|
|
59 else
|
|
60 return CONTROL_FALSE;
|
|
61 break;
|
|
62 case 3:
|
|
63 case 4:
|
|
64 if ((*((int*)arg) == IMGFMT_BGR24) || (*((int*)arg) == IMGFMT_BGR32))
|
|
65 return CONTROL_TRUE;
|
|
66 else
|
|
67 return CONTROL_FALSE;
|
|
68 break;
|
|
69 default:
|
|
70 return CONTROL_FALSE;
|
|
71 }
|
|
72
|
|
73 return CONTROL_UNKNOWN;
|
|
74 }
|
|
75
|
|
76
|
|
77 /*
|
|
78 *
|
|
79 * Init 8BPS decoder
|
|
80 *
|
|
81 */
|
|
82 static int init(sh_video_t *sh)
|
|
83 {
|
|
84 int vo_ret; // Video output init ret value
|
|
85 qt8bps_context_t *hc; // Decoder context
|
|
86 BITMAPINFOHEADER *bih = sh->bih;
|
|
87 int i;
|
|
88 unsigned char *psrc, *pdest;
|
|
89
|
|
90 if ((hc = malloc(sizeof(qt8bps_context_t))) == NULL) {
|
|
91 mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Can't allocate memory for 8BPS decoder context.\n");
|
|
92 return 0;
|
|
93 }
|
|
94
|
|
95 sh->context = (void *)hc;
|
|
96 hc->palette = NULL;
|
|
97
|
|
98 switch (bih->biBitCount) {
|
|
99 case 8:
|
|
100 hc->planes = 1;
|
|
101 hc->planemap[0] = 0; // 1st plane is palette indexes
|
|
102 if (bih->biSize > sizeof(BITMAPINFOHEADER)) {
|
|
103 psrc = (unsigned char*)bih + sizeof(BITMAPINFOHEADER);
|
|
104 pdest = hc->palette = (unsigned char *)malloc(256*3);
|
|
105 for (i = 0; i < 256; i++) {
|
|
106 *pdest++ = *psrc++;
|
|
107 *pdest++ = *psrc++;
|
|
108 *pdest++ = *psrc++;
|
|
109 psrc++;
|
|
110 }
|
|
111 }
|
|
112 break;
|
|
113 case 24:
|
|
114 hc->planes = 3;
|
|
115 hc->planemap[0] = 2; // 1st plane is red
|
|
116 hc->planemap[1] = 1; // 2nd plane is green
|
|
117 hc->planemap[2] = 0; // 3rd plane is blue
|
|
118 break;
|
|
119 case 32:
|
|
120 hc->planes = 4;
|
|
121 hc->planemap[0] = 2; // 1st plane is red
|
|
122 hc->planemap[1] = 1; // 2nd plane is green
|
|
123 hc->planemap[2] = 0; // 3rd plane is blue
|
|
124 hc->planemap[3] = 3; // 4th plane is alpha???
|
|
125 mp_msg(MSGT_DECVIDEO, MSGL_WARN, "[8BPS] Ignoring 4th (alpha?) plane.\n");
|
|
126 break;
|
|
127 default:
|
|
128 mp_msg(MSGT_DECVIDEO, MSGL_ERR, "[8BPS] Unsupported color depth: %u.\n", bih->biBitCount);
|
|
129 return 0;
|
|
130 }
|
|
131
|
|
132 /*
|
|
133 * Initialize video output device
|
|
134 */
|
|
135 vo_ret = mpcodecs_config_vo(sh,sh->disp_w,sh->disp_h,IMGFMT_BGR24);
|
|
136
|
|
137 return vo_ret;
|
|
138 }
|
|
139
|
|
140
|
|
141
|
|
142
|
|
143 /*
|
|
144 *
|
|
145 * Uninit 8BPS decoder
|
|
146 *
|
|
147 */
|
|
148 static void uninit(sh_video_t *sh)
|
|
149 {
|
|
150 qt8bps_context_t *hc = (qt8bps_context_t *) sh->context; // Decoder context
|
|
151
|
|
152 if (sh->context) {
|
|
153 if (hc->palette)
|
|
154 free (hc->palette);
|
|
155 free(sh->context);
|
|
156 }
|
|
157 }
|
|
158
|
|
159
|
|
160
|
|
161 /*
|
|
162 *
|
|
163 * Decode a frame
|
|
164 *
|
|
165 */
|
|
166 static mp_image_t* decode(sh_video_t *sh,void* data,int len,int flags)
|
|
167 {
|
|
168 mp_image_t* mpi;
|
|
169 unsigned char *encoded = (unsigned char *)data;
|
|
170 qt8bps_context_t *hc = (qt8bps_context_t *) sh->context; // Decoder context
|
|
171 unsigned char *outptr, *pixptr;
|
|
172 unsigned int height = sh->disp_h; // Real image height
|
|
173 unsigned int dlen, p, row;
|
|
174 unsigned char *lp, *dp;
|
|
175 unsigned char count;
|
|
176 unsigned int px_inc;
|
|
177 unsigned int planes = hc->planes;
|
|
178 unsigned char *planemap = hc->planemap;
|
|
179
|
|
180
|
|
181 // Skipped frame
|
|
182 if(len <= 0)
|
|
183 return NULL;
|
|
184
|
|
185 /* Get output image buffer */
|
|
186 mpi=mpcodecs_get_image(sh, MP_IMGTYPE_STATIC, MP_IMGFLAG_ACCEPT_STRIDE, sh->disp_w, sh->disp_h);
|
|
187 if (!mpi) {
|
|
188 mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Can't allocate mpi image for 8BPS codec.\n");
|
|
189 return NULL;
|
|
190 }
|
|
191
|
|
192 outptr = mpi->planes[0]; // Output image pointer
|
|
193 px_inc = mpi->bpp/8;
|
|
194
|
|
195 /* Set data pointer after line lengths */
|
|
196 dp = encoded + hc->planes*(height << 1);
|
|
197
|
|
198 /* Ignore alpha plane, don't know what to do with it */
|
|
199 if (planes == 4)
|
|
200 planes--;
|
|
201
|
|
202 for (p = 0; p < planes; p++) {
|
|
203 /* Lines length pointer for this plane */
|
|
204 lp = encoded + p*(height << 1);
|
|
205
|
|
206 /* Decode a plane */
|
|
207 for(row = 0; row < height; row++) {
|
|
208 pixptr = outptr + row * mpi->stride[0] + planemap[p];
|
|
209 dlen = be2me_16(*(unsigned short *)(lp+row*2));
|
|
210 /* Decode a row of this plane */
|
|
211 while(dlen > 0) {
|
|
212 if ((count = *dp++) <= 127) {
|
|
213 count++;
|
|
214 dlen -= count + 1;
|
|
215 while(count--) {
|
|
216 *pixptr = *dp++;
|
|
217 pixptr += px_inc;
|
|
218 }
|
|
219 } else {
|
|
220 count = 257 - count;
|
|
221 while(count--) {
|
|
222 *pixptr = *dp;
|
|
223 pixptr += px_inc;
|
|
224 }
|
|
225 dp++;
|
|
226 dlen -= 2;
|
|
227 }
|
|
228 }
|
|
229 }
|
|
230 }
|
|
231
|
|
232 if (hc->palette)
|
|
233 mpi->planes[1] = hc->palette;
|
|
234
|
|
235 return mpi;
|
|
236 }
|