r125: This commit was manufactured by cvs2svn to create tag 'r1_1_7-last'.
[cinelerra_cv/mob.git] / hvirtual / quicktime / yuv2.c
blob57dc25e96fc1768993cb2e47e151a4ca2755ea50
1 #include "colormodels.h"
2 #include "funcprotos.h"
3 #include "quicktime.h"
4 #include "yuv2.h"
6 /* U V values are signed but Y R G B values are unsigned! */
7 /*
8 * R = Y + 1.40200 * V
9 * G = Y - 0.34414 * U - 0.71414 * V
10 * B = Y + 1.77200 * U
14 * Y = 0.2990 * R + 0.5870 * G + 0.1140 * B
15 * U = -0.1687 * R - 0.3310 * G + 0.5000 * B
16 * V = 0.5000 * R - 0.4187 * G - 0.0813 * B
20 typedef struct
22 int use_float;
23 long rtoy_tab[256], gtoy_tab[256], btoy_tab[256];
24 long rtou_tab[256], gtou_tab[256], btou_tab[256];
25 long rtov_tab[256], gtov_tab[256], btov_tab[256];
27 long vtor_tab[256], vtog_tab[256];
28 long utog_tab[256], utob_tab[256];
29 long *vtor, *vtog, *utog, *utob;
31 unsigned char *work_buffer;
32 int coded_w, coded_h;
34 /* The YUV2 codec requires a bytes per line that is a multiple of 4 */
35 int bytes_per_line;
36 int initialized;
37 } quicktime_yuv2_codec_t;
39 static int quicktime_delete_codec_yuv2(quicktime_video_map_t *vtrack)
41 quicktime_yuv2_codec_t *codec;
43 codec = ((quicktime_codec_t*)vtrack->codec)->priv;
44 if(codec->work_buffer) free(codec->work_buffer);
45 free(codec);
46 return 0;
49 static int quicktime_reads_colormodel_yuv2(quicktime_t *file,
50 int colormodel,
51 int track)
53 return (colormodel == BC_RGB888 ||
54 colormodel == BC_YUV888 ||
55 colormodel == BC_YUV422P);
58 static void encode_sign_change(quicktime_yuv2_codec_t *codec, unsigned char **row_pointers)
60 int y, x;
61 for(y = 0; y < codec->coded_h; y++)
63 unsigned char *out_row = codec->work_buffer + y * codec->bytes_per_line;
64 unsigned char *in_row = row_pointers[y];
65 for(x = 0; x < codec->bytes_per_line; )
67 *out_row++ = *in_row++;
68 *out_row++ = (int)(*in_row++) - 128;
69 *out_row++ = *in_row++;
70 *out_row++ = (int)(*in_row++) - 128;
71 x += 4;
76 static void decode_sign_change(quicktime_yuv2_codec_t *codec, unsigned char **row_pointers)
78 int y, x;
79 for(y = 0; y < codec->coded_h; y++)
81 unsigned char *in_row = row_pointers[y];
82 for(x = 0; x < codec->bytes_per_line; )
84 in_row[1] += 128;
85 in_row[3] += 128;
86 x += 4;
87 in_row += 4;
92 static void initialize(quicktime_video_map_t *vtrack, quicktime_yuv2_codec_t *codec)
94 int i;
95 if(!codec->initialized)
97 /* Init private items */
98 for(i = 0; i < 256; i++)
100 /* compression */
101 codec->rtoy_tab[i] = (long)( 0.2990 * 65536 * i);
102 codec->rtou_tab[i] = (long)(-0.1687 * 65536 * i);
103 codec->rtov_tab[i] = (long)( 0.5000 * 65536 * i);
105 codec->gtoy_tab[i] = (long)( 0.5870 * 65536 * i);
106 codec->gtou_tab[i] = (long)(-0.3320 * 65536 * i);
107 codec->gtov_tab[i] = (long)(-0.4187 * 65536 * i);
109 codec->btoy_tab[i] = (long)( 0.1140 * 65536 * i);
110 codec->btou_tab[i] = (long)( 0.5000 * 65536 * i);
111 codec->btov_tab[i] = (long)(-0.0813 * 65536 * i);
114 codec->vtor = &(codec->vtor_tab[128]);
115 codec->vtog = &(codec->vtog_tab[128]);
116 codec->utog = &(codec->utog_tab[128]);
117 codec->utob = &(codec->utob_tab[128]);
119 for(i = -128; i < 128; i++)
121 /* decompression */
122 codec->vtor[i] = (long)( 1.4020 * 65536 * i);
123 codec->vtog[i] = (long)(-0.7141 * 65536 * i);
125 codec->utog[i] = (long)(-0.3441 * 65536 * i);
126 codec->utob[i] = (long)( 1.7720 * 65536 * i);
129 codec->coded_w = (int)((float)vtrack->track->tkhd.track_width / 4 + 0.5) * 4;
130 codec->coded_h = (int)((float)vtrack->track->tkhd.track_height / 4 + 0.5) * 4;
132 codec->bytes_per_line = codec->coded_w * 2;
133 codec->work_buffer = malloc(codec->bytes_per_line *
134 codec->coded_h);
135 codec->initialized = 1;
139 static int decode(quicktime_t *file, unsigned char **row_pointers, int track)
141 int64_t bytes, x, y;
142 quicktime_video_map_t *vtrack = &(file->vtracks[track]);
143 quicktime_yuv2_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
144 int width = vtrack->track->tkhd.track_width;
145 int height = vtrack->track->tkhd.track_height;
146 unsigned char *buffer;
147 char *input_row;
148 unsigned char *output_row, *y_plane, *u_plane, *v_plane;
149 int result = 0;
150 int y1, u, v, y2, r, g, b;
151 int bytes_per_row = width * cmodel_calculate_pixelsize(file->color_model);
152 initialize(vtrack, codec);
154 vtrack->track->tkhd.track_width;
155 quicktime_set_video_position(file, vtrack->current_position, track);
156 bytes = quicktime_frame_size(file, vtrack->current_position, track);
158 if(file->color_model == BC_YUV422 &&
159 file->in_x == 0 &&
160 file->in_y == 0 &&
161 file->in_w == width &&
162 file->in_h == height &&
163 file->out_w == width &&
164 file->out_h == height)
166 result = !quicktime_read_data(file, row_pointers[0], bytes);
167 decode_sign_change(codec, row_pointers);
169 else
171 unsigned char *input_rows[height];
172 result = !quicktime_read_data(file, codec->work_buffer, bytes);
173 for(y = 0; y < height; y++)
174 input_rows[y] = &codec->work_buffer[y * codec->bytes_per_line];
175 decode_sign_change(codec, input_rows);
177 cmodel_transfer(row_pointers,
178 input_rows,
179 row_pointers[0],
180 row_pointers[1],
181 row_pointers[2],
185 file->in_x,
186 file->in_y,
187 file->in_w,
188 file->in_h,
191 file->out_w,
192 file->out_h,
193 BC_YUV422,
194 file->color_model,
196 codec->coded_w,
197 file->out_w);
202 return result;
205 static int encode(quicktime_t *file, unsigned char **row_pointers, int track)
207 int64_t offset = quicktime_position(file);
208 quicktime_video_map_t *vtrack = &(file->vtracks[track]);
209 quicktime_trak_t *trak = vtrack->track;
210 quicktime_yuv2_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
211 int result = 1;
212 int width = vtrack->track->tkhd.track_width;
213 int height = vtrack->track->tkhd.track_height;
214 int64_t bytes;
215 unsigned char *buffer;
216 int x, y;
217 int y1, u, y2, v;
218 int r, g, b, i;
219 int bytes_per_row = width * 3;
220 quicktime_atom_t chunk_atom;
222 initialize(vtrack, codec);
224 bytes = height * codec->bytes_per_line;
225 buffer = codec->work_buffer;
226 if(file->color_model == BC_YUV422)
228 encode_sign_change(codec, row_pointers);
229 quicktime_write_chunk_header(file, trak, &chunk_atom);
230 result = !quicktime_write_data(file, buffer, bytes);
232 else
234 unsigned char **temp_rows = malloc(sizeof(unsigned char*) * height);
235 for(i = 0; i < height; i++)
236 temp_rows[i] = buffer + i * codec->bytes_per_line;
238 cmodel_transfer(temp_rows,
239 row_pointers,
243 row_pointers[0],
244 row_pointers[1],
245 row_pointers[2],
248 width,
249 height,
252 width,
253 height,
254 file->color_model,
255 BC_YUV422,
257 width,
258 codec->coded_w);
259 encode_sign_change(codec, temp_rows);
260 quicktime_write_chunk_header(file, trak, &chunk_atom);
261 result = !quicktime_write_data(file, buffer, bytes);
262 free(temp_rows);
265 quicktime_write_chunk_footer(file,
266 trak,
267 vtrack->current_chunk,
268 &chunk_atom,
271 vtrack->current_chunk++;
272 return result;
275 static int reads_colormodel(quicktime_t *file,
276 int colormodel,
277 int track)
279 quicktime_video_map_t *vtrack = &(file->vtracks[track]);
280 quicktime_yuv2_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
282 return (colormodel == BC_RGB888 ||
283 colormodel == BC_YUV888 ||
284 colormodel == BC_YUV422P ||
285 colormodel == BC_YUV422);
288 static int writes_colormodel(quicktime_t *file,
289 int colormodel,
290 int track)
292 quicktime_video_map_t *vtrack = &(file->vtracks[track]);
293 quicktime_yuv2_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
295 return (colormodel == BC_RGB888 ||
296 colormodel == BC_YUV888 ||
297 colormodel == BC_YUV422P ||
298 colormodel == BC_YUV422);
301 void quicktime_init_codec_yuv2(quicktime_video_map_t *vtrack)
303 quicktime_codec_t *codec_base = (quicktime_codec_t*)vtrack->codec;
305 /* Init public items */
306 codec_base->priv = calloc(1, sizeof(quicktime_yuv2_codec_t));
307 codec_base->delete_vcodec = quicktime_delete_codec_yuv2;
308 codec_base->decode_video = decode;
309 codec_base->encode_video = encode;
310 codec_base->decode_audio = 0;
311 codec_base->encode_audio = 0;
312 codec_base->reads_colormodel = reads_colormodel;
313 codec_base->writes_colormodel = writes_colormodel;
314 codec_base->fourcc = QUICKTIME_YUV2;
315 codec_base->title = "Component Video";
316 codec_base->desc = "YUV 4:2:2";