Merge branch 'ct' of git.pipapo.org:cinelerra-ct into ct
[cinelerra_cv/ct.git] / quicktime / raw.c
blob5da0f80472f0159364012debb06e2efe6011f713
1 #include "colormodels.h"
2 #include "funcprotos.h"
3 #include "quicktime.h"
4 #include "graphics.h"
6 typedef struct
8 unsigned char *temp_frame; /* For changing color models and scaling */
9 unsigned char **temp_rows;
10 } quicktime_raw_codec_t;
13 static int quicktime_delete_codec_raw(quicktime_video_map_t *vtrack)
15 quicktime_raw_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
16 if(codec->temp_frame)
18 free(codec->temp_frame);
19 free(codec->temp_rows);
21 free(codec);
22 return 0;
25 static int source_cmodel(quicktime_t *file, int track)
27 int depth = quicktime_video_depth(file, track);
28 if(depth == 24)
29 return BC_RGB888;
30 else
31 return BC_ARGB8888;
34 static int decode(quicktime_t *file, unsigned char **row_pointers, int track)
36 int result = 0;
37 quicktime_trak_t *trak = file->vtracks[track].track;
38 int frame_depth = quicktime_video_depth(file, track);
39 int height = trak->tkhd.track_height;
40 int width = trak->tkhd.track_width;
41 long bytes;
42 int i;
43 quicktime_raw_codec_t *codec = ((quicktime_codec_t*)file->vtracks[track].codec)->priv;
44 int pixel_size = frame_depth / 8;
45 int cmodel = source_cmodel(file, track);
46 int use_temp = (cmodel != file->color_model ||
47 file->in_x != 0 ||
48 file->in_y != 0 ||
49 file->in_w != width ||
50 file->in_h != height ||
51 file->out_w != width ||
52 file->out_h != height);
53 unsigned char *temp_data;
54 unsigned char **temp_rows = malloc(sizeof(unsigned char*) * height);
56 if(use_temp)
58 if(!codec->temp_frame)
60 codec->temp_frame = malloc(cmodel_calculate_datasize(width,
61 height,
62 -1,
63 cmodel));
65 for(i = 0; i < height; i++)
66 temp_rows[i] = codec->temp_frame +
67 cmodel_calculate_pixelsize(cmodel) * width * i;
68 temp_data = codec->temp_frame;
70 else
72 temp_data = row_pointers[0];
73 for(i = 0; i < height; i++)
74 temp_rows[i] = row_pointers[i];
78 /* Read data */
79 quicktime_set_video_position(file, file->vtracks[track].current_position, track);
80 bytes = quicktime_frame_size(file, file->vtracks[track].current_position, track);
81 result = !quicktime_read_data(file, temp_data, bytes);
83 /* Convert colormodel */
84 if(use_temp)
86 cmodel_transfer(row_pointers,
87 temp_rows,
88 row_pointers[0],
89 row_pointers[1],
90 row_pointers[2],
94 file->in_x,
95 file->in_y,
96 file->in_w,
97 file->in_h,
98 0,
99 0,
100 file->out_w,
101 file->out_h,
102 cmodel,
103 file->color_model,
105 width,
106 file->out_w);
109 free(temp_rows);
111 return result;
114 static int encode(quicktime_t *file,
115 unsigned char **row_pointers,
116 int track)
118 quicktime_video_map_t *vtrack = &(file->vtracks[track]);
119 quicktime_raw_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
120 quicktime_trak_t *trak = vtrack->track;
121 int64_t offset = quicktime_position(file);
122 int result = 0;
123 register int i, j;
124 int height = trak->tkhd.track_height;
125 int width = trak->tkhd.track_width;
126 int depth = quicktime_video_depth(file, track);
127 int64_t bytes = height * width * depth / 8;
128 int64_t bytes_per_row = width * depth / 8;
129 unsigned char temp;
130 int dest_cmodel;
131 quicktime_atom_t chunk_atom;
133 //printf("quicktime_encode_raw %llx %llx\n", file->file_position, file->ftell_position);
134 if(depth == 32)
136 dest_cmodel = BC_ARGB8888;
139 else
141 dest_cmodel = BC_RGB888;
147 if(file->color_model != dest_cmodel)
149 if(!codec->temp_frame)
151 codec->temp_frame = malloc(cmodel_calculate_datasize(width,
152 height,
154 dest_cmodel));
155 codec->temp_rows = malloc(sizeof(unsigned char*) * height);
157 for(i = 0; i < height; i++)
159 codec->temp_rows[i] = codec->temp_frame +
160 i * cmodel_calculate_pixelsize(dest_cmodel) * width;
166 cmodel_transfer(codec->temp_rows, /* Leave NULL if non existent */
167 row_pointers,
168 0, /* Leave NULL if non existent */
171 row_pointers[0], /* Leave NULL if non existent */
172 row_pointers[1],
173 row_pointers[2],
174 0, /* Dimensions to capture from input frame */
176 width,
177 height,
178 0, /* Dimensions to project on output frame */
180 width,
181 height,
182 file->color_model,
183 dest_cmodel,
184 0, /* When transfering BC_RGBA8888 to non-alpha this is the background color in 0xRRGGBB hex */
185 width, /* For planar use the luma rowspan */
186 width); /* For planar use the luma rowspan */
188 quicktime_write_chunk_header(file, trak, &chunk_atom);
189 result = !quicktime_write_data(file, codec->temp_frame,
190 cmodel_calculate_datasize(width,
191 height,
193 dest_cmodel));
194 quicktime_write_chunk_footer(file,
195 trak,
196 vtrack->current_chunk,
197 &chunk_atom,
200 else
202 quicktime_write_chunk_header(file, trak, &chunk_atom);
203 result = !quicktime_write_data(file, row_pointers[0],
204 cmodel_calculate_datasize(width,
205 height,
207 file->color_model));
208 quicktime_write_chunk_footer(file,
209 trak,
210 vtrack->current_chunk,
211 &chunk_atom,
216 vtrack->current_chunk++;
217 return result;
220 int quicktime_raw_rows_consecutive(unsigned char **row_pointers, int w, int h, int depth)
222 int i, result;
223 /* see if row_pointers are consecutive */
224 for(i = 1, result = 1; i < h; i++)
226 if(row_pointers[i] - row_pointers[i - 1] != w * depth) result = 0;
228 return result;
231 static int reads_colormodel(quicktime_t *file,
232 int colormodel,
233 int track)
235 return (colormodel == BC_RGB888 ||
236 colormodel == BC_BGR8888);
239 void quicktime_init_codec_raw(quicktime_video_map_t *vtrack)
241 quicktime_codec_t *codec_base = (quicktime_codec_t*)vtrack->codec;
243 codec_base->priv = calloc(1, sizeof(quicktime_raw_codec_t));
244 codec_base->delete_vcodec = quicktime_delete_codec_raw;
245 codec_base->decode_video = decode;
246 codec_base->encode_video = encode;
247 codec_base->decode_audio = 0;
248 codec_base->encode_audio = 0;
249 codec_base->reads_colormodel = reads_colormodel;
250 codec_base->fourcc = QUICKTIME_RAW;
251 codec_base->title = "RGB uncompressed";
252 codec_base->desc = "RGB uncompressed";