Mercurial > mplayer.hg
annotate libmpcodecs/vd_mtga.c @ 25210:92204ff32b27
When IFO file is opened (detected by extension), set dvd-device to IFO file's
directory and start dvd:// stream instead of file://.
If VTS_<N>_*.IFO is opened, open stream as dvd://<N>
As Nico Sabbi said:
There is no no guarantie that title N is in titleset N,
but there are at least good chances.
The main purpose of this patch is ability to load DVDs, stored on HDD,
using OSD menu.
Modified patch from Benjamin Zores ben at geexbox dot org
author | voroshil |
---|---|
date | Sun, 02 Dec 2007 13:13:02 +0000 |
parents | 2c09fe135c93 |
children | b21e1506e50b |
rev | line source |
---|---|
7362 | 1 /* author: Tilman Sauerbeck <tsauerbeck@users.sourceforge.net> |
2 * based on: XreaL's x_r_img_tga.* (http://www.sourceforge.net/projects/xreal/) | |
3 * libtarga.* | |
4 * xli's tga.* | |
5 */ | |
6 | |
7 #include <stdio.h> | |
8 #include <stdlib.h> | |
23305
22d3d12c6dfb
Include string.h for memcpy, fastmemcpy.h alone is not enough.
reimar
parents:
21507
diff
changeset
|
9 #include <string.h> |
7362 | 10 |
11 #include "config.h" | |
12 #include "mp_msg.h" | |
13 | |
21372 | 14 #include "libavutil/common.h" |
21507
fa99b3d31d13
Hack around libavutil/bswap.h compilation problems due to always_inline undefined.
reimar
parents:
21372
diff
changeset
|
15 #include "mpbswap.h" |
7362 | 16 #include "libvo/fastmemcpy.h" |
17 | |
18 #include "vd_internal.h" | |
19 | |
20 static vd_info_t info = | |
21 { | |
22 "TGA Images decoder", | |
23 "mtga", | |
7401 | 24 "Tilman Sauerbeck, A'rpi", |
7362 | 25 "Tilman Sauerbeck", |
26 "only 24bpp and 32bpp RGB targa files support so far" | |
27 }; | |
28 | |
29 LIBVD_EXTERN(mtga) | |
30 | |
31 typedef enum | |
32 { | |
33 TGA_NO_DATA, | |
34 TGA_UNCOMP_PALETTED, | |
35 TGA_UNCOMP_TRUECOLOR, | |
36 TGA_UNCOMP_GRAYSCALE, | |
37 TGA_RLE_PALETTED = 9, | |
38 TGA_RLE_TRUECOLOR, | |
39 TGA_RLE_GRAYSCALE | |
40 } TGAImageType; | |
41 | |
42 typedef struct | |
43 { | |
44 unsigned char id_len; | |
45 unsigned short img_type; | |
46 | |
47 unsigned short width; | |
48 unsigned short height; | |
49 | |
50 unsigned char bpp; | |
51 unsigned char origin; /* 0 = lower left, 1 = upper left */ | |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
52 unsigned short start_row; |
9605 | 53 short increment; |
7362 | 54 } TGAInfo; |
55 | |
56 static unsigned int out_fmt = 0; | |
57 | |
58 static int last_w = -1; | |
59 static int last_h = -1; | |
60 static int last_c = -1; | |
61 | |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
62 |
7362 | 63 /* to set/get/query special features/parameters */ |
64 static int control(sh_video_t *sh, int cmd, void *arg, ...) | |
65 { | |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
66 switch (cmd) |
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
67 { |
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
68 case VDCTRL_QUERY_FORMAT: |
7401 | 69 if (*((int *) arg) == out_fmt) return CONTROL_TRUE; |
70 return CONTROL_FALSE; | |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
71 } |
7401 | 72 return CONTROL_UNKNOWN; |
7362 | 73 } |
74 | |
75 /* init driver */ | |
76 static int init(sh_video_t *sh) | |
77 { | |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
78 sh->context = (TGAInfo *) calloc(1, sizeof(TGAInfo)); |
7362 | 79 last_w = -1; |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
80 |
7362 | 81 return 1; |
82 } | |
83 | |
84 | |
85 /* uninit driver */ | |
86 static void uninit(sh_video_t *sh) | |
87 { | |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
88 TGAInfo *info = sh->context; |
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
89 free(info); |
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
90 return; |
7362 | 91 } |
92 | |
93 | |
94 /* decode a runlength-encoded tga */ | |
7401 | 95 static void decode_rle_tga(TGAInfo *info, unsigned char *data, mp_image_t *mpi) |
7362 | 96 { |
7401 | 97 int row, col, replen, i, num_bytes = info->bpp / 8; |
7362 | 98 unsigned char repetitions, packet_header, *final; |
99 | |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
100 /* see line 207 to see why this loop is set up like this */ |
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
101 for (row = info->start_row; (!info->origin && row) || (info->origin && row < info->height); row += info->increment) |
7362 | 102 { |
7401 | 103 final = mpi->planes[0] + mpi->stride[0] * row; |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
104 |
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
105 for (col = 0; col < info->width; col += repetitions) |
7362 | 106 { |
107 packet_header = *data++; | |
7401 | 108 repetitions = (1 + (packet_header & 0x7f)); |
109 replen = repetitions * num_bytes; | |
7362 | 110 |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
111 if (packet_header & 0x80) /* runlength encoded packet */ |
7362 | 112 { |
23458
973e53dc7df5
Do not use fast_memcpy for small size copy, esp. when the size is constant
reimar
parents:
23457
diff
changeset
|
113 memcpy(final, data, num_bytes); |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
114 |
7401 | 115 // Note: this will be slow when DR to vram! |
116 i=num_bytes; | |
117 while(2*i<=replen){ | |
23459
2c09fe135c93
Do not use fast_memcpy when data is read again immediately afterwards.
reimar
parents:
23458
diff
changeset
|
118 memcpy(final+i,final,i); |
7401 | 119 i*=2; |
120 } | |
23459
2c09fe135c93
Do not use fast_memcpy when data is read again immediately afterwards.
reimar
parents:
23458
diff
changeset
|
121 memcpy(final+i,final,replen-i); |
7401 | 122 data += num_bytes; |
7362 | 123 } |
124 else /* raw packet */ | |
7401 | 125 { |
23457
a124f3abc1ec
Replace implicit use of fast_memcpy via macro by explicit use to allow
reimar
parents:
23305
diff
changeset
|
126 fast_memcpy(final, data, replen); |
7401 | 127 data += replen; |
128 } | |
129 | |
130 final += replen; | |
7362 | 131 } |
132 } | |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
133 |
7362 | 134 return; |
135 } | |
136 | |
137 | |
7401 | 138 static void decode_uncompressed_tga(TGAInfo *info, unsigned char *data, mp_image_t *mpi) |
7362 | 139 { |
140 unsigned char *final; | |
7401 | 141 int row, num_bytes = info->bpp / 8; |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
142 |
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
143 /* see line 207 to see why this loop is set up like this */ |
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
144 for (row = info->start_row; (!info->origin && row) || (info->origin && row < info->height); row += info->increment) |
7362 | 145 { |
7401 | 146 final = mpi->planes[0] + mpi->stride[0] * row; |
23457
a124f3abc1ec
Replace implicit use of fast_memcpy via macro by explicit use to allow
reimar
parents:
23305
diff
changeset
|
147 fast_memcpy(final, data, info->width * num_bytes); |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
148 data += info->width * num_bytes; |
7362 | 149 } |
150 | |
151 return; | |
152 } | |
153 | |
154 | |
7401 | 155 static short read_tga_header(unsigned char *buf, TGAInfo *info) |
7362 | 156 { |
7401 | 157 info->id_len = buf[0]; |
7362 | 158 |
7401 | 159 info->img_type = buf[2]; |
7362 | 160 |
161 /* targa data is always stored in little endian byte order */ | |
7401 | 162 info->width = le2me_16(*(unsigned short *) &buf[12]); |
163 info->height = le2me_16(*(unsigned short *) &buf[14]); | |
7362 | 164 |
7401 | 165 info->bpp = buf[16]; |
7362 | 166 |
7401 | 167 info->origin = (buf[17] & 0x20) >> 5; |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
168 |
7362 | 169 /* FIXME check for valid targa data */ |
170 | |
171 return 0; | |
172 } | |
173 | |
174 | |
175 /* decode a frame */ | |
176 static mp_image_t *decode(sh_video_t *sh, void *raw, int len, int flags) | |
177 { | |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
178 TGAInfo *info = sh->context; |
7362 | 179 unsigned char *data = raw; |
180 mp_image_t *mpi; | |
181 | |
182 | |
183 if (len <= 0) | |
184 return NULL; /* skip frame */ | |
185 | |
7401 | 186 read_tga_header(data, info); /* read information about the file */ |
7362 | 187 |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
188 if (info->bpp == 24) |
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
189 out_fmt = IMGFMT_BGR24; |
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
190 else if (info->bpp == 32) |
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
191 out_fmt = IMGFMT_BGR32; |
7362 | 192 else |
193 { | |
7401 | 194 mp_msg(MSGT_DECVIDEO, MSGL_INFO, "Unsupported TGA type! depth=%d\n",info->bpp); |
7362 | 195 return NULL; |
196 } | |
197 | |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
198 if (info->img_type != TGA_UNCOMP_TRUECOLOR && info->img_type != TGA_RLE_TRUECOLOR) /* not a true color image */ |
7362 | 199 { |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
200 mp_msg(MSGT_DECVIDEO, MSGL_INFO, "Unsupported TGA type: %i!\n", info->img_type); |
7362 | 201 return NULL; |
202 } | |
203 | |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
204 /* if img.origin is 0, we decode from bottom to top. if it's 1, we decode from top to bottom */ |
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
205 info->start_row = (info->origin) ? 0 : info->height - 1; |
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
206 info->increment = (info->origin) ? 1 : -1; |
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
207 |
7362 | 208 /* set data to the beginning of the image data */ |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
209 data += 18 + info->id_len; |
7362 | 210 |
211 /* (re)init libvo if image parameters changed (width/height/colorspace) */ | |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
212 if (last_w != info->width || last_h != info->height || last_c != out_fmt) |
7362 | 213 { |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
214 last_w = info->width; |
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
215 last_h = info->height; |
7362 | 216 last_c = out_fmt; |
217 | |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
218 if (!out_fmt || !mpcodecs_config_vo(sh, info->width, info->height, out_fmt)) |
7362 | 219 return NULL; |
220 } | |
221 | |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
222 if (!(mpi = mpcodecs_get_image(sh, MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, info->width, info->height))) |
7362 | 223 return NULL; |
224 | |
225 /* finally decode the image */ | |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
226 if (info->img_type == TGA_UNCOMP_TRUECOLOR) |
7401 | 227 decode_uncompressed_tga(info, data, mpi); |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
228 else if (info->img_type == TGA_RLE_TRUECOLOR) |
7401 | 229 decode_rle_tga(info, data, mpi); |
230 // else | |
231 // mpi = NULL; | |
7362 | 232 |
233 return mpi; | |
234 } | |
235 |