diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp index 919e2337ef49ad6d32cf6cecc0891d2bcde0758d..377ac7612587f31df174474cae25655ce22f1f1b 100644 --- a/indra/newview/llfilepicker.cpp +++ b/indra/newview/llfilepicker.cpp @@ -52,7 +52,7 @@ LLFilePicker LLFilePicker::sInstance; #if LL_WINDOWS #define SOUND_FILTER L"Sounds (*.wav)\0*.wav\0" -#define IMAGE_FILTER L"Images (*.tga; *.bmp; *.jpg; *.jpeg; *.png)\0*.tga;*.bmp;*.jpg;*.jpeg;*.png\0" +#define IMAGE_FILTER L"Images (*.tga; *.bmp; *.jpg; *.jpeg; *.png; *.webp)\0*.tga;*.bmp;*.jpg;*.jpeg;*.png;*.webp\0" #define ANIM_FILTER L"Animations (*.bvh; *.anim)\0*.bvh;*.anim\0" #define COLLADA_FILTER L"Scene (*.dae)\0*.dae\0" #ifdef _CORY_TESTING @@ -442,7 +442,17 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename, L"PNG Images (*.png)\0*.png\0" \ L"\0"; break; - case FFSAVE_TGAPNG: + case FFSAVE_WEBP: + if (filename.empty()) + { + wcsncpy(mFilesW, L"untitled.webp", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ + } + mOFN.lpstrDefExt = L"webp"; + mOFN.lpstrFilter = + L"WebP Images (*.webp)\0*.webp\0" \ + L"\0"; + break; + case FFSAVE_TGAPNGWEBP: if (filename.empty()) { wcsncpy( mFilesW,L"untitled.png", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ @@ -452,9 +462,10 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename, mOFN.lpstrFilter = L"PNG Images (*.png)\0*.png\0" \ L"Targa Images (*.tga)\0*.tga\0" \ + L"WebP Images (*.webp)\0*.webp\0" \ L"\0"; break; - + case FFSAVE_JPEG: if (filename.empty()) { @@ -614,6 +625,7 @@ std::vector<std::string>* LLFilePicker::navOpenFilterProc(ELoadFilter filter) // allowedv->push_back("bmpf"); allowedv->push_back("tpic"); allowedv->push_back("png"); + allowedv->push_back("webp"); break; case FFLOAD_EXE: allowedv->push_back("app"); @@ -704,10 +716,10 @@ bool LLFilePicker::doNavSaveDialog(ESaveFilter filter, const std::string& filena creator = "prvw"; extension = "tga"; break; - case FFSAVE_TGAPNG: + case FFSAVE_TGAPNGWEBP: type = "PNG"; creator = "prvw"; - extension = "png,tga"; + extension = "png,tga,webp"; break; case FFSAVE_BMP: type = "BMPf"; @@ -724,6 +736,11 @@ bool LLFilePicker::doNavSaveDialog(ESaveFilter filter, const std::string& filena creator = "prvw"; extension = "png"; break; + case FFSAVE_WEBP: + type = "WebP"; + creator = "prvw"; + extension = "webp"; + break; case FFSAVE_AVI: type = "\?\?\?\?"; creator = "\?\?\?\?"; @@ -1017,6 +1034,10 @@ void LLFilePicker::chooser_responder(GtkWidget *widget, gint response, gpointer { picker->mCurrentExtension = ".tga"; } + else if (filter == LLTrans::getString("webp_image_files")) + { + picker->mCurrentExtension = ".webp"; + } } // set the default path for this usage context. @@ -1206,17 +1227,22 @@ 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(); + GtkFileFilter *gfilter_webp = 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_add_pattern(gfilter_webp, "*.webp"); + std::string caption = LLTrans::getString("save_texture_image_files") + " (*.tga; *.png; *.webp)"; 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_filter_set_name(gfilter_webp, LLTrans::getString("webp_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); + gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(picker), + gfilter_webp); return caption; } @@ -1262,7 +1288,12 @@ BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename (picker, "image/png", LLTrans::getString("png_image_files") + " (*.png)"); suggest_ext = ".png"; break; - case FFSAVE_TGAPNG: + case FFSAVE_WEBP: + caption += add_simple_pattern_filter_to_gtkchooser + (picker, "*.webp", LLTrans::getString("webp_image_files") + " (*.webp)"); + suggest_ext = ".webp"; + break; + case FFSAVE_TGAPNGWEBP: caption += add_save_texture_filter_to_gtkchooser(picker); suggest_ext = ".png"; break; @@ -1324,7 +1355,7 @@ BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename rtn = (getFileCount() == 1); - if(rtn && filter == FFSAVE_TGAPNG) + if(rtn && filter == FFSAVE_TGAPNGWEBP) { std::string selected_file = mFiles.back(); mFiles.pop_back(); diff --git a/indra/newview/llfilepicker.h b/indra/newview/llfilepicker.h index c1fa147d2d7223c1f4a58103f8b0702788c656bb..bc8c6eaf5a63684bc2fd4b864da418486eea73a0 100644 --- a/indra/newview/llfilepicker.h +++ b/indra/newview/llfilepicker.h @@ -110,7 +110,8 @@ class LLFilePicker FFSAVE_PNG = 13, FFSAVE_JPEG = 14, FFSAVE_SCRIPT = 15, - FFSAVE_TGAPNG = 16 + FFSAVE_TGAPNGWEBP = 16, + FFSAVE_WEBP = 17 }; // open the dialog. This is a modal operation diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp index 5a17332fde653a868d52712c5bba8e9916fa4c5f..3714bc67352d7aa313e178b86c8cebf44db4aa75 100644 --- a/indra/newview/lllocalbitmaps.cpp +++ b/indra/newview/lllocalbitmaps.cpp @@ -40,6 +40,7 @@ #include "llimagetga.h" #include "llimagejpeg.h" #include "llimagepng.h" +#include "llimagewebp.h" /* time headers */ #include <time.h> @@ -109,6 +110,10 @@ LLLocalBitmap::LLLocalBitmap(std::string filename) { mExtension = ET_IMG_PNG; } + else if (temp_exten == "webp") + { + mExtension = ET_IMG_WEBP; + } else { LL_WARNS() << "File of no valid extension given, local bitmap creation aborted." << "\n" @@ -324,6 +329,17 @@ bool LLLocalBitmap::decodeBitmap(LLPointer<LLImageRaw> rawimg) break; } + case ET_IMG_WEBP: + { + LLPointer<LLImageWebP> webp_image = new LLImageWebP; + if (webp_image->load(mFilename) && webp_image->decode(rawimg, 0.0f)) + { + rawimg->biasedScaleToPowerOfTwo(LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); + decode_successful = true; + } + break; + } + default: { // separating this into -several- LL_WARNS() calls because in the extremely unlikely case that this happens diff --git a/indra/newview/lllocalbitmaps.h b/indra/newview/lllocalbitmaps.h index d5ee7efdc640cfa5c90028c5e8b8f7fd8d823986..226dbbe4949c5d8e53e6cdf823851187982e86eb 100644 --- a/indra/newview/lllocalbitmaps.h +++ b/indra/newview/lllocalbitmaps.h @@ -80,7 +80,8 @@ class LLLocalBitmap ET_IMG_BMP, ET_IMG_TGA, ET_IMG_JPG, - ET_IMG_PNG + ET_IMG_PNG, + ET_IMG_WEBP }; private: /* members */ diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp index 90cc18fbe989598a8464766c61c8bdb0ba8f3e37..d625548c7bb2b37bb6563564ff15abbc07b65605 100644 --- a/indra/newview/llpreviewtexture.cpp +++ b/indra/newview/llpreviewtexture.cpp @@ -37,6 +37,7 @@ #include "llfloaterreg.h" #include "llimagetga.h" #include "llimagepng.h" +#include "llimagewebp.h" #include "llinventory.h" #include "llinventorymodel.h" #include "llnotificationsutil.h" @@ -295,7 +296,7 @@ void LLPreviewTexture::saveAs() return; std::string filename = getItem() ? LLDir::getScrubbedFileName(getItem()->getName()) : LLStringUtil::null; - (new LLFilePickerReplyThread(boost::bind(&LLPreviewTexture::saveTextureToFile, this, _1), LLFilePicker::FFSAVE_TGAPNG, filename))->getFile(); + (new LLFilePickerReplyThread(boost::bind(&LLPreviewTexture::saveTextureToFile, this, _1), LLFilePicker::FFSAVE_TGAPNGWEBP, filename))->getFile(); } void LLPreviewTexture::saveTextureToFile(const std::vector<std::string>& filenames) @@ -412,8 +413,12 @@ void LLPreviewTexture::onFileLoadedForSave(BOOL success, if( self && final && success ) { - const U32 ext_length = 3; - std::string extension = self->mSaveFileName.substr( self->mSaveFileName.length() - ext_length); + std::string extension; + size_t extpos = self->mSaveFileName.rfind("."); + if (extpos != std::string::npos) + { + extension = self->mSaveFileName.substr(extpos + 1); + } // We only support saving in PNG or TGA format LLPointer<LLImageFormatted> image; @@ -425,6 +430,10 @@ void LLPreviewTexture::onFileLoadedForSave(BOOL success, { image = new LLImageTGA; } + else if (extension == "webp") + { + image = new LLImageWebP; + } if( image && !image->encode( src, 0 ) ) { diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 17945dfdb66adcd24d24c71117eaa08da23a7dd8..755fed4705c86938654bfb4145d9b9c77dce27cf 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -258,7 +258,7 @@ void LLFilePickerReplyThread::notify(const std::vector<std::string>& filenames) #if LL_WINDOWS static std::string SOUND_EXTENSIONS = "wav"; -static std::string IMAGE_EXTENSIONS = "tga bmp jpg jpeg png"; +static std::string IMAGE_EXTENSIONS = "tga bmp jpg jpeg png webp"; static std::string ANIM_EXTENSIONS = "bvh anim"; #ifdef _CORY_TESTING static std::string GEOMETRY_EXTENSIONS = "slg"; diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index e3163d6c85722e8645f7032a7c0396d54a0aafa9..112b2cdbda4cdd86fbc3a07bceb19077f39850e1 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -563,7 +563,8 @@ http://secondlife.com/support for help fixing this problem. <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="webp_image_files">WebP Images</string> + <string name="save_texture_image_files">Targa, PNG, or WebP 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>