1 #include "colormodels.h"
2 #include "funcprotos.h"
10 unsigned char *buffer
;
16 long buffer_allocated
;
18 unsigned char *temp_frame
;
19 } quicktime_png_codec_t
;
21 static int delete_codec(quicktime_video_map_t
*vtrack
)
23 quicktime_png_codec_t
*codec
= ((quicktime_codec_t
*)vtrack
->codec
)->priv
;
24 if(codec
->buffer
) free(codec
->buffer
);
25 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
)
44 for(i
= 0; i
< file
->total_vtracks
; i
++)
46 if(quicktime_match_32(quicktime_video_compressor(file
, i
), QUICKTIME_PNG
))
48 quicktime_png_codec_t
*codec
= ((quicktime_codec_t
*)file
->vtracks
[i
].codec
)->priv
;
49 codec
->compression_level
= compression_level
;
54 static void read_function(png_structp png_ptr
, png_bytep data
, png_uint_32 length
)
56 quicktime_png_codec_t
*codec
= png_get_io_ptr(png_ptr
);
58 if(length
+ codec
->buffer_position
<= codec
->buffer_size
)
60 memcpy(data
, codec
->buffer
+ codec
->buffer_position
, length
);
61 codec
->buffer_position
+= length
;
65 static void write_function(png_structp png_ptr
, png_bytep data
, png_uint_32 length
)
67 quicktime_png_codec_t
*codec
= png_get_io_ptr(png_ptr
);
69 if(length
+ codec
->buffer_size
> codec
->buffer_allocated
)
71 codec
->buffer_allocated
+= length
;
72 codec
->buffer
= realloc(codec
->buffer
, codec
->buffer_allocated
);
74 memcpy(codec
->buffer
+ codec
->buffer_size
, data
, length
);
75 codec
->buffer_size
+= length
;
78 static void flush_function(png_structp png_ptr
)
83 static int decode(quicktime_t
*file
, unsigned char **row_pointers
, int track
)
87 quicktime_video_map_t
*vtrack
= &(file
->vtracks
[track
]);
88 quicktime_trak_t
*trak
= vtrack
->track
;
91 png_infop end_info
= 0;
92 int height
= trak
->tkhd
.track_height
;
93 int width
= trak
->tkhd
.track_width
;
94 quicktime_png_codec_t
*codec
= ((quicktime_codec_t
*)vtrack
->codec
)->priv
;
95 int cmodel
= source_cmodel(file
, track
);
96 int use_temp
= (cmodel
!= file
->color_model
||
99 file
->in_w
!= width
||
100 file
->in_h
!= height
||
101 file
->out_w
!= width
||
102 file
->out_h
!= height
);
103 unsigned char **temp_rows
= malloc(sizeof(unsigned char*) * height
);
107 if(!codec
->temp_frame
)
109 codec
->temp_frame
= malloc(cmodel_calculate_datasize(width
,
114 for(i
= 0; i
< height
; i
++)
115 temp_rows
[i
] = codec
->temp_frame
+
116 cmodel_calculate_pixelsize(cmodel
) * width
* i
;
120 for(i
= 0; i
< height
; i
++)
121 temp_rows
[i
] = row_pointers
[i
];
124 quicktime_set_video_position(file
, vtrack
->current_position
, track
);
125 codec
->buffer_size
= quicktime_frame_size(file
, vtrack
->current_position
, track
);
126 codec
->buffer_position
= 0;
127 if(codec
->buffer_size
> codec
->buffer_allocated
)
129 codec
->buffer_allocated
= codec
->buffer_size
;
130 codec
->buffer
= realloc(codec
->buffer
, codec
->buffer_allocated
);
133 result
= !quicktime_read_data(file
, codec
->buffer
, codec
->buffer_size
);
137 png_ptr
= png_create_read_struct(PNG_LIBPNG_VER_STRING
, 0, 0, 0);
138 info_ptr
= png_create_info_struct(png_ptr
);
139 png_set_read_fn(png_ptr
, codec
, (png_rw_ptr
)read_function
);
140 png_read_info(png_ptr
, info_ptr
);
143 png_read_image(png_ptr
, temp_rows
);
144 png_destroy_read_struct(&png_ptr
, &info_ptr
, &end_info
);
149 cmodel_transfer(row_pointers
,
181 static int encode(quicktime_t
*file
, unsigned char **row_pointers
, int track
)
183 int64_t offset
= quicktime_position(file
);
186 quicktime_video_map_t
*vtrack
= &(file
->vtracks
[track
]);
187 quicktime_trak_t
*trak
= vtrack
->track
;
188 quicktime_png_codec_t
*codec
= ((quicktime_codec_t
*)vtrack
->codec
)->priv
;
189 int height
= trak
->tkhd
.track_height
;
190 int width
= trak
->tkhd
.track_width
;
193 int cmodel
= source_cmodel(file
, track
);
194 quicktime_atom_t chunk_atom
;
196 codec
->buffer_size
= 0;
197 codec
->buffer_position
= 0;
199 png_ptr
= png_create_write_struct(PNG_LIBPNG_VER_STRING
, 0, 0, 0);
200 info_ptr
= png_create_info_struct(png_ptr
);
201 png_set_write_fn(png_ptr
,
203 (png_rw_ptr
)write_function
,
204 (png_flush_ptr
)flush_function
);
205 png_set_compression_level(png_ptr
, codec
->compression_level
);
206 png_set_IHDR(png_ptr
,
210 cmodel
== BC_RGB888
?
212 PNG_COLOR_TYPE_RGB_ALPHA
,
214 PNG_COMPRESSION_TYPE_DEFAULT
,
215 PNG_FILTER_TYPE_DEFAULT
);
216 png_write_info(png_ptr
, info_ptr
);
217 png_write_image(png_ptr
, row_pointers
);
218 png_write_end(png_ptr
, info_ptr
);
219 png_destroy_write_struct(&png_ptr
, &info_ptr
);
221 quicktime_write_chunk_header(file
, trak
, &chunk_atom
);
222 result
= !quicktime_write_data(file
,
225 quicktime_write_chunk_footer(file
,
227 vtrack
->current_chunk
,
231 vtrack
->current_chunk
++;
235 static int set_parameter(quicktime_t
*file
,
240 quicktime_video_map_t
*vtrack
= &(file
->vtracks
[track
]);
241 quicktime_codec_t
*codec_base
= (quicktime_codec_t
*)vtrack
->codec
;
242 quicktime_png_codec_t
*codec
= codec_base
->priv
;
244 if(!strcasecmp(key
, "compression_level"))
245 codec
->compression_level
= *(int*)value
;
248 static int reads_colormodel(quicktime_t
*file
,
252 return (colormodel
== BC_RGB888
||
253 colormodel
== BC_BGR8888
);
256 void quicktime_init_codec_png(quicktime_video_map_t
*vtrack
)
258 quicktime_codec_t
*codec_base
= (quicktime_codec_t
*)vtrack
->codec
;
259 quicktime_png_codec_t
*codec
;
261 /* Init public items */
262 codec_base
->priv
= calloc(1, sizeof(quicktime_png_codec_t
));
263 codec_base
->delete_vcodec
= delete_codec
;
264 codec_base
->decode_video
= decode
;
265 codec_base
->encode_video
= encode
;
266 codec_base
->decode_audio
= 0;
267 codec_base
->encode_audio
= 0;
268 codec_base
->reads_colormodel
= reads_colormodel
;
269 codec_base
->set_parameter
= set_parameter
;
270 codec_base
->fourcc
= QUICKTIME_PNG
;
271 codec_base
->title
= "PNG";
272 codec_base
->desc
= "Lossless RGB compression";
274 /* Init private items */
275 codec
= codec_base
->priv
;
276 codec
->compression_level
= 9;