1
/* fmfconv_yuv.c: yuv4mpeg output routine included into fmfconv.c
2
Copyright (c) 2004-2005 Gergely Szasz
4
$Id: fmfconv_yuv.c 4777 2012-11-26 23:35:48Z sbaldovi $
6
This program is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2 of the License, or
9
(at your option) any later version.
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
GNU General Public License for more details.
16
You should have received a copy of the GNU General Public License along
17
with this program; if not, write to the Free Software Foundation, Inc.,
18
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20
Author contact information:
22
E-mail: szaszg@hu.inter.net
30
#include "libspectrum.h"
33
int yuv_ylen = 0, yuv_uvlen = 0;
34
static libspectrum_byte pix_uv[2][40 * 8 * 240 * 2]; /* bpp = 2; w = 40*8 h = 240 timex = 2 subsampled yuv*/
38
422 cosited -> @*@* @*@*
40
420j centered -> @*@* @*@*
42
420m h cosited -> * * * * * * * *
45
420 cosited -> @*@* @*@*
48
!!!410 cosited -> @*** @*** TODO
55
libspectrum_byte *u, *v, *u_out, *v_out;
65
if( yuv_t == TYPE_444 ) { /* */
69
} else if( yuv_t == TYPE_420J ) { /* interstitial */
70
for( j = 0; j < frm_h; j += 2 ) { /* lines */
71
u = &pix_yuv[1][j * frm_w];
72
for( i = 0; i < frm_w; i += 2 ) { /* columns */
73
*u_out++ = ( (libspectrum_word)(*u) + *(u + 1) +
74
*( u + frm_w ) + *( u + frm_w + 1 ) ) >> 2;
78
for( j = 0; j < frm_h; j += 2 ) { /* lines */
79
v = &pix_yuv[2][j * frm_w];
80
for( i = 0; i < frm_w; i += 2 ) { /* columns */
81
*v_out++ = ( (libspectrum_word)(*v) + *(v + 1) +
82
*( v + frm_w ) + *( v + frm_w + 1 ) ) >> 2;
86
yuv_uvlen = yuv_ylen >> 2;
89
} else if( yuv_t == TYPE_420M ) { /* horiz cosited */
90
for( j = 0; j < frm_h; j += 2 ) { /* lines */
91
u = &pix_yuv[1][j * frm_w];
92
*u_out++ = ( (libspectrum_word)(*u) * 3 + *(u + 1) +
93
*( u + frm_w ) * 3 + *( u + frm_w + 1 ) ) >> 3;
95
for( i = 2; i < frm_w; i += 2 ) { /* columns */
96
*u_out++ = ( (libspectrum_word)(*(u - 1)) + *u * 2 + *(u + 1) +
97
*( u + frm_w - 1 ) + *( u + frm_w ) * 2 +
98
*( u + frm_w + 1 ) ) >> 3;
102
for( j = 0; j < frm_h; j += 2 ) { /* lines */
103
v = &pix_yuv[2][j * frm_w];
104
*v_out++ = ( (libspectrum_word)(*v) * 3 + *(v + 1) +
105
*( v + frm_w ) * 3 + *( v + frm_w + 1 ) ) >> 3;
107
for( i = 2; i < frm_w; i += 2 ) { /* columns */
108
*v_out++ = ( (libspectrum_word)(*(v - 1)) + *v * 2 + *(v + 1) +
109
*( v + frm_w - 1 ) + *( v + frm_w ) * 2 +
110
*( v + frm_w + 1 ) ) >> 3;
114
yuv_uvlen = yuv_ylen >> 2;
117
} else if( yuv_t == TYPE_420 ) { /* cosited */
119
abcdef hino => 1/4a+1/2b+1/4c+1/2g+h+1/2i+1/4m+1/2n+1/4o / 4
120
ghijkl abgh => 1/4a+1/2a+1/4b+1/2a+a+1/2b+1/4g+1/2g+1/4h / 4
121
mnopqr ghmn => 1/4a+1/2a+1/4b+1/2g+g+1/2h+1/4m+1/2m+1/4n / 4
123
for( j = 0; j < frm_h; j += 2 ) { /* lines */
124
u = &pix_yuv[1][j * frm_w];
126
*u_out++ = ( (libspectrum_word)(*u) * 9 + *(u + 1) * 3 +
127
*(u + frm_w) * 3 + *(u + frm_w + 1) ) >> 4;
129
*u_out++ = ( (libspectrum_word)(*(u - frm_w)) * 3 +
131
(*u) * 5 + *(u + 1) * 2 +
132
*(u + frm_w) * 3 + *(u + frm_w + 1) ) >> 4;
134
for( i = 2; i < frm_w; i += 2 ) { /* columns */
135
*u_out++ = ( (libspectrum_word)(*(u - frm_w - 1)) +
136
*(u - frm_w) * 2 + *(u - frm_w + 1) +
137
*(u - 1) * 2 + *u * 4 + *(u + 1) * 2 +
139
*(u + frm_w) * 2 + *(u + frm_w + 1) ) >> 4;
143
for( j = 0; j < frm_h; j += 2 ) { /* lines */
144
v = &pix_yuv[2][j * frm_w];
146
*v_out++ = ( (libspectrum_word)(*v) * 9 + *(v + 1) * 3 +
147
*(v + frm_w) * 3 + *(v + frm_w + 1) ) >> 4;
149
*v_out++ = ( (libspectrum_word)(*(v - frm_w)) * 3 +
151
(*v) * 5 + *(v + 1) * 2 +
152
*(v + frm_w) * 3 + *(v + frm_w + 1) ) >> 4;
154
for( i = 2; i < frm_w; i += 2 ) { /* columns */
155
*v_out++ = ( (libspectrum_word)(*(v - frm_w - 1)) +
156
*(v - frm_w) * 2 + *(v - frm_w + 1) +
157
*(v - 1) * 2 + *v * 4 + *(v + 1) * 2 +
159
*(v + frm_w) * 2 + *(v + frm_w + 1) ) >> 4;
163
yuv_uvlen = yuv_ylen >> 2;
166
} else if( yuv_t == TYPE_422 ) { /* cosited (PAL/NTSC TV)*/
167
for( j = 0; j < frm_h; j++ ) { /* lines */
168
u = &pix_yuv[1][j * frm_w];
169
*u_out++ = ( (libspectrum_word)(*u) * 3 + *(u + 1) +
170
*( u + frm_w ) * 3 + *( u + frm_w + 1 ) ) >> 3;
172
for( i = 2; i < frm_w - 2; i += 2 ) { /* columns */
173
*u_out++ = ( (libspectrum_word)(*(u - 1)) + *u * 2 + *(u + 1) +
174
*( u + frm_w - 1 ) + *( u + frm_w ) * 2 +
175
*( u + frm_w + 1 ) ) >> 3;
178
*u_out++ = ( (libspectrum_word)(*u) + *(u + 1) * 3 +
179
*( u + frm_w ) + *( u + frm_w + 1 ) * 3 ) >> 3;
182
for( j = 0; j < frm_h; j++ ) { /* lines */
183
v = &pix_yuv[2][j * frm_w];
184
*v_out++ = ( (libspectrum_word)(*v) * 3 + *(v + 1) +
185
*( v + frm_w ) * 3 + *( v + frm_w + 1 ) ) >> 3;
187
for( i = 2; i < frm_w - 2; i += 2 ) { /* columns */
188
*v_out++ = ( (libspectrum_word)(*(v - 1)) + *v * 2 + *(v + 1) +
189
*( v + frm_w - 1 ) + *( v + frm_w ) * 2 +
190
*( v + frm_w + 1 ) ) >> 3;
193
*v_out++ = ( (libspectrum_word)(*v) + *(v + 1) * 3 +
194
*( v + frm_w ) + *( v + frm_w + 1 ) * 3 ) >> 3;
197
yuv_uvlen = yuv_ylen >> 1;
205
out_write_yuvheader( void )
207
const char *yuv4mpeg2[] = {
208
"444", "422", "420jpeg", "420mpeg2", "420", "410"
213
" W%d H%d F%d:1000 Ip A%c:1 C%s\n",
214
frm_w, frm_h, out_fps,
215
( scr_t == TYPE_HRE && 0 ? '2' : '1' ),
216
yuv4mpeg2[yuv_t - TYPE_444] );
218
printi( 1, "out_write_yuvheader(): W=%d H=%d F=%d:1000 A=%d\n", frm_w, frm_h,
224
out_write_yuv( void )
228
if( !out_header_ok && ( err = out_write_yuvheader() ) ) return err;
230
fprintf( out, "FRAME\n" );
231
if( fwrite( pix_yuv[0], yuv_ylen, 1, out ) != 1 ) return ERR_WRITE_OUT;
232
if( yuv_t != TYPE_444 ) {
234
if( fwrite( pix_uv[0], yuv_uvlen, 1, out ) != 1 ) return ERR_WRITE_OUT;
235
if( fwrite( pix_uv[1], yuv_uvlen, 1, out ) != 1 ) return ERR_WRITE_OUT;
237
if( fwrite( pix_yuv[1], yuv_ylen, 1, out ) != 1 ) return ERR_WRITE_OUT;
238
if( fwrite( pix_yuv[2], yuv_ylen, 1, out ) != 1 ) return ERR_WRITE_OUT;
241
printi( 2, "out_write_yuv()\n" );