Mercurial > mplayer.hg
annotate libmpcodecs/vd_mtga.c @ 35367:f1bd28a00384
Fix segmentation fault with mouse button release.
This should have been part of r35445, but has been forgotten. In r35445
only the main window has been fixed while this fixes the playbar window.
author | ib |
---|---|
date | Fri, 23 Nov 2012 14:17:21 +0000 |
parents | b40d593a463f |
children |
rev | line source |
---|---|
30421
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29263
diff
changeset
|
1 /* |
7362 | 2 * based on: XreaL's x_r_img_tga.* (http://www.sourceforge.net/projects/xreal/) |
3 * libtarga.* | |
4 * xli's tga.* | |
30421
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29263
diff
changeset
|
5 * |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29263
diff
changeset
|
6 * Copyright (c) 2002 Tilman Sauerbeck <tsauerbeck@users.sourceforge.net> |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29263
diff
changeset
|
7 * |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29263
diff
changeset
|
8 * This file is part of MPlayer. |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29263
diff
changeset
|
9 * |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29263
diff
changeset
|
10 * MPlayer is free software; you can redistribute it and/or modify |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29263
diff
changeset
|
11 * it under the terms of the GNU General Public License as published by |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29263
diff
changeset
|
12 * the Free Software Foundation; either version 2 of the License, or |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29263
diff
changeset
|
13 * (at your option) any later version. |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29263
diff
changeset
|
14 * |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29263
diff
changeset
|
15 * MPlayer is distributed in the hope that it will be useful, |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29263
diff
changeset
|
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29263
diff
changeset
|
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29263
diff
changeset
|
18 * GNU General Public License for more details. |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29263
diff
changeset
|
19 * |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29263
diff
changeset
|
20 * You should have received a copy of the GNU General Public License along |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29263
diff
changeset
|
21 * with MPlayer; if not, write to the Free Software Foundation, Inc., |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29263
diff
changeset
|
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
7362 | 23 */ |
24 | |
25 #include <stdio.h> | |
26 #include <stdlib.h> | |
23305
22d3d12c6dfb
Include string.h for memcpy, fastmemcpy.h alone is not enough.
reimar
parents:
21507
diff
changeset
|
27 #include <string.h> |
7362 | 28 |
29 #include "config.h" | |
30 #include "mp_msg.h" | |
31 | |
31614
b40d593a463f
Use AV_RL* macros instead of typecasts where appropriate.
reimar
parents:
30702
diff
changeset
|
32 #include "libavutil/intreadwrite.h" |
7362 | 33 #include "libvo/fastmemcpy.h" |
34 | |
35 #include "vd_internal.h" | |
36 | |
30504
cc27da5d7286
Mark all ad_info_t/vd_info_t structure declarations as const.
diego
parents:
30421
diff
changeset
|
37 static const vd_info_t info = |
7362 | 38 { |
39 "TGA Images decoder", | |
40 "mtga", | |
7401 | 41 "Tilman Sauerbeck, A'rpi", |
7362 | 42 "Tilman Sauerbeck", |
43 "only 24bpp and 32bpp RGB targa files support so far" | |
44 }; | |
45 | |
46 LIBVD_EXTERN(mtga) | |
47 | |
48 typedef enum | |
49 { | |
50 TGA_NO_DATA, | |
51 TGA_UNCOMP_PALETTED, | |
52 TGA_UNCOMP_TRUECOLOR, | |
53 TGA_UNCOMP_GRAYSCALE, | |
54 TGA_RLE_PALETTED = 9, | |
55 TGA_RLE_TRUECOLOR, | |
56 TGA_RLE_GRAYSCALE | |
57 } TGAImageType; | |
58 | |
59 typedef struct | |
60 { | |
61 unsigned char id_len; | |
62 unsigned short img_type; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26280
diff
changeset
|
63 |
7362 | 64 unsigned short width; |
65 unsigned short height; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26280
diff
changeset
|
66 |
7362 | 67 unsigned char bpp; |
68 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
|
69 unsigned short start_row; |
9605 | 70 short increment; |
7362 | 71 } TGAInfo; |
72 | |
73 static unsigned int out_fmt = 0; | |
74 | |
75 static int last_w = -1; | |
76 static int last_h = -1; | |
77 static int last_c = -1; | |
78 | |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
79 |
7362 | 80 /* to set/get/query special features/parameters */ |
81 static int control(sh_video_t *sh, int cmd, void *arg, ...) | |
82 { | |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
83 switch (cmd) |
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
84 { |
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
85 case VDCTRL_QUERY_FORMAT: |
7401 | 86 if (*((int *) arg) == out_fmt) return CONTROL_TRUE; |
87 return CONTROL_FALSE; | |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
88 } |
7401 | 89 return CONTROL_UNKNOWN; |
7362 | 90 } |
91 | |
92 /* init driver */ | |
93 static int init(sh_video_t *sh) | |
94 { | |
30702 | 95 sh->context = calloc(1, sizeof(TGAInfo)); |
7362 | 96 last_w = -1; |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
97 |
7362 | 98 return 1; |
99 } | |
100 | |
101 | |
102 /* uninit driver */ | |
103 static void uninit(sh_video_t *sh) | |
104 { | |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
105 TGAInfo *info = sh->context; |
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
106 free(info); |
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
107 return; |
7362 | 108 } |
109 | |
110 | |
111 /* decode a runlength-encoded tga */ | |
7401 | 112 static void decode_rle_tga(TGAInfo *info, unsigned char *data, mp_image_t *mpi) |
7362 | 113 { |
7401 | 114 int row, col, replen, i, num_bytes = info->bpp / 8; |
7362 | 115 unsigned char repetitions, packet_header, *final; |
116 | |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
117 /* 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
|
118 for (row = info->start_row; (!info->origin && row) || (info->origin && row < info->height); row += info->increment) |
7362 | 119 { |
7401 | 120 final = mpi->planes[0] + mpi->stride[0] * row; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26280
diff
changeset
|
121 |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
122 for (col = 0; col < info->width; col += repetitions) |
7362 | 123 { |
124 packet_header = *data++; | |
7401 | 125 repetitions = (1 + (packet_header & 0x7f)); |
126 replen = repetitions * num_bytes; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26280
diff
changeset
|
127 |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
128 if (packet_header & 0x80) /* runlength encoded packet */ |
7362 | 129 { |
23458
973e53dc7df5
Do not use fast_memcpy for small size copy, esp. when the size is constant
reimar
parents:
23457
diff
changeset
|
130 memcpy(final, data, num_bytes); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26280
diff
changeset
|
131 |
7401 | 132 // Note: this will be slow when DR to vram! |
133 i=num_bytes; | |
134 while(2*i<=replen){ | |
23459
2c09fe135c93
Do not use fast_memcpy when data is read again immediately afterwards.
reimar
parents:
23458
diff
changeset
|
135 memcpy(final+i,final,i); |
7401 | 136 i*=2; |
137 } | |
23459
2c09fe135c93
Do not use fast_memcpy when data is read again immediately afterwards.
reimar
parents:
23458
diff
changeset
|
138 memcpy(final+i,final,replen-i); |
7401 | 139 data += num_bytes; |
7362 | 140 } |
141 else /* raw packet */ | |
7401 | 142 { |
23457
a124f3abc1ec
Replace implicit use of fast_memcpy via macro by explicit use to allow
reimar
parents:
23305
diff
changeset
|
143 fast_memcpy(final, data, replen); |
7401 | 144 data += replen; |
145 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26280
diff
changeset
|
146 |
7401 | 147 final += replen; |
7362 | 148 } |
149 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26280
diff
changeset
|
150 |
7362 | 151 return; |
152 } | |
153 | |
154 | |
7401 | 155 static void decode_uncompressed_tga(TGAInfo *info, unsigned char *data, mp_image_t *mpi) |
7362 | 156 { |
157 unsigned char *final; | |
7401 | 158 int row, num_bytes = info->bpp / 8; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26280
diff
changeset
|
159 |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
160 /* 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
|
161 for (row = info->start_row; (!info->origin && row) || (info->origin && row < info->height); row += info->increment) |
7362 | 162 { |
7401 | 163 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
|
164 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
|
165 data += info->width * num_bytes; |
7362 | 166 } |
167 | |
168 return; | |
169 } | |
170 | |
171 | |
7401 | 172 static short read_tga_header(unsigned char *buf, TGAInfo *info) |
7362 | 173 { |
7401 | 174 info->id_len = buf[0]; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26280
diff
changeset
|
175 |
7401 | 176 info->img_type = buf[2]; |
7362 | 177 |
178 /* targa data is always stored in little endian byte order */ | |
31614
b40d593a463f
Use AV_RL* macros instead of typecasts where appropriate.
reimar
parents:
30702
diff
changeset
|
179 info->width = AV_RL16(&buf[12]); |
b40d593a463f
Use AV_RL* macros instead of typecasts where appropriate.
reimar
parents:
30702
diff
changeset
|
180 info->height = AV_RL16(&buf[14]); |
7362 | 181 |
7401 | 182 info->bpp = buf[16]; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26280
diff
changeset
|
183 |
7401 | 184 info->origin = (buf[17] & 0x20) >> 5; |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
185 |
7362 | 186 /* FIXME check for valid targa data */ |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26280
diff
changeset
|
187 |
7362 | 188 return 0; |
189 } | |
190 | |
191 | |
192 /* decode a frame */ | |
193 static mp_image_t *decode(sh_video_t *sh, void *raw, int len, int flags) | |
194 { | |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
195 TGAInfo *info = sh->context; |
7362 | 196 unsigned char *data = raw; |
197 mp_image_t *mpi; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26280
diff
changeset
|
198 |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26280
diff
changeset
|
199 |
7362 | 200 if (len <= 0) |
201 return NULL; /* skip frame */ | |
202 | |
7401 | 203 read_tga_header(data, info); /* read information about the file */ |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26280
diff
changeset
|
204 |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
205 if (info->bpp == 24) |
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
206 out_fmt = IMGFMT_BGR24; |
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
207 else if (info->bpp == 32) |
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
208 out_fmt = IMGFMT_BGR32; |
7362 | 209 else |
210 { | |
7401 | 211 mp_msg(MSGT_DECVIDEO, MSGL_INFO, "Unsupported TGA type! depth=%d\n",info->bpp); |
7362 | 212 return NULL; |
213 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26280
diff
changeset
|
214 |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
215 if (info->img_type != TGA_UNCOMP_TRUECOLOR && info->img_type != TGA_RLE_TRUECOLOR) /* not a true color image */ |
7362 | 216 { |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
217 mp_msg(MSGT_DECVIDEO, MSGL_INFO, "Unsupported TGA type: %i!\n", info->img_type); |
7362 | 218 return NULL; |
219 } | |
220 | |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
221 /* 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
|
222 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
|
223 info->increment = (info->origin) ? 1 : -1; |
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
224 |
7362 | 225 /* 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
|
226 data += 18 + info->id_len; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26280
diff
changeset
|
227 |
7362 | 228 /* (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
|
229 if (last_w != info->width || last_h != info->height || last_c != out_fmt) |
7362 | 230 { |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
231 last_w = info->width; |
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
232 last_h = info->height; |
7362 | 233 last_c = out_fmt; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26280
diff
changeset
|
234 |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
235 if (!out_fmt || !mpcodecs_config_vo(sh, info->width, info->height, out_fmt)) |
7362 | 236 return NULL; |
237 } | |
238 | |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
239 if (!(mpi = mpcodecs_get_image(sh, MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, info->width, info->height))) |
7362 | 240 return NULL; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
26280
diff
changeset
|
241 |
7362 | 242 /* finally decode the image */ |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
243 if (info->img_type == TGA_UNCOMP_TRUECOLOR) |
7401 | 244 decode_uncompressed_tga(info, data, mpi); |
7392
e21841225e2a
query_format support by Tilman Sauerbeck <tsauerbeck@users.sourceforge.net>
alex
parents:
7362
diff
changeset
|
245 else if (info->img_type == TGA_RLE_TRUECOLOR) |
7401 | 246 decode_rle_tga(info, data, mpi); |
247 // else | |
248 // mpi = NULL; | |
7362 | 249 |
250 return mpi; | |
251 } |