Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

filepng.C

Go to the documentation of this file.
00001 #include "asset.h"
00002 #include "edit.h"
00003 #include "file.h"
00004 #include "filepng.h"
00005 #include "interlacemodes.h"
00006 #include "language.h"
00007 #include "mwindow.inc"
00008 #include "quicktime.h"
00009 #include "vframe.h"
00010 #include "videodevice.inc"
00011 
00012 #include <png.h>
00013 
00014 FilePNG::FilePNG(Asset *asset, File *file)
00015  : FileList(asset, file, "PNGLIST", ".png", FILE_PNG, FILE_PNG_LIST)
00016 {
00017 }
00018 
00019 FilePNG::~FilePNG()
00020 {
00021 }
00022 
00023 
00024 
00025 int FilePNG::check_sig(Asset *asset)
00026 {
00027         FILE *stream = fopen(asset->path, "rb");
00028 
00029         if(stream)
00030         {
00031 
00032 //printf("FilePNG::check_sig 1\n");
00033                 char test[16];
00034                 fread(test, 16, 1, stream);
00035                 fclose(stream);
00036 
00037                 if(png_check_sig((unsigned char*)test, 8))
00038                 {
00039 //printf("FilePNG::check_sig 1\n");
00040                         return 1;
00041                 }
00042                 else
00043                 if(test[0] == 'P' && test[1] == 'N' && test[2] == 'G' && 
00044                         test[3] == 'L' && test[4] == 'I' && test[5] == 'S' && test[6] == 'T')
00045                 {
00046 //printf("FilePNG::check_sig 1\n");
00047                         return 1;
00048                 }
00049         }
00050         return 0;
00051 }
00052 
00053 
00054 
00055 void FilePNG::get_parameters(BC_WindowBase *parent_window, 
00056         Asset *asset, 
00057         BC_WindowBase* &format_window,
00058         int audio_options,
00059         int video_options)
00060 {
00061         if(video_options)
00062         {
00063                 PNGConfigVideo *window = new PNGConfigVideo(parent_window, asset);
00064                 format_window = window;
00065                 window->create_objects();
00066                 window->run_window();
00067                 delete window;
00068         }
00069 }
00070 
00071 
00072 
00073 
00074 int FilePNG::can_copy_from(Edit *edit, int64_t position)
00075 {
00076         if(edit->asset->format == FILE_MOV)
00077         {
00078                 if(match4(edit->asset->vcodec, QUICKTIME_PNG)) return 1;
00079         }
00080         else
00081         if(edit->asset->format == FILE_PNG || 
00082                 edit->asset->format == FILE_PNG_LIST)
00083                 return 1;
00084 
00085         return 0;
00086 }
00087 
00088 
00089 int FilePNG::colormodel_supported(int colormodel)
00090 {
00091         if (((colormodel == BC_RGBA8888) && (native_cmodel == BC_RGBA16161616))
00092             || ((colormodel == BC_RGB161616) && (native_cmodel == BC_RGBA16161616))
00093             || (colormodel == BC_RGB888))
00094         {
00095             return colormodel;
00096         }
00097         else if ((colormodel == BC_RGB161616) && (native_cmodel == BC_RGBA8888))
00098         {
00099             return BC_RGB888;
00100         }
00101         else
00102         {
00103             return native_cmodel;
00104         }
00105 }
00106 
00107 
00108 int FilePNG::get_best_colormodel(Asset *asset, int driver)
00109 {
00110         if(asset->png_use_alpha)
00111                 return BC_RGBA8888;
00112         else
00113                 return BC_RGB888;
00114 }
00115 
00116 
00117 
00118 
00119 int FilePNG::read_frame_header(char *path)
00120 {
00121         int result = 0;
00122         int color_type;
00123         int color_depth;
00124         int num_trans = 0;
00125         
00126         FILE *stream;
00127 
00128         if(!(stream = fopen(path, "rb")))
00129         {
00130                 perror("FilePNG::read_frame_header");
00131                 return 1;
00132         }
00133 
00134         png_structp png_ptr;
00135         png_infop info_ptr;
00136         png_infop end_info = 0; 
00137         png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
00138         info_ptr = png_create_info_struct(png_ptr);
00139         png_init_io(png_ptr, stream);
00140 
00141 
00142         png_read_info(png_ptr, info_ptr);
00143 
00144         asset->width = png_get_image_width(png_ptr, info_ptr);
00145         asset->height = png_get_image_height(png_ptr, info_ptr);
00146         
00147         asset->interlace_mode = BC_ILACE_MODE_NOTINTERLACED;
00148 
00149         color_type = png_get_color_type(png_ptr, info_ptr);
00150         color_depth = png_get_bit_depth(png_ptr,info_ptr);
00151         
00152         png_get_tRNS(png_ptr, info_ptr, NULL, &num_trans, NULL);
00153         
00154         if (color_depth == 16)
00155         {
00156             if (color_type & PNG_COLOR_MASK_ALPHA)
00157             {
00158                 native_cmodel = BC_RGBA16161616;
00159             }
00160             else
00161             {
00162                 native_cmodel = BC_RGB161616;
00163             }
00164         }
00165         else 
00166         if ((color_type & PNG_COLOR_MASK_ALPHA)
00167             || (num_trans > 0))
00168         {
00169             native_cmodel = BC_RGBA8888;
00170         }
00171         else
00172         {
00173             native_cmodel = BC_RGB888;
00174         }
00175 
00176 
00177         png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
00178         fclose(stream);
00179         
00180         
00181         
00182         return result;
00183 }
00184 
00185 
00186 
00187 
00188 static void read_function(png_structp png_ptr, 
00189         png_bytep data, 
00190         png_uint_32 length)
00191 {
00192         VFrame *input = (VFrame*)png_get_io_ptr(png_ptr);
00193 
00194         memcpy(data, input->get_data() + input->get_compressed_size(), length);
00195         input->set_compressed_size(input->get_compressed_size() + length);
00196 }
00197 
00198 static void write_function(png_structp png_ptr, png_bytep data, png_uint_32 length)
00199 {
00200         VFrame *output = (VFrame*)png_get_io_ptr(png_ptr);
00201 
00202         if(output->get_compressed_allocated() < output->get_compressed_size() + length)
00203                 output->allocate_compressed_data((output->get_compressed_allocated() + length) * 2);
00204         memcpy(output->get_data() + output->get_compressed_size(), data, length);
00205         output->set_compressed_size(output->get_compressed_size() + length);
00206 }
00207 
00208 static void flush_function(png_structp png_ptr)
00209 {
00210         ;
00211 }
00212 
00213 
00214 
00215 int FilePNG::write_frame(VFrame *frame, VFrame *data, FrameWriterUnit *unit)
00216 {
00217         PNGUnit *png_unit = (PNGUnit*)unit;
00218         int result = 0;
00219         png_structp png_ptr;
00220         png_infop info_ptr;
00221         png_infop end_info = 0; 
00222         VFrame *output_frame;
00223         data->set_compressed_size(0);
00224 
00225 //printf("FilePNG::write_frame 1\n");
00226         png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
00227         info_ptr = png_create_info_struct(png_ptr);
00228         png_set_write_fn(png_ptr,
00229                data, 
00230                            (png_rw_ptr)write_function,
00231                (png_flush_ptr)flush_function);
00232         png_set_compression_level(png_ptr, 9);
00233 
00234         png_set_IHDR(png_ptr, 
00235                 info_ptr, 
00236                 asset->width, 
00237                 asset->height,
00238         8, 
00239                 asset->png_use_alpha ? 
00240                   PNG_COLOR_TYPE_RGB_ALPHA : 
00241                   PNG_COLOR_TYPE_RGB, 
00242                 PNG_INTERLACE_NONE, 
00243                 PNG_COMPRESSION_TYPE_DEFAULT, 
00244                 PNG_FILTER_TYPE_DEFAULT);
00245         png_write_info(png_ptr, info_ptr);
00246 
00247 //printf("FilePNG::write_frame 1\n");
00248         native_cmodel = asset->png_use_alpha ? BC_RGBA8888 : BC_RGB888;
00249         if(frame->get_color_model() != native_cmodel)
00250         {
00251                 if(!png_unit->temp_frame) png_unit->temp_frame = new VFrame(0, 
00252                         asset->width, 
00253                         asset->height, 
00254                         native_cmodel);
00255 
00256                 cmodel_transfer(png_unit->temp_frame->get_rows(), /* Leave NULL if non existent */
00257                         frame->get_rows(),
00258                         png_unit->temp_frame->get_y(), /* Leave NULL if non existent */
00259                         png_unit->temp_frame->get_u(),
00260                         png_unit->temp_frame->get_v(),
00261                         frame->get_y(), /* Leave NULL if non existent */
00262                         frame->get_u(),
00263                         frame->get_v(),
00264                         0,        /* Dimensions to capture from input frame */
00265                         0, 
00266                         asset->width, 
00267                         asset->height,
00268                         0,       /* Dimensions to project on output frame */
00269                         0, 
00270                         asset->width, 
00271                         asset->height,
00272                         frame->get_color_model(), 
00273                         png_unit->temp_frame->get_color_model(),
00274                         0,         /* When transfering BC_RGBA8888 to non-alpha this is the background color in 0xRRGGBB hex */
00275                         asset->width,       /* For planar use the luma rowspan */
00276                         asset->height);
00277                 
00278                 output_frame = png_unit->temp_frame;
00279         }
00280         else
00281                 output_frame = frame;
00282 
00283 
00284 //printf("FilePNG::write_frame 2\n");
00285         png_write_image(png_ptr, output_frame->get_rows());
00286         png_write_end(png_ptr, info_ptr);
00287         png_destroy_write_struct(&png_ptr, &info_ptr);
00288 //printf("FilePNG::write_frame 3 %d\n", data->get_compressed_size());
00289 
00290         return result;
00291 }
00292 
00293 int FilePNG::read_frame(VFrame *output, VFrame *input)
00294 {
00295         png_structp png_ptr;
00296         png_infop info_ptr;
00297         png_infop end_info = 0; 
00298         int result = 0;
00299         int color_type;
00300         int color_depth;
00301         int colormodel;
00302         int size = input->get_compressed_size();
00303         input->set_compressed_size(0);
00304         
00305         
00306         //printf("FilePNG::read_frame 1 %d %d\n", native_cmodel, output->get_color_model());
00307         png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
00308         info_ptr = png_create_info_struct(png_ptr);
00309         png_set_read_fn(png_ptr, input, (png_rw_ptr)read_function);
00310         png_read_info(png_ptr, info_ptr);
00311 
00312         int png_color_type = png_get_color_type(png_ptr, info_ptr);
00313         if (png_color_type == PNG_COLOR_TYPE_GRAY ||
00314                 png_color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
00315         {
00316                 png_set_gray_to_rgb(png_ptr);
00317         }
00318 
00319         colormodel = output->get_color_model();
00320         color_type = png_get_color_type(png_ptr, info_ptr);
00321         color_depth = png_get_bit_depth(png_ptr,info_ptr);
00322         
00323         if (((native_cmodel == BC_RGBA16161616)||(native_cmodel == BC_RGB161616))
00324             && ((colormodel == BC_RGBA8888)||(colormodel == BC_RGB888)))
00325         {
00326             png_set_strip_16(png_ptr);
00327         }
00328 
00329         /* If we're dropping the alpha channel, use the background color of the image
00330            otherwise, use black */
00331         if (((native_cmodel == BC_RGBA16161616)||(native_cmodel == BC_RGBA8888))
00332             && ((colormodel == BC_RGB161616)||(colormodel == BC_RGB888)))
00333         {
00334             png_color_16 my_background;
00335             png_color_16p image_background;
00336             
00337             memset(&my_background,0,sizeof(png_color_16));
00338             
00339             if (png_get_bKGD(png_ptr, info_ptr, &image_background))
00340             {
00341                 png_set_background(png_ptr, image_background, PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
00342             }
00343             else
00344             {
00345                 png_set_background(png_ptr, &my_background, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
00346             }
00347         }
00348         
00349         /* Little endian */
00350         if ((color_depth == 16)
00351             &&((colormodel == BC_RGBA16161616)||(colormodel == BC_RGB161616)))
00352         {
00353             png_set_swap(png_ptr);
00354         }
00355         
00356         if (!(color_type & PNG_COLOR_MASK_COLOR))
00357         {
00358             png_set_gray_to_rgb(png_ptr);
00359         }
00360         
00361         if (color_type & PNG_COLOR_MASK_PALETTE)
00362         {
00363             png_set_palette_to_rgb(png_ptr);
00364         }
00365         
00366         if (color_depth <= 8)
00367         {
00368             png_set_expand(png_ptr);
00369         }
00370 
00371 /* read the image */
00372         png_read_image(png_ptr, output->get_rows());
00373 //printf("FilePNG::read_frame 3\n");
00374         png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);
00375 
00376         input->set_compressed_size(size);
00377 
00378 //printf("FilePNG::read_frame 4\n");
00379         return result;
00380 }
00381 
00382 FrameWriterUnit* FilePNG::new_writer_unit(FrameWriter *writer)
00383 {
00384         return new PNGUnit(this, writer);
00385 }
00386 
00387 
00388 
00389 
00390 
00391 
00392 
00393 
00394 
00395 
00396 
00397 
00398 PNGUnit::PNGUnit(FilePNG *file, FrameWriter *writer)
00399  : FrameWriterUnit(writer)
00400 {
00401         this->file = file;
00402         temp_frame = 0;
00403 }
00404 PNGUnit::~PNGUnit()
00405 {
00406         if(temp_frame) delete temp_frame;
00407 }
00408 
00409 
00410 
00411 
00412 
00413 
00414 
00415 
00416 
00417 PNGConfigVideo::PNGConfigVideo(BC_WindowBase *parent_window, Asset *asset)
00418  : BC_Window(PROGRAM_NAME ": Video Compression",
00419         parent_window->get_abs_cursor_x(1),
00420         parent_window->get_abs_cursor_y(1),
00421         200,
00422         100)
00423 {
00424         this->parent_window = parent_window;
00425         this->asset = asset;
00426 }
00427 
00428 PNGConfigVideo::~PNGConfigVideo()
00429 {
00430 }
00431 
00432 int PNGConfigVideo::create_objects()
00433 {
00434         int x = 10, y = 10;
00435         add_subwindow(new PNGUseAlpha(this, x, y));
00436         add_subwindow(new BC_OKButton(this));
00437         return 0;
00438 }
00439 
00440 int PNGConfigVideo::close_event()
00441 {
00442         set_done(0);
00443         return 1;
00444 }
00445 
00446 
00447 PNGUseAlpha::PNGUseAlpha(PNGConfigVideo *gui, int x, int y)
00448  : BC_CheckBox(x, y, gui->asset->png_use_alpha, _("Use alpha"))
00449 {
00450         this->gui = gui;
00451 }
00452 
00453 int PNGUseAlpha::handle_event()
00454 {
00455         gui->asset->png_use_alpha = get_value();
00456         return 1;
00457 }
00458 
00459 
00460 

Generated on Sun Jan 8 13:38:55 2006 for Cinelerra-svn by  doxygen 1.4.4