1 #include "colormodels.h"
2 #include "funcprotos.h"
10 int compression_level;
11 unsigned char *buffer;
17 long buffer_allocated;
19 unsigned char *temp_frame;
20 } quicktime_png_codec_t;
22 static void delete_codec(quicktime_video_map_t *vtrack)
24 quicktime_png_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
25 if(codec->buffer) free(codec->buffer);
26 if(codec->temp_frame) free(codec->temp_frame);
30 static int source_cmodel(quicktime_t *file, int track)
32 int depth = quicktime_video_depth(file, track);
39 void quicktime_set_png(quicktime_t *file, int compression_level)
43 for(i = 0; i < file->total_vtracks; i++)
45 if(quicktime_match_32(quicktime_video_compressor(file, i), QUICKTIME_PNG))
47 quicktime_png_codec_t *codec = ((quicktime_codec_t*)file->vtracks[i].codec)->priv;
48 codec->compression_level = compression_level;
53 static void read_function(png_structp png_ptr, png_bytep data, png_uint_32 length)
55 quicktime_png_codec_t *codec = png_get_io_ptr(png_ptr);
57 if(length + codec->buffer_position <= codec->buffer_size)
59 memcpy(data, codec->buffer + codec->buffer_position, length);
60 codec->buffer_position += length;
64 static void write_function(png_structp png_ptr, png_bytep data, png_uint_32 length)
66 quicktime_png_codec_t *codec = png_get_io_ptr(png_ptr);
68 if(length + codec->buffer_size > codec->buffer_allocated)
70 codec->buffer_allocated += length;
71 codec->buffer = realloc(codec->buffer, codec->buffer_allocated);
73 memcpy(codec->buffer + codec->buffer_size, data, length);
74 codec->buffer_size += length;
77 static void flush_function(png_structp png_ptr)
82 static int decode(quicktime_t *file, unsigned char **row_pointers, int track)
86 quicktime_video_map_t *vtrack = &(file->vtracks[track]);
87 quicktime_trak_t *trak = vtrack->track;
90 png_infop end_info = 0;
91 int height = trak->tkhd.track_height;
92 int width = trak->tkhd.track_width;
93 quicktime_png_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
94 int cmodel = source_cmodel(file, track);
95 int use_temp = (cmodel != file->color_model ||
98 file->in_w != width ||
99 file->in_h != height ||
100 file->out_w != width ||
101 file->out_h != height);
102 unsigned char **temp_rows = malloc(sizeof(unsigned char*) * height);
106 if(!codec->temp_frame)
108 codec->temp_frame = malloc(cmodel_calculate_datasize(width,
113 for(i = 0; i < height; i++)
114 temp_rows[i] = codec->temp_frame +
115 cmodel_calculate_pixelsize(cmodel) * width * i;
119 for(i = 0; i < height; i++)
120 temp_rows[i] = row_pointers[i];
123 quicktime_set_video_position(file, vtrack->current_position, track);
124 codec->buffer_size = quicktime_frame_size(file, vtrack->current_position, track);
125 codec->buffer_position = 0;
126 if(codec->buffer_size > codec->buffer_allocated)
128 codec->buffer_allocated = codec->buffer_size;
129 codec->buffer = realloc(codec->buffer, codec->buffer_allocated);
132 result = !quicktime_read_data(file, (char*)codec->buffer, codec->buffer_size);
136 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
137 info_ptr = png_create_info_struct(png_ptr);
138 png_set_read_fn(png_ptr, codec, (png_rw_ptr)read_function);
139 png_read_info(png_ptr, info_ptr);
142 png_read_image(png_ptr, temp_rows);
143 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
148 cmodel_transfer(row_pointers,
180 static int encode(quicktime_t *file, unsigned char **row_pointers, int track)
182 //int64_t offset = quicktime_position(file);
184 quicktime_video_map_t *vtrack = &(file->vtracks[track]);
185 quicktime_trak_t *trak = vtrack->track;
186 quicktime_png_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
187 int height = trak->tkhd.track_height;
188 int width = trak->tkhd.track_width;
191 int cmodel = source_cmodel(file, track);
192 quicktime_atom_t chunk_atom;
194 codec->buffer_size = 0;
195 codec->buffer_position = 0;
197 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
198 info_ptr = png_create_info_struct(png_ptr);
199 png_set_write_fn(png_ptr,
201 (png_rw_ptr)write_function,
202 (png_flush_ptr)flush_function);
203 png_set_compression_level(png_ptr, codec->compression_level);
204 png_set_IHDR(png_ptr,
208 cmodel == BC_RGB888 ?
210 PNG_COLOR_TYPE_RGB_ALPHA,
212 PNG_COMPRESSION_TYPE_DEFAULT,
213 PNG_FILTER_TYPE_DEFAULT);
214 png_write_info(png_ptr, info_ptr);
215 png_write_image(png_ptr, row_pointers);
216 png_write_end(png_ptr, info_ptr);
217 png_destroy_write_struct(&png_ptr, &info_ptr);
219 quicktime_write_chunk_header(file, trak, &chunk_atom);
220 result = !quicktime_write_data(file, (char*) codec->buffer, codec->buffer_size);
221 quicktime_write_chunk_footer(file, trak, vtrack->current_chunk, &chunk_atom, 1);
223 vtrack->current_chunk++;
227 static int set_parameter(quicktime_t *file,
232 quicktime_video_map_t *vtrack = &(file->vtracks[track]);
233 quicktime_codec_t *codec_base = (quicktime_codec_t*)vtrack->codec;
234 quicktime_png_codec_t *codec = codec_base->priv;
236 if(!strcasecmp(key, "compression_level"))
237 codec->compression_level = *(int*)value;
241 static int reads_colormodel(quicktime_t *file,
245 return (colormodel == BC_RGB888 ||
246 colormodel == BC_BGR8888);
249 void quicktime_init_codec_png(quicktime_video_map_t *vtrack)
251 quicktime_codec_t *codec_base = (quicktime_codec_t*)vtrack->codec;
252 quicktime_png_codec_t *codec;
254 /* Init public items */
255 codec_base->priv = calloc(1, sizeof(quicktime_png_codec_t));
256 codec_base->delete_vcodec = delete_codec;
257 codec_base->decode_video = decode;
258 codec_base->encode_video = encode;
259 codec_base->decode_audio = 0;
260 codec_base->encode_audio = 0;
261 codec_base->reads_colormodel = reads_colormodel;
262 codec_base->set_parameter = set_parameter;
263 codec_base->fourcc = QUICKTIME_PNG;
264 codec_base->title = "PNG";
265 codec_base->desc = "Lossless RGB compression";
267 /* Init private items */
268 codec = codec_base->priv;
269 codec->compression_level = 9;