00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifdef HAVE_CONFIG_H
00021 #include <config.h>
00022 #endif
00023
00024 #include <vector>
00025 #include <iostream>
00026 using std::cerr;
00027 using std::endl;
00028
00029 #include <gtk/gtk.h>
00030 #include <stdio.h>
00031 #include <stdlib.h>
00032
00033 #include "page_export_stills.h"
00034 #include "preferences.h"
00035 #include "kino_common.h"
00036 #include "frame.h"
00037 #include "page_editor.h"
00038 #include "message.h"
00039
00046 ExportStills::ExportStills( PageExport *_exportPage, KinoCommon *_common ) :
00047 Export( _exportPage, _common )
00048 {
00049 cerr << "> Creating ExportStills Page" << endl;
00050
00051
00052 qualityScale
00053 = GTK_RANGE( lookup_widget( common->getWidget(), "hscale_export_stills" ) );
00054
00055 fileEntry
00056 = GTK_ENTRY( lookup_widget( common->getWidget(), "entry_export_stills_file" ) );
00057 }
00058
00062 ExportStills::~ExportStills()
00063 {
00064 cerr << "> Destroying ExportStills Page" << endl;
00065 }
00066
00069 enum export_result
00070 ExportStills::doExport( PlayList * playlist, int begin, int end, int every,
00071 bool preview )
00072 {
00073 static unsigned char pixels[ FRAME_MAX_WIDTH * FRAME_MAX_HEIGHT * 4 ];
00074 GdkPixbuf *image = NULL;
00075 gchar *file = NULL;
00076 gchar *filename = NULL;
00077 gchar *extension = NULL;
00078 int i = -1;
00079 GError *gerror = NULL;
00080 char quality[ 8 ] = "75";
00081 int extractOption;
00082 bool isResample;
00083
00084 file = g_strdup( gtk_entry_get_text( fileEntry ) );
00085
00086
00087 if ( !strcmp( file, "" ) )
00088 {
00089 modal_message( _( "You must enter a filename." ) );
00090 g_free( file );
00091 return EXPORT_RESULT_FAILURE;
00092 }
00093
00094
00095 GtkAdjustment * adjust = gtk_range_get_adjustment( qualityScale );
00096 if ( adjust )
00097 snprintf( quality, 8, "%d", ( int ) adjust->value );
00098
00099
00100 char *tmp = strrchr( file, '.' );
00101 if ( tmp == NULL )
00102 {
00103 modal_message( _( "You must enter a filename with an extension" ) );
00104 g_free( file );
00105 return EXPORT_RESULT_FAILURE;
00106 }
00107 else
00108 {
00109 extension = g_strdup( tmp );
00110 tmp[0] = '\0';
00111 }
00112
00113
00114 GtkWidget *widget = gtk_option_menu_get_menu( GTK_OPTION_MENU( lookup_widget( common->getWidget(),
00115 "optionmenu_export_stills_extract" ) ) );
00116 GtkWidget *active_item = gtk_menu_get_active( GTK_MENU( widget ) );
00117 extractOption = g_list_index( GTK_MENU_SHELL( widget )->children, active_item );
00118
00119 widget = lookup_widget( common->getWidget(), "checkbutton_export_stills_resample" );
00120 isResample = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( widget ) );
00121
00122
00123 Frame &frame = *GetFramePool( ) ->GetFrame( );
00124 frame.decoder->quality = DV_QUALITY_BEST;
00125
00126 for ( i = begin; i <= end && exportPage->isExporting; i += every )
00127 {
00128
00129
00130 innerLoopUpdate( i, begin, end, every );
00131
00132
00133 playlist->GetFrame( i, frame );
00134 frame.ExtractRGB( pixels );
00135 switch ( extractOption )
00136 {
00137 case 1:
00138 frame.Deinterlace( ( uint8_t* ) pixels, ( uint8_t* ) pixels, frame.GetWidth() * 3, frame.GetHeight() );
00139 break;
00140 case 2:
00141 frame.GetLowerField( pixels, 3 );
00142 break;
00143 case 3:
00144 frame.GetUpperField( pixels, 3 );
00145 break;
00146 default:
00147 break;
00148 }
00149
00150
00151 image = gdk_pixbuf_new_from_data( pixels, GDK_COLORSPACE_RGB, FALSE, 8,
00152 frame.GetWidth(), frame.GetHeight(), frame.GetWidth() * 3, NULL, NULL );
00153
00154
00155 if ( isResample )
00156 {
00157 int width = frame.GetWidth();
00158 if ( frame.IsWide() )
00159 width = frame.IsPAL() ? 1024 : 854;
00160 AspectRatioCalculator calc( width, frame.GetHeight(),
00161 frame.GetWidth(), frame.GetHeight(),
00162 frame.IsPAL(), frame.IsWide() );
00163 GdkPixbuf *scaled = gdk_pixbuf_scale_simple( image, calc.width, calc.height, GDK_INTERP_HYPER );
00164 g_object_unref( image );
00165 image = scaled;
00166 }
00167
00168
00169 filename = g_strdup_printf( "%s_%06i%s", file, i + 1, extension );
00170 if ( strncasecmp( extension + 1, "png", 8 ) == 0 )
00171 gdk_pixbuf_save( image, filename, "png", &gerror, NULL );
00172 else
00173 gdk_pixbuf_save( image, filename, "jpeg", &gerror, "quality", quality, NULL );
00174
00175 if ( gerror != NULL )
00176 {
00177 modal_message( gerror->message );
00178 g_error_free( gerror );
00179 }
00180 g_object_unref( image );
00181 g_free( filename );
00182 }
00183
00184 GetFramePool( ) ->DoneWithFrame( &frame );
00185
00186 g_free( file );
00187 g_free( extension );
00188
00189 if ( !exportPage->isExporting )
00190 return EXPORT_RESULT_ABORT;
00191 else if ( i > end )
00192 return EXPORT_RESULT_SUCCESS;
00193 else
00194 return EXPORT_RESULT_FAILURE;
00195 }
00196
00197 extern "C"
00198 {
00199 void
00200 on_button_export_stills_file_clicked (GtkButton *button,
00201 gpointer user_data)
00202 {
00203 const char *filename = common->getFileToSave( _("Enter a File Name to Save As") );
00204 gtk_widget_grab_focus( lookup_widget( GTK_WIDGET( button ), "entry_export_stills_file" ) );
00205 if ( strcmp( filename, "" ) )
00206 gtk_entry_set_text( GTK_ENTRY( lookup_widget( GTK_WIDGET( button ), "entry_export_stills_file" ) ), filename );
00207 }
00208 }