2 #include "bcwidgetgrid.h"
6 #include "interlacemodes.h"
11 #include "videodevice.inc"
12 #include "mainerror.h"
16 FilePNG::FilePNG(Asset_GC asset, File *file)
17 : FileList(asset, file, "PNGLIST", ".png", FILE_PNG, FILE_PNG_LIST)
27 int FilePNG::check_sig(Asset_GC asset)
29 FILE *stream = fopen(asset->path, "rb");
34 //printf("FilePNG::check_sig 1\n");
36 fread(test, 16, 1, stream);
39 if(png_check_sig((unsigned char*)test, 8))
41 //printf("FilePNG::check_sig 1\n");
45 if(test[0] == 'P' && test[1] == 'N' && test[2] == 'G' &&
46 test[3] == 'L' && test[4] == 'I' && test[5] == 'S' && test[6] == 'T')
48 //printf("FilePNG::check_sig 1\n");
57 void FilePNG::get_parameters(BC_WindowBase *parent_window,
59 BC_WindowBase* &format_window,
65 PNGConfigVideo *window = new PNGConfigVideo(parent_window, asset);
66 format_window = window;
67 window->create_objects();
76 int FilePNG::can_copy_from(Edit *edit, int64_t position)
78 if(edit->asset->format == FILE_MOV)
80 if(match4(edit->asset->vcodec, QUICKTIME_PNG)) return 1;
83 if(edit->asset->format == FILE_PNG ||
84 edit->asset->format == FILE_PNG_LIST)
91 int FilePNG::colormodel_supported(int colormodel)
93 if (((colormodel == BC_RGBA8888) && (native_cmodel == BC_RGBA16161616))
94 || ((colormodel == BC_RGB161616) && (native_cmodel == BC_RGBA16161616))
95 || (colormodel == BC_RGB888))
99 else if ((colormodel == BC_RGB161616) && (native_cmodel == BC_RGBA8888))
105 return native_cmodel;
110 int FilePNG::get_best_colormodel(Asset_GC asset, int driver)
112 if(asset->png_use_alpha)
121 int FilePNG::read_frame_header(char *path)
130 if(!(stream = fopen(path, "rb")))
132 eprintf("Error while opening \"%s\" for reading. \n%m\n", asset->path);
138 png_infop end_info = 0;
139 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
140 info_ptr = png_create_info_struct(png_ptr);
141 png_init_io(png_ptr, stream);
144 png_read_info(png_ptr, info_ptr);
146 asset->width = png_get_image_width(png_ptr, info_ptr);
147 asset->height = png_get_image_height(png_ptr, info_ptr);
149 asset->interlace_mode = BC_ILACE_MODE_NOTINTERLACED;
151 color_type = png_get_color_type(png_ptr, info_ptr);
152 color_depth = png_get_bit_depth(png_ptr,info_ptr);
154 png_get_tRNS(png_ptr, info_ptr, NULL, &num_trans, NULL);
156 if (color_depth == 16)
158 if (color_type & PNG_COLOR_MASK_ALPHA)
160 native_cmodel = BC_RGBA16161616;
164 native_cmodel = BC_RGB161616;
168 if ((color_type & PNG_COLOR_MASK_ALPHA)
171 native_cmodel = BC_RGBA8888;
175 native_cmodel = BC_RGB888;
179 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
190 static void read_function(png_structp png_ptr,
194 VFrame *input = (VFrame*)png_get_io_ptr(png_ptr);
196 memcpy(data, input->get_data() + input->get_compressed_size(), length);
197 input->set_compressed_size(input->get_compressed_size() + length);
200 static void write_function(png_structp png_ptr, png_bytep data, png_uint_32 length)
202 VFrame *output = (VFrame*)png_get_io_ptr(png_ptr);
204 if(output->get_compressed_allocated() < output->get_compressed_size() + length)
205 output->allocate_compressed_data((output->get_compressed_allocated() + length) * 2);
206 memcpy(output->get_data() + output->get_compressed_size(), data, length);
207 output->set_compressed_size(output->get_compressed_size() + length);
210 static void flush_function(png_structp png_ptr)
217 int FilePNG::write_frame(VFrame *frame, VFrame *data, FrameWriterUnit *unit)
219 PNGUnit *png_unit = (PNGUnit*)unit;
223 png_infop end_info = 0;
224 VFrame *output_frame;
225 data->set_compressed_size(0);
227 //printf("FilePNG::write_frame 1\n");
228 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
229 info_ptr = png_create_info_struct(png_ptr);
230 png_set_write_fn(png_ptr,
232 (png_rw_ptr)write_function,
233 (png_flush_ptr)flush_function);
234 png_set_compression_level(png_ptr, 9);
236 png_set_IHDR(png_ptr,
241 asset->png_use_alpha ?
242 PNG_COLOR_TYPE_RGB_ALPHA :
245 PNG_COMPRESSION_TYPE_DEFAULT,
246 PNG_FILTER_TYPE_DEFAULT);
247 png_write_info(png_ptr, info_ptr);
249 //printf("FilePNG::write_frame 1\n");
250 native_cmodel = asset->png_use_alpha ? BC_RGBA8888 : BC_RGB888;
251 if(frame->get_color_model() != native_cmodel)
253 if(!png_unit->temp_frame) png_unit->temp_frame = new VFrame(0,
258 cmodel_transfer(png_unit->temp_frame->get_rows(), /* Leave NULL if non existent */
260 png_unit->temp_frame->get_y(), /* Leave NULL if non existent */
261 png_unit->temp_frame->get_u(),
262 png_unit->temp_frame->get_v(),
263 frame->get_y(), /* Leave NULL if non existent */
266 0, /* Dimensions to capture from input frame */
270 0, /* Dimensions to project on output frame */
274 frame->get_color_model(),
275 png_unit->temp_frame->get_color_model(),
276 0, /* When transfering BC_RGBA8888 to non-alpha this is the background color in 0xRRGGBB hex */
277 asset->width, /* For planar use the luma rowspan */
280 output_frame = png_unit->temp_frame;
283 output_frame = frame;
286 //printf("FilePNG::write_frame 2\n");
287 png_write_image(png_ptr, output_frame->get_rows());
288 png_write_end(png_ptr, info_ptr);
289 png_destroy_write_struct(&png_ptr, &info_ptr);
290 //printf("FilePNG::write_frame 3 %d\n", data->get_compressed_size());
295 int FilePNG::read_frame(VFrame *output, VFrame *input)
299 png_infop end_info = 0;
304 int size = input->get_compressed_size();
305 input->set_compressed_size(0);
308 //printf("FilePNG::read_frame 1 %d %d\n", native_cmodel, output->get_color_model());
309 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
310 info_ptr = png_create_info_struct(png_ptr);
311 png_set_read_fn(png_ptr, input, (png_rw_ptr)read_function);
312 png_read_info(png_ptr, info_ptr);
314 int png_color_type = png_get_color_type(png_ptr, info_ptr);
315 if (png_color_type == PNG_COLOR_TYPE_GRAY ||
316 png_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
318 png_set_gray_to_rgb(png_ptr);
321 colormodel = output->get_color_model();
322 color_type = png_get_color_type(png_ptr, info_ptr);
323 color_depth = png_get_bit_depth(png_ptr,info_ptr);
325 if (((native_cmodel == BC_RGBA16161616)||(native_cmodel == BC_RGB161616))
326 && ((colormodel == BC_RGBA8888)||(colormodel == BC_RGB888)))
328 png_set_strip_16(png_ptr);
331 /* If we're dropping the alpha channel, use the background color of the image
332 otherwise, use black */
333 if (((native_cmodel == BC_RGBA16161616)||(native_cmodel == BC_RGBA8888))
334 && ((colormodel == BC_RGB161616)||(colormodel == BC_RGB888)))
336 png_color_16 my_background;
337 png_color_16p image_background;
339 memset(&my_background,0,sizeof(png_color_16));
341 if (png_get_bKGD(png_ptr, info_ptr, &image_background))
343 png_set_background(png_ptr, image_background, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
347 png_set_background(png_ptr, &my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
352 if ((color_depth == 16)
353 &&((colormodel == BC_RGBA16161616)||(colormodel == BC_RGB161616)))
355 png_set_swap(png_ptr);
358 if (!(color_type & PNG_COLOR_MASK_COLOR))
360 png_set_gray_to_rgb(png_ptr);
363 if (color_type & PNG_COLOR_MASK_PALETTE)
365 png_set_palette_to_rgb(png_ptr);
368 if (color_depth <= 8)
370 png_set_expand(png_ptr);
374 png_read_image(png_ptr, output->get_rows());
375 //printf("FilePNG::read_frame 3\n");
376 png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
378 input->set_compressed_size(size);
380 //printf("FilePNG::read_frame 4\n");
384 FrameWriterUnit* FilePNG::new_writer_unit(FrameWriter *writer)
386 return new PNGUnit(this, writer);
400 PNGUnit::PNGUnit(FilePNG *file, FrameWriter *writer)
401 : FrameWriterUnit(writer)
408 if(temp_frame) delete temp_frame;
419 PNGConfigVideo::PNGConfigVideo(BC_WindowBase *parent_window, Asset_GC asset)
420 : BC_Window(PROGRAM_NAME ": Video Compression",
421 parent_window->get_abs_cursor_x(1),
422 parent_window->get_abs_cursor_y(1),
430 this->parent_window = parent_window;
434 PNGConfigVideo::~PNGConfigVideo()
438 int PNGConfigVideo::create_objects()
443 BC_RelocatableWidget *rw;
445 wg = add_widgetgrid(new BC_WidgetGrid(10, 10, 10, 10, 3, 3));
448 add_subwindow(new PNGUseAlpha(this, x, y));
452 add_subwindow(new BC_OKButton(this));
455 resize_window(wg->get_w_wm(), wg->get_h_wm() + rw->get_h());
459 int PNGConfigVideo::close_event()
466 PNGUseAlpha::PNGUseAlpha(PNGConfigVideo *gui, int x, int y)
467 : BC_CheckBox(x, y, gui->asset->png_use_alpha, _("Use alpha"))
472 int PNGUseAlpha::handle_event()
474 gui->asset->png_use_alpha = get_value();
483 // c-file-style: "linux"