1 /*
2 * TARGA video output
3 *
4 * This video output module writes TARGA uncompressed files in 15, 24 and 32
5 * bit BGR format.
6 *
7 * to select the output format use the format filter:
8 * mplayer -vo tga -vf format=bgr15 ...
9 * mplayer -vo tga -vf format=bgr24 ...
10 * mplayer -vo tga -vf format=bgr32 ...
11 *
12 * The 16 bit files are loaded without problem from Gimp and ImageMagick but
13 * give an error with entice (a visualizer from the enlightenment package
14 * that uses the imlib2 package).
15 *
16 * In 32-bit mode the alpha channel is set to 255 (0xff). For big-endian
17 * machines, TGA_ALPHA32 changes from 0xff000000 to 0x000000ff, and
18 * TGA_SHIFT32 from 0 to 8.
19 *
20 * I need to fill the alpha channel because entice considers that alpha
21 * channel (and displays nothing, only the background!), but ImageMagick
22 * (the program display) or gimp doesn't care.
23 *
24 * Maybe it is possible (with a compilation switch) to avoid the fill of
25 * the alpha channel and work outside MPlayer (if needed).
26 *
27 * Daniele Forghieri ( guru@digitalfantasy.it )
28 *
29 * This file is part of MPlayer.
30 *
31 * MPlayer is free software; you can redistribute it and/or modify
32 * it under the terms of the GNU General Public License as published by
33 * the Free Software Foundation; either version 2 of the License, or
34 * (at your option) any later version.
35 *
36 * MPlayer is distributed in the hope that it will be useful,
37 * but WITHOUT ANY WARRANTY; without even the implied warranty of
38 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
39 * GNU General Public License for more details.
40 *
41 * You should have received a copy of the GNU General Public License along
42 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
43 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
44 */
45
46 #include <stdio.h>
47 #include <stdlib.h>
48 #include <string.h>
49 #include <errno.h>
50 #include <math.h>
51
52 #include "config.h"
53 #include "mp_msg.h"
54 #include "help_mp.h"
55 #include "video_out.h"
56 #define NO_DRAW_FRAME
57 #define NO_DRAW_SLICE
58 #include "video_out_internal.h"
59
60 static const vo_info_t info =
61 {
62 "Targa output",
63 "tga",
64 "Daniele Forghieri - guru@digitalfantasy.it",
65 ""
66 };
67
68
69 const LIBVO_EXTERN (tga)
70
71 /* locals vars */
72 static int frame_num = 0;
73
tga_make_header(uint8_t * h,int dx,int dy,int bpp)74 static void tga_make_header(uint8_t *h, int dx, int dy, int bpp)
75 {
76
77 int i;
78
79 for(i = 0; i < 18; i++) {
80 switch (i) {
81 case 2:
82 *h = 0x02;
83 break;
84
85 case 12:
86 *h = dx & 0xff;
87 break;
88
89 case 13:
90 *h = (dx >> 8) & 0xff;
91 break;
92
93 case 14:
94 *h = dy & 0xff;
95 break;
96
97 case 15:
98 *h = (dy >> 8) & 0xff;
99 break;
100
101 case 16:
102 *h = bpp;
103 break;
104
105 case 17:
106 *h = 0x20;
107 break;
108
109 default:
110 *h = 0;
111 }
112 ++h;
113 }
114
115 }
116
write_tga(char * file,int bpp,int dx,int dy,uint8_t * buf,int stride)117 static int write_tga( char *file, int bpp, int dx, int dy, uint8_t *buf, int stride)
118 {
119 int er;
120 FILE *fo;
121
122 fo = fopen(file, "wb");
123 if (fo != NULL) {
124 uint8_t hdr[18];
125
126 er = 0;
127 tga_make_header(hdr, dx, dy, bpp);
128 if (fwrite(hdr, sizeof(hdr), 1, fo) == 1) {
129 int wb;
130
131 wb = ((bpp + 7) / 8) * dx;
132 while (dy-- > 0) {
133 if (fwrite(buf, wb, 1, fo) != 1) {
134 er = 4;
135 break;
136 }
137 buf += stride;
138 }
139 }
140 else {
141 er = 2;
142 }
143
144 fclose(fo);
145 }
146 else {
147 er = 1;
148 }
149
150 if (er) {
151 fprintf(stderr, "Error writing file [%s]\n", file);
152 }
153 return er;
154 }
155
draw_image(mp_image_t * mpi)156 static uint32_t draw_image(mp_image_t* mpi)
157 {
158 char file[20 + 1];
159
160 snprintf (file, 20, "%08d.tga", ++frame_num);
161
162 write_tga( file,
163 mpi->bpp,
164 mpi->w,
165 mpi->h,
166 mpi->planes[0],
167 mpi->stride[0]);
168
169 return VO_TRUE;
170 }
171
config(uint32_t width,uint32_t height,uint32_t d_width,uint32_t d_height,uint32_t flags,char * title,uint32_t format)172 static int config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t flags, char *title, uint32_t format)
173 {
174 return 0;
175 }
176
draw_osd(void)177 static void draw_osd(void)
178 {
179 }
180
flip_page(void)181 static void flip_page (void)
182 {
183 return;
184 }
185
query_format(uint32_t format)186 static int query_format(uint32_t format)
187 {
188 switch(format){
189 case IMGFMT_BGR15LE:
190 case IMGFMT_BGR24:
191 case IMGFMT_BGRA:
192 return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW;
193 }
194 return 0;
195 }
196
uninit(void)197 static void uninit(void)
198 {
199 }
200
check_events(void)201 static void check_events(void)
202 {
203 }
204
preinit(const char * arg)205 static int preinit(const char *arg)
206 {
207 if(arg) {
208 mp_msg(MSGT_VO,MSGL_WARN, MSGTR_LIBVO_TGA_UnknownSubdevice,arg);
209 return ENOSYS;
210 }
211 return 0;
212 }
213
control(uint32_t request,void * data)214 static int control(uint32_t request, void *data)
215 {
216 switch (request) {
217 case VOCTRL_DRAW_IMAGE:
218 return draw_image(data);
219
220 case VOCTRL_QUERY_FORMAT:
221 return query_format(*((uint32_t*)data));
222 }
223 return VO_NOTIMPL;
224 }
225