diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp
index d13f85baa2ec0b2fd309dee63d6b2dcd67ffe2f9..65aa75c9ce967d490394bd2d5498870e237030d1 100755
--- a/indra/newview/llfilepicker.cpp
+++ b/indra/newview/llfilepicker.cpp
@@ -425,6 +425,19 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename)
 			L"PNG Images (*.png)\0*.png\0" \
 			L"\0";
 		break;
+	case FFSAVE_TGAPNG:
+		if (filename.empty())
+		{
+			wcsncpy( mFilesW,L"untitled.png", FILENAME_BUFFER_SIZE);	/*Flawfinder: ignore*/
+			//PNG by default
+		}
+		mOFN.lpstrDefExt = L"png";
+		mOFN.lpstrFilter =
+			L"PNG Images (*.png)\0*.png\0" \
+			L"Targa Images (*.tga)\0*.tga\0" \
+			L"\0";
+		break;
+		
 	case FFSAVE_JPEG:
 		if (filename.empty())
 		{
@@ -1089,6 +1102,20 @@ void LLFilePicker::chooser_responder(GtkWidget *widget, gint response, gpointer
 		g_slist_free (file_list);
 	}
 
+	// let's save the extension of the last added file(considering current filter)
+	GtkFileFilter *gfilter = gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(widget));
+	std::string filter = gtk_file_filter_get_name(gfilter);
+
+	if(filter == LLTrans::getString("png_image_files"))
+	{
+		picker->mCurrentExtension = ".png";
+	}
+	else if(filter == LLTrans::getString("targa_image_files"))
+	{
+		picker->mCurrentExtension = ".tga";
+	}
+
+
 	// set the default path for this usage context.
 	const char* cur_folder = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(widget));
 	if (cur_folder != NULL)
@@ -1260,6 +1287,24 @@ static std::string add_dictionary_filter_to_gtkchooser(GtkWindow *picker)
 							LLTrans::getString("dictionary_files") + " (*.dic; *.xcu)");
 }
 
+static std::string add_save_texture_filter_to_gtkchooser(GtkWindow *picker)
+{
+	GtkFileFilter *gfilter_tga = gtk_file_filter_new();
+	GtkFileFilter *gfilter_png = gtk_file_filter_new();
+
+	gtk_file_filter_add_pattern(gfilter_tga, "*.tga");
+	gtk_file_filter_add_mime_type(gfilter_png, "image/png");
+	std::string caption = LLTrans::getString("save_texture_image_files") + " (*.tga; *.png)";
+	gtk_file_filter_set_name(gfilter_tga, LLTrans::getString("targa_image_files").c_str());
+	gtk_file_filter_set_name(gfilter_png, LLTrans::getString("png_image_files").c_str());
+
+	gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker),
+					gfilter_png);
+	gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker),
+					gfilter_tga);
+	return caption;
+}
+
 BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename )
 {
 	BOOL rtn = FALSE;
@@ -1297,6 +1342,15 @@ BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename
 				(picker, "image/bmp", LLTrans::getString("bitmap_image_files") + " (*.bmp)");
 			suggest_ext = ".bmp";
 			break;
+		case FFSAVE_PNG:
+			caption += add_simple_mime_filter_to_gtkchooser
+				(picker, "image/png", LLTrans::getString("png_image_files") + " (*.png)");
+			suggest_ext = ".png";
+			break;
+		case FFSAVE_TGAPNG:
+			caption += add_save_texture_filter_to_gtkchooser(picker);
+			suggest_ext = ".png";
+			break;
 		case FFSAVE_AVI:
 			caption += add_simple_mime_filter_to_gtkchooser
 				(picker, "video/x-msvideo",
@@ -1349,9 +1403,17 @@ BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename
 		}
 
 		gtk_widget_show_all(GTK_WIDGET(picker));
+
 		gtk_main();
 
 		rtn = (getFileCount() == 1);
+
+		if(rtn && filter == FFSAVE_TGAPNG)
+		{
+			std::string selected_file = mFiles.back();
+			mFiles.pop_back();
+			mFiles.push_back(selected_file + mCurrentExtension);
+		}
 	}
 
 	gViewerWindow->getWindow()->afterDialog();
diff --git a/indra/newview/llfilepicker.h b/indra/newview/llfilepicker.h
index 4f602f63f13afb50aae9d8934d9af0f6a1b35dad..8a0ecb124a88eea00fe18df50d74b677a6bd4649 100755
--- a/indra/newview/llfilepicker.h
+++ b/indra/newview/llfilepicker.h
@@ -106,6 +106,7 @@ class LLFilePicker
 		FFSAVE_PNG = 13,
 		FFSAVE_JPEG = 14,
 		FFSAVE_SCRIPT = 15,
+		FFSAVE_TGAPNG = 16
 	};
 
 	// open the dialog. This is a modal operation
@@ -175,6 +176,8 @@ class LLFilePicker
 	// we remember the last path that was accessed for a particular usage
 	std::map <std::string, std::string> mContextToPathMap;
 	std::string mCurContextName;
+	// we also remember the extension of the last added file.
+	std::string mCurrentExtension;
 #endif
 
 	std::vector<std::string> mFiles;
diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp
index 91a98792eb56b3dd0e529db8c3dce9e9d1e4d916..1ed48a978fffa2693494b8e55221b0d4c8340e9f 100755
--- a/indra/newview/llpreviewtexture.cpp
+++ b/indra/newview/llpreviewtexture.cpp
@@ -36,6 +36,7 @@
 #include "llfilepicker.h"
 #include "llfloaterreg.h"
 #include "llimagetga.h"
+#include "llimagepng.h"
 #include "llinventory.h"
 #include "llnotificationsutil.h"
 #include "llresmgr.h"
@@ -261,7 +262,7 @@ void LLPreviewTexture::saveAs()
 
 	LLFilePicker& file_picker = LLFilePicker::instance();
 	const LLInventoryItem* item = getItem() ;
-	if( !file_picker.getSaveFile( LLFilePicker::FFSAVE_TGA, item ? LLDir::getScrubbedFileName(item->getName()) : LLStringUtil::null) )
+	if( !file_picker.getSaveFile( LLFilePicker::FFSAVE_TGAPNG, item ? LLDir::getScrubbedFileName(item->getName()) : LLStringUtil::null) )
 	{
 		// User canceled or we failed to acquire save file.
 		return;
@@ -358,14 +359,27 @@ void LLPreviewTexture::onFileLoadedForSave(BOOL success,
 
 	if( self && final && success )
 	{
-		LLPointer<LLImageTGA> image_tga = new LLImageTGA;
-		if( !image_tga->encode( src ) )
+		const U32 ext_length = 3;
+		std::string extension = self->mSaveFileName.substr( self->mSaveFileName.length() - ext_length);
+
+		// We only support saving in PNG or TGA format
+		LLPointer<LLImageFormatted> image;
+		if(extension == "png")
+		{
+			image = new LLImagePNG;
+		}
+		else if(extension == "tga")
+		{
+			image = new LLImageTGA;
+		}
+
+		if( image && !image->encode( src, 0 ) )
 		{
 			LLSD args;
 			args["FILE"] = self->mSaveFileName;
 			LLNotificationsUtil::add("CannotEncodeFile", args);
 		}
-		else if( !image_tga->save( self->mSaveFileName ) )
+		else if( image && !image->save( self->mSaveFileName ) )
 		{
 			LLSD args;
 			args["FILE"] = self->mSaveFileName;
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index d4a37a98135c4dd36306f6d0854160f9f912c8c9..ed862dd2697d91cf0e18b75609cde15b0957dce1 100755
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -447,6 +447,8 @@ Please try logging in again in a minute.</string>
 	<string name="load_file_verb">Load</string>
 	<string name="targa_image_files">Targa Images</string>
 	<string name="bitmap_image_files">Bitmap Images</string>
+	<string name="png_image_files">PNG Images</string>
+	<string name="save_texture_image_files">Targa or PNG Images</string>
 	<string name="avi_movie_file">AVI Movie File</string>
 	<string name="xaf_animation_file">XAF Anim File</string>
 	<string name="xml_file">XML File</string>