r125: This commit was manufactured by cvs2svn to create tag 'r1_1_7-last'.
[cinelerra_cv/mob.git] / hvirtual / cinelerra / filepng.C
blob73739e22aeb523d944acf397cf9203cec00b5987
1 #include "assets.h"
2 #include "edit.h"
3 #include "file.h"
4 #include "filepng.h"
5 #include "mwindow.inc"
6 #include "quicktime.h"
7 #include "vframe.h"
8 #include "videodevice.inc"
10 #include <png.h>
11 #include <libintl.h>
12 #define _(String) gettext(String)
13 #define gettext_noop(String) String
14 #define N_(String) gettext_noop (String)
16 FilePNG::FilePNG(Asset *asset, File *file)
17  : FileList(asset, file, "PNGLIST", ".png", FILE_PNG, FILE_PNG_LIST)
19         temp = 0;
22 FilePNG::~FilePNG()
24         if(temp) delete temp;
29 int FilePNG::check_sig(Asset *asset)
31         FILE *stream = fopen(asset->path, "rb");
33         if(stream)
34         {
36 //printf("FilePNG::check_sig 1\n");
37                 char test[16];
38                 fread(test, 16, 1, stream);
39                 fclose(stream);
41                 if(png_check_sig((unsigned char*)test, 8))
42                 {
43 //printf("FilePNG::check_sig 1\n");
44                         return 1;
45                 }
46                 else
47                 if(test[0] == 'P' && test[1] == 'N' && test[2] == 'G' && 
48                         test[3] == 'L' && test[4] == 'I' && test[5] == 'S' && test[6] == 'T')
49                 {
50 //printf("FilePNG::check_sig 1\n");
51                         return 1;
52                 }
53         }
54         return 0;
59 void FilePNG::get_parameters(BC_WindowBase *parent_window, 
60         Asset *asset, 
61         BC_WindowBase* &format_window,
62         int audio_options,
63         int video_options)
65         if(video_options)
66         {
67                 PNGConfigVideo *window = new PNGConfigVideo(parent_window, asset);
68                 format_window = window;
69                 window->create_objects();
70                 window->run_window();
71                 delete window;
72         }
78 int FilePNG::can_copy_from(Edit *edit, int64_t position)
80         if(edit->asset->format == FILE_MOV)
81         {
82                 if(match4(edit->asset->vcodec, QUICKTIME_PNG)) return 1;
83         }
84         else
85         if(edit->asset->format == FILE_PNG || 
86                 edit->asset->format == FILE_PNG_LIST)
87                 return 1;
89         return 0;
93 int FilePNG::colormodel_supported(int colormodel)
95         return native_cmodel;
99 int FilePNG::get_best_colormodel(Asset *asset, int driver)
101         if(asset->png_use_alpha)
102                 return BC_RGBA8888;
103         else
104                 return BC_RGB888;
110 int FilePNG::read_frame_header(char *path)
112         int result = 0;
115 //printf("FilePNG::read_frame_header 1\n");
116         FILE *stream;
118         if(!(stream = fopen(path, "rb")))
119         {
120                 perror("FilePNG::read_frame_header");
121                 return 1;
122         }
124 //printf("FilePNG::read_frame_header 1\n");
125         png_structp png_ptr;
126         png_infop info_ptr;
127         png_infop end_info = 0; 
128         png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
129         info_ptr = png_create_info_struct(png_ptr);
130         png_init_io(png_ptr, stream);
132 //printf("FilePNG::read_frame_header 1\n");
134         png_read_info(png_ptr, info_ptr);
136 //printf("FilePNG::read_frame_header 1\n");
137         asset->width = png_get_image_width(png_ptr, info_ptr);
138         asset->height = png_get_image_height(png_ptr, info_ptr);
139         native_cmodel = 
140                 png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_RGB_ALPHA ?
141                 BC_RGBA8888 :
142                 BC_RGB888;
144 //printf("FilePNG::read_frame_header 1\n");
145         png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
146 //printf("FilePNG::read_frame_header 1\n");
147         fclose(stream);
148         
149 //printf("FilePNG::read_frame_header 2\n");
150         
151         
152         return result;
158 static void read_function(png_structp png_ptr, 
159         png_bytep data, 
160         png_uint_32 length)
162         VFrame *input = (VFrame*)png_get_io_ptr(png_ptr);
164 //printf("read_function 1\n");
165         memcpy(data, input->get_data() + input->get_compressed_size(), length);
166 //printf("read_function 1\n");
167         input->set_compressed_size(input->get_compressed_size() + length);
168 //printf("read_function 2\n");
171 static void write_function(png_structp png_ptr, png_bytep data, png_uint_32 length)
173         VFrame *output = (VFrame*)png_get_io_ptr(png_ptr);
175         if(output->get_compressed_allocated() < output->get_compressed_size() + length)
176                 output->allocate_compressed_data((output->get_compressed_allocated() + length) * 2);
177         memcpy(output->get_data() + output->get_compressed_size(), data, length);
178         output->set_compressed_size(output->get_compressed_size() + length);
179 //printf("write_function %d %d\n", output->get_compressed_size(), length);
182 static void flush_function(png_structp png_ptr)
184         ;
189 int FilePNG::write_frame(VFrame *frame, VFrame *data, FrameWriterUnit *unit)
191         PNGUnit *png_unit = (PNGUnit*)unit;
192         int result = 0;
193         png_structp png_ptr;
194         png_infop info_ptr;
195         png_infop end_info = 0; 
196         VFrame *output_frame;
197         data->set_compressed_size(0);
199 //printf("FilePNG::write_frame 1\n");
200         png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
201         info_ptr = png_create_info_struct(png_ptr);
202         png_set_write_fn(png_ptr,
203                data, 
204                            (png_rw_ptr)write_function,
205                (png_flush_ptr)flush_function);
206         png_set_compression_level(png_ptr, 9);
208         png_set_IHDR(png_ptr, 
209                 info_ptr, 
210                 asset->width, 
211                 asset->height,
212         8, 
213                 asset->png_use_alpha ? 
214                   PNG_COLOR_TYPE_RGB_ALPHA : 
215                   PNG_COLOR_TYPE_RGB, 
216                 PNG_INTERLACE_NONE, 
217                 PNG_COMPRESSION_TYPE_DEFAULT, 
218                 PNG_FILTER_TYPE_DEFAULT);
219         png_write_info(png_ptr, info_ptr);
221 //printf("FilePNG::write_frame 1\n");
222         native_cmodel = asset->png_use_alpha ? BC_RGBA8888 : BC_RGB888;
223         if(frame->get_color_model() != native_cmodel)
224         {
225                 if(!png_unit->temp_frame) png_unit->temp_frame = new VFrame(0, asset->width, asset->height, native_cmodel);
227                 cmodel_transfer(png_unit->temp_frame->get_rows(), /* Leave NULL if non existent */
228                         frame->get_rows(),
229                         png_unit->temp_frame->get_y(), /* Leave NULL if non existent */
230                         png_unit->temp_frame->get_u(),
231                         png_unit->temp_frame->get_v(),
232                         frame->get_y(), /* Leave NULL if non existent */
233                         frame->get_u(),
234                         frame->get_v(),
235                         0,        /* Dimensions to capture from input frame */
236                         0, 
237                         asset->width, 
238                         asset->height,
239                         0,       /* Dimensions to project on output frame */
240                         0, 
241                         asset->width, 
242                         asset->height,
243                         frame->get_color_model(), 
244                         png_unit->temp_frame->get_color_model(),
245                         0,         /* When transfering BC_RGBA8888 to non-alpha this is the background color in 0xRRGGBB hex */
246                         asset->width,       /* For planar use the luma rowspan */
247                         asset->height);
248                 
249                 output_frame = png_unit->temp_frame;
250         }
251         else
252                 output_frame = frame;
255 //printf("FilePNG::write_frame 2\n");
256         png_write_image(png_ptr, output_frame->get_rows());
257         png_write_end(png_ptr, info_ptr);
258         png_destroy_write_struct(&png_ptr, &info_ptr);
259 //printf("FilePNG::write_frame 3 %d\n", data->get_compressed_size());
261         return result;
264 int FilePNG::read_frame(VFrame *output, VFrame *input)
266         png_structp png_ptr;
267         png_infop info_ptr;
268         png_infop end_info = 0; 
269         int result = 0;
270         int size = input->get_compressed_size();
271         input->set_compressed_size(0);
272         
276 //printf("FilePNG::read_frame 1 %d %d\n", native_cmodel, output->get_color_model());
277         png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
278         info_ptr = png_create_info_struct(png_ptr);
279         png_set_read_fn(png_ptr, input, (png_rw_ptr)read_function);
280         png_read_info(png_ptr, info_ptr);
281 //printf("FilePNG::read_frame 2 %d\n", output->get_color_model());
283 /* read the image */
284         png_read_image(png_ptr, output->get_rows());
285 //printf("FilePNG::read_frame 3\n");
286         png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
288         input->set_compressed_size(size);
290 //printf("FilePNG::read_frame 4\n");
291         return result;
294 FrameWriterUnit* FilePNG::new_writer_unit(FrameWriter *writer)
296         return new PNGUnit(this, writer);
310 PNGUnit::PNGUnit(FilePNG *file, FrameWriter *writer)
311  : FrameWriterUnit(writer)
313         this->file = file;
314         temp_frame = 0;
316 PNGUnit::~PNGUnit()
318         if(temp_frame) delete temp_frame;
329 PNGConfigVideo::PNGConfigVideo(BC_WindowBase *parent_window, Asset *asset)
330  : BC_Window(PROGRAM_NAME ": Video Compression",
331         parent_window->get_abs_cursor_x(),
332         parent_window->get_abs_cursor_y(),
333         400,
334         100)
336         this->parent_window = parent_window;
337         this->asset = asset;
340 PNGConfigVideo::~PNGConfigVideo()
344 int PNGConfigVideo::create_objects()
346         int x = 10, y = 10;
347         add_subwindow(new PNGUseAlpha(this, x, y));
348         add_subwindow(new BC_OKButton(this));
349         return 0;
352 int PNGConfigVideo::close_event()
354         set_done(0);
355         return 1;
359 PNGUseAlpha::PNGUseAlpha(PNGConfigVideo *gui, int x, int y)
360  : BC_CheckBox(x, y, gui->asset->png_use_alpha, _("Use alpha"))
362         this->gui = gui;
365 int PNGUseAlpha::handle_event()
367         gui->asset->png_use_alpha = get_value();
368         return 1;