Merge branch 'ct' of git.pipapo.org:cinelerra-ct into ct
[cinelerra_cv/ct.git] / quicktime / rle.c
blobf34d508265f0034a849b1fd1b62158ec26be5db5
1 /* RLE codec */
3 #include "colormodels.h"
4 #include "funcprotos.h"
5 #include "quicktime.h"
8 typedef struct
10 unsigned char *work_buffer;
11 int buffer_size;
12 unsigned char *output_temp;
13 } quicktime_rle_codec_t;
16 static int delete_codec(quicktime_video_map_t *vtrack)
18 quicktime_rle_codec_t *codec;
19 codec = ((quicktime_codec_t*)vtrack->codec)->priv;
20 if(codec->work_buffer) free(codec->work_buffer);
21 if(codec->output_temp) free(codec->output_temp);
22 free(codec);
25 static int reads_colormodel(quicktime_t *file,
26 int colormodel,
27 int track)
29 return (colormodel == BC_RGB888);
32 static int source_cmodel(quicktime_t *file, int track)
34 int depth = quicktime_video_depth(file, track);
35 if(depth == 24)
36 return BC_RGB888;
37 else
38 return BC_ARGB8888;
43 static int decode(quicktime_t *file, unsigned char **row_pointers, int track)
45 quicktime_video_map_t *vtrack = &(file->vtracks[track]);
46 quicktime_trak_t *trak = vtrack->track;
47 quicktime_rle_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
48 int depth = quicktime_video_depth(file, track);
49 int width = trak->tkhd.track_width;
50 int height = trak->tkhd.track_height;
51 int size;
52 int result = 0;
53 unsigned char *ptr;
54 int start_line;
55 int total_lines;
56 int header;
57 int row_bytes;
58 int pixel_size;
59 unsigned char *row_ptr;
60 unsigned char *pixel;
61 unsigned char *buffer_end;
62 int code;
63 int r, g, b, i;
64 int need_temp;
65 unsigned char **temp_rows = malloc(sizeof(unsigned char*) * height);
66 int cmodel = source_cmodel(file, track);
67 int skip;
69 quicktime_set_video_position(file, vtrack->current_position, track);
70 size = quicktime_frame_size(file, vtrack->current_position, track);
71 row_bytes = depth / 8 * width;
72 pixel_size = depth / 8;
74 if(size <= 8) return 0;
75 if(codec->buffer_size < size && codec->work_buffer)
77 free(codec->work_buffer);
78 codec->work_buffer = 0;
80 if(!codec->work_buffer)
82 codec->work_buffer = malloc(size);
83 codec->buffer_size = size;
86 if(!quicktime_read_data(file,
87 codec->work_buffer,
88 size))
89 result = -1;
91 ptr = codec->work_buffer;
92 buffer_end = ptr + size;
94 // Chunk size
95 ptr += 4;
97 // Header
98 header = (ptr[0] << 8) | ptr[1];
99 ptr += 2;
101 // Incremental change
102 if(header & 0x0008)
104 start_line = (ptr[0] << 8) | ptr[1];
105 ptr += 4;
106 total_lines = (ptr[0] << 8) | ptr[1];
107 ptr += 4;
109 else
110 // Keyframe
112 start_line = 0;
113 total_lines = height;
117 if(cmodel != file->color_model ||
118 file->in_x != 0 ||
119 file->in_y != 0 ||
120 file->in_w != width ||
121 file->in_h != height ||
122 file->out_w != width ||
123 file->out_h != height)
124 need_temp = 1;
126 if(need_temp)
128 if(!codec->output_temp)
129 codec->output_temp = calloc(1, height * row_bytes);
130 row_ptr = codec->output_temp + start_line * row_bytes;
131 for(i = 0; i < height; i++)
132 temp_rows[i] = codec->output_temp + i * row_bytes;
134 else
136 row_ptr = row_pointers[start_line];
137 for(i = 0; i < height; i++)
138 temp_rows[i] = row_pointers[i];
141 switch(depth)
143 case 24:
144 while(total_lines--)
146 skip = *ptr++;
147 pixel = row_ptr + (skip - 1) * pixel_size;
149 while(ptr < buffer_end &&
150 (code = (char)*ptr++) != -1)
152 if(code == 0)
154 // Skip code
155 pixel += (*ptr++ - 1) * pixel_size;
157 else
158 // Run length encoded
159 if(code < 0)
161 code *= -1;
162 r = *ptr++;
163 g = *ptr++;
164 b = *ptr++;
165 while(code--)
167 *pixel++ = r;
168 *pixel++ = g;
169 *pixel++ = b;
172 else
173 // Uncompressed
175 while(code--)
177 *pixel++ = *ptr++;
178 *pixel++ = *ptr++;
179 *pixel++ = *ptr++;
185 row_ptr += row_bytes;
187 break;
191 if(need_temp)
193 cmodel_transfer(row_pointers,
194 temp_rows,
195 row_pointers[0],
196 row_pointers[1],
197 row_pointers[2],
201 file->in_x,
202 file->in_y,
203 file->in_w,
204 file->in_h,
207 file->out_w,
208 file->out_h,
209 cmodel,
210 file->color_model,
212 width,
213 file->out_w);
216 free(temp_rows);
218 return 0;
223 void quicktime_init_codec_rle(quicktime_video_map_t *vtrack)
225 quicktime_codec_t *codec_base = (quicktime_codec_t*)vtrack->codec;
226 quicktime_rle_codec_t *codec;
227 codec_base->priv = calloc(1, sizeof(quicktime_rle_codec_t));
228 codec_base->delete_vcodec = delete_codec;
229 codec_base->decode_video = decode;
230 codec_base->reads_colormodel = reads_colormodel;
231 codec_base->fourcc = "rle ";
232 codec_base->title = "RLE";
233 codec_base->desc = "Run length encoding";
235 codec = (quicktime_rle_codec_t*)codec_base->priv;