From db3f7eafa05636a3079037109d3d21514b25a8bb Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 4 Jun 2024 02:08:12 +0300 Subject: viewer#1588 Upload directly to Specified Inventory Folder --- indra/newview/llfloaterimagepreview.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/newview/llfloaterimagepreview.cpp') diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp index 7851c5403b..9fa3dd0c47 100644 --- a/indra/newview/llfloaterimagepreview.cpp +++ b/indra/newview/llfloaterimagepreview.cpp @@ -71,8 +71,8 @@ const S32 PREVIEW_TEXTURE_HEIGHT = 320; //----------------------------------------------------------------------------- // LLFloaterImagePreview() //----------------------------------------------------------------------------- -LLFloaterImagePreview::LLFloaterImagePreview(const std::string& filename) : - LLFloaterNameDesc(filename), +LLFloaterImagePreview::LLFloaterImagePreview(const LLSD& args) : + LLFloaterNameDesc(args), mAvatarPreview(NULL), mSculptedPreview(NULL), -- cgit v1.3 From 533390a531fb1f82f7f14c6ab3bf3cfa6d806cd1 Mon Sep 17 00:00:00 2001 From: "Kyler \"Félix\" Eastridge" Date: Sat, 26 Jul 2025 20:18:26 +0100 Subject: 2k image resize (#4444) * Fix spelling error in variable name * Resize images larger than allowed before upload * Resize bulk images if they are larger than the allow size * Fix indentation error caused by Visual Studio * Fix bulk upload cost calculation --- indra/newview/llfloaterimagepreview.cpp | 114 +++++++++++++-- indra/newview/llfloaterimagepreview.h | 2 + indra/newview/llviewermenufile.cpp | 161 +++++++++++++++++---- .../newview/skins/default/xui/en/notifications.xml | 11 ++ 4 files changed, 248 insertions(+), 40 deletions(-) (limited to 'indra/newview/llfloaterimagepreview.cpp') diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp index 989e1d8d04..49e557a6cb 100644 --- a/indra/newview/llfloaterimagepreview.cpp +++ b/indra/newview/llfloaterimagepreview.cpp @@ -32,6 +32,7 @@ #include "llimagetga.h" #include "llimagejpeg.h" #include "llimagepng.h" +#include "llimagej2c.h" #include "llagent.h" #include "llagentbenefits.h" @@ -43,6 +44,10 @@ #include "llrender.h" #include "llface.h" #include "llfocusmgr.h" +#include "llfilesystem.h" +#include "llfloaterperms.h" +#include "llnotificationsutil.h" +#include "llstatusbar.h" // can_afford_transaction() #include "lltextbox.h" #include "lltoolmgr.h" #include "llui.h" @@ -52,6 +57,7 @@ #include "llvoavatar.h" #include "pipeline.h" #include "lluictrlfactory.h" +#include "llviewermenufile.h" // upload_new_resource() #include "llviewershadermgr.h" #include "llviewertexturelist.h" #include "llstring.h" @@ -140,7 +146,7 @@ bool LLFloaterImagePreview::postBuild() } } - getChild("ok_btn")->setCommitCallback(boost::bind(&LLFloaterNameDesc::onBtnOK, this)); + getChild("ok_btn")->setCommitCallback(boost::bind(&LLFloaterImagePreview::onBtnOK, this)); return true; } @@ -243,6 +249,59 @@ void LLFloaterImagePreview::clearAllPreviewTextures() } } +//----------------------------------------------------------------------------- +// onBtnOK() +//----------------------------------------------------------------------------- +void LLFloaterImagePreview::onBtnOK() +{ + getChildView("ok_btn")->setEnabled(false); // don't allow inadvertent extra uploads + + S32 expected_upload_cost = getExpectedUploadCost(); + if (can_afford_transaction(expected_upload_cost)) + { + LL_INFOS() << "saving texture: " << mRawImagep->getWidth() << "x" << mRawImagep->getHeight() << LL_ENDL; + // gen a new uuid for this asset + LLTransactionID tid; + tid.generate(); + LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); + + LLPointer formatted = new LLImageJ2C; + + if (formatted->encode(mRawImagep, 0.0f)) + { + LLFileSystem fmt_file(new_asset_id, LLAssetType::AT_TEXTURE, LLFileSystem::WRITE); + fmt_file.write(formatted->getData(), formatted->getDataSize()); + + LLResourceUploadInfo::ptr_t assetUploadInfo(new LLResourceUploadInfo( + tid, LLAssetType::AT_TEXTURE, + getChild("name_form")->getValue().asString(), + getChild("description_form")->getValue().asString(), + 0, + LLFolderType::FT_NONE, LLInventoryType::IT_NONE, + LLFloaterPerms::getNextOwnerPerms("Uploads"), + LLFloaterPerms::getGroupPerms("Uploads"), + LLFloaterPerms::getEveryonePerms("Uploads"), + expected_upload_cost + )); + + upload_new_resource(assetUploadInfo); + } + else + { + LLNotificationsUtil::add("ErrorEncodingImage"); + LL_WARNS() << "Error encoding image" << LL_ENDL; + } + } + else + { + LLSD args; + args["COST"] = llformat("%d", expected_upload_cost); + LLNotificationsUtil::add("ErrorCannotAffordUpload", args); + } + + closeFloater(false); +} + //----------------------------------------------------------------------------- // draw() //----------------------------------------------------------------------------- @@ -364,19 +423,6 @@ bool LLFloaterImagePreview::loadImage(const std::string& src_filename) return false; } - S32 max_width = gSavedSettings.getS32("max_texture_dimension_X"); - S32 max_height = gSavedSettings.getS32("max_texture_dimension_Y"); - - if ((image_info.getWidth() > max_width) || (image_info.getHeight() > max_height)) - { - LLStringUtil::format_map_t args; - args["WIDTH"] = llformat("%d", max_width); - args["HEIGHT"] = llformat("%d", max_height); - - mImageLoadError = LLTrans::getString("texture_load_dimensions_error", args); - return false; - } - // Load the image LLPointer image = LLImageFormatted::createFromType(codec); if (image.isNull()) @@ -399,6 +445,46 @@ bool LLFloaterImagePreview::loadImage(const std::string& src_filename) image->setLastError("Image files with less than 3 or more than 4 components are not supported."); return false; } + // Downscale images to fit the max_texture_dimensions_* + S32 max_width = gSavedSettings.getS32("max_texture_dimension_X"); + S32 max_height = gSavedSettings.getS32("max_texture_dimension_Y"); + + S32 orig_width = raw_image->getWidth(); + S32 orig_height = raw_image->getHeight(); + + if (orig_width > max_width || orig_height > max_height) + { + // Calculate scale factors + F32 width_scale = (F32)max_width / (F32)orig_width; + F32 height_scale = (F32)max_height / (F32)orig_height; + F32 scale = llmin(width_scale, height_scale); + + // Calculate new dimensions, preserving aspect ratio + S32 new_width = LLImageRaw::contractDimToPowerOfTwo( + llclamp((S32)llroundf(orig_width * scale), 4, max_width) + ); + S32 new_height = LLImageRaw::contractDimToPowerOfTwo( + llclamp((S32)llroundf(orig_height * scale), 4, max_height) + ); + + if (!raw_image->scale(new_width, new_height)) + { + LL_WARNS() << "Failed to scale image from " + << orig_width << "x" << orig_height + << " to " << new_width << "x" << new_height << LL_ENDL; + return false; + } + + // Inform the resident about the resized image + LLSD subs; + subs["[ORIGINAL_WIDTH]"] = orig_width; + subs["[ORIGINAL_HEIGHT]"] = orig_height; + subs["[NEW_WIDTH]"] = new_width; + subs["[NEW_HEIGHT]"] = new_height; + subs["[MAX_WIDTH]"] = max_width; + subs["[MAX_HEIGHT]"] = max_height; + LLNotificationsUtil::add("ImageUploadResized", subs); + } raw_image->biasedScaleToPowerOfTwo(LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); mRawImagep = raw_image; diff --git a/indra/newview/llfloaterimagepreview.h b/indra/newview/llfloaterimagepreview.h index ed395722de..0ebb96a768 100644 --- a/indra/newview/llfloaterimagepreview.h +++ b/indra/newview/llfloaterimagepreview.h @@ -126,6 +126,8 @@ public: void clearAllPreviewTextures(); + void onBtnOK(); + protected: static void onPreviewTypeCommit(LLUICtrl*,void*); void draw() override; diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 9743ec0c59..316f841717 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -69,6 +69,7 @@ #include "llviewerassetupload.h" // linden libraries +#include "llfilesystem.h" #include "llnotificationsutil.h" #include "llsdserialize.h" #include "llsdutil.h" @@ -544,16 +545,9 @@ void do_bulk_upload(std::vector filenames, bool allow_2k) if (LLResourceUploadInfo::findAssetTypeAndCodecOfExtension(ext, asset_type, codec)) { bool resource_upload = false; - if (asset_type == LLAssetType::AT_TEXTURE && allow_2k) + if (asset_type == LLAssetType::AT_TEXTURE) { - LLPointer image_frmted = LLImageFormatted::createFromType(codec); - if (gDirUtilp->fileExists(filename) && image_frmted && image_frmted->load(filename)) - { - S32 biased_width = LLImageRaw::biasedDimToPowerOfTwo(image_frmted->getWidth(), LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); - S32 biased_height = LLImageRaw::biasedDimToPowerOfTwo(image_frmted->getHeight(), LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); - expected_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost(biased_width, biased_height); - resource_upload = true; - } + resource_upload = true; } else if (LLAgentBenefitsMgr::current().findUploadCost(asset_type, expected_upload_cost)) { @@ -562,23 +556,115 @@ void do_bulk_upload(std::vector filenames, bool allow_2k) if (resource_upload) { - LLNewFileResourceUploadInfo* info_p = new LLNewFileResourceUploadInfo( - filename, - asset_name, - asset_name, 0, - LLFolderType::FT_NONE, LLInventoryType::IT_NONE, - LLFloaterPerms::getNextOwnerPerms("Uploads"), - LLFloaterPerms::getGroupPerms("Uploads"), - LLFloaterPerms::getEveryonePerms("Uploads"), - expected_upload_cost); - - if (!allow_2k) + if (asset_type == LLAssetType::AT_TEXTURE) { - info_p->setMaxImageSize(1024); - } - LLResourceUploadInfo::ptr_t uploadInfo(info_p); + std::string exten = gDirUtilp->getExtension(filename); + U32 codec = LLImageBase::getCodecFromExtension(exten); + + // Load the image + LLPointer image = LLImageFormatted::createFromType(codec); + if (image.isNull()) + { + LL_WARNS() << "Failed to create image container for " << filename << LL_ENDL; + continue; + } + if (!image->load(filename)) + { + LL_WARNS() << "Failed to load image: " << filename << LL_ENDL; + continue; + } + // Decompress or expand it in a raw image structure + LLPointer raw_image = new LLImageRaw; + if (!image->decode(raw_image, 0.0f)) + { + LL_WARNS() << "Failed to decode image: " << filename << LL_ENDL; + continue; + } + // Check the image constraints + if ((image->getComponents() != 3) && (image->getComponents() != 4)) + { + LL_WARNS() << "Attempted to upload a texture that has " << image->getComponents() + << " components, but only 3 (RGB) or 4 (RGBA) are allowed." << LL_ENDL; + continue; + } + // Downscale images to fit the max_texture_dimensions_*, or 1024 if allow_2k is false + S32 max_width = allow_2k ? gSavedSettings.getS32("max_texture_dimension_X") : 1024; + S32 max_height = allow_2k ? gSavedSettings.getS32("max_texture_dimension_Y") : 1024; + + S32 orig_width = raw_image->getWidth(); + S32 orig_height = raw_image->getHeight(); + + if (orig_width > max_width || orig_height > max_height) + { + // Calculate scale factors + F32 width_scale = (F32)max_width / (F32)orig_width; + F32 height_scale = (F32)max_height / (F32)orig_height; + F32 scale = llmin(width_scale, height_scale); + + // Calculate new dimensions, preserving aspect ratio + S32 new_width = LLImageRaw::contractDimToPowerOfTwo(llclamp((S32)llroundf(orig_width * scale), 4, max_width)); + S32 new_height = LLImageRaw::contractDimToPowerOfTwo(llclamp((S32)llroundf(orig_height * scale), 4, max_height)); + + if (!raw_image->scale(new_width, new_height)) + { + LL_WARNS() << "Failed to scale image from " << orig_width << "x" << orig_height << " to " << new_width << "x" + << new_height << LL_ENDL; + continue; + } + + // Inform the resident about the resized image + LLSD subs; + subs["[ORIGINAL_WIDTH]"] = orig_width; + subs["[ORIGINAL_HEIGHT]"] = orig_height; + subs["[NEW_WIDTH]"] = new_width; + subs["[NEW_HEIGHT]"] = new_height; + subs["[MAX_WIDTH]"] = max_width; + subs["[MAX_HEIGHT]"] = max_height; + LLNotificationsUtil::add("ImageUploadResized", subs); + } + + raw_image->biasedScaleToPowerOfTwo(LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); + + LLTransactionID tid; + tid.generate(); + LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); - upload_new_resource(uploadInfo); + LLPointer formatted = new LLImageJ2C; + + if (formatted->encode(raw_image, 0.0f)) + { + LLFileSystem fmt_file(new_asset_id, LLAssetType::AT_TEXTURE, LLFileSystem::WRITE); + fmt_file.write(formatted->getData(), formatted->getDataSize()); + + LLResourceUploadInfo::ptr_t assetUploadInfo(new LLResourceUploadInfo( + tid, LLAssetType::AT_TEXTURE, + asset_name, + asset_name, 0, + LLFolderType::FT_NONE, LLInventoryType::IT_NONE, + LLFloaterPerms::getNextOwnerPerms("Uploads"), + LLFloaterPerms::getGroupPerms("Uploads"), + LLFloaterPerms::getEveryonePerms("Uploads"), + LLAgentBenefitsMgr::current().getTextureUploadCost(raw_image->getWidth(), raw_image->getHeight()) + )); + + upload_new_resource(assetUploadInfo); + } + } + else + { + LLNewFileResourceUploadInfo* info_p = new LLNewFileResourceUploadInfo( + filename, + asset_name, + asset_name, 0, + LLFolderType::FT_NONE, LLInventoryType::IT_NONE, + LLFloaterPerms::getNextOwnerPerms("Uploads"), + LLFloaterPerms::getGroupPerms("Uploads"), + LLFloaterPerms::getEveryonePerms("Uploads"), + expected_upload_cost); + LLResourceUploadInfo::ptr_t uploadInfo(info_p); + + upload_new_resource(uploadInfo); + } } } @@ -647,8 +733,31 @@ bool get_bulk_upload_expected_cost( LLPointer image_frmted = LLImageFormatted::createFromType(codec); if (gDirUtilp->fileExists(filename) && image_frmted && image_frmted->load(filename)) { - S32 biased_width = LLImageRaw::biasedDimToPowerOfTwo(image_frmted->getWidth(), LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); - S32 biased_height = LLImageRaw::biasedDimToPowerOfTwo(image_frmted->getHeight(), LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); + S32 biased_width, biased_height; + + S32 max_width = allow_2k ? gSavedSettings.getS32("max_texture_dimension_X") : 1024; + S32 max_height = allow_2k ? gSavedSettings.getS32("max_texture_dimension_Y") : 1024; + + S32 orig_width = image_frmted->getWidth(); + S32 orig_height = image_frmted->getHeight(); + + if (orig_width > max_width || orig_height > max_height) + { + // Calculate scale factors + F32 width_scale = (F32)max_width / (F32)orig_width; + F32 height_scale = (F32)max_height / (F32)orig_height; + F32 scale = llmin(width_scale, height_scale); + + // Calculate new dimensions, preserving aspect ratio + biased_width = LLImageRaw::contractDimToPowerOfTwo(llclamp((S32)llroundf(orig_width * scale), 4, max_width)); + biased_height = LLImageRaw::contractDimToPowerOfTwo(llclamp((S32)llroundf(orig_height * scale), 4, max_height)); + } + else + { + biased_width = LLImageRaw::biasedDimToPowerOfTwo(orig_width, LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); + biased_height = LLImageRaw::biasedDimToPowerOfTwo(orig_height, LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); + } + total_cost += LLAgentBenefitsMgr::current().getTextureUploadCost(biased_width, biased_height); S32 area = biased_width * biased_height; if (area >= LLAgentBenefits::MIN_2K_TEXTURE_AREA) diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index a51feeb7ab..93797c0b58 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -12619,4 +12619,15 @@ are wearing now. Unable to apply material to the water exclusion surface. fail + + + The texture you are uploading has been resized from [ORIGINAL_WIDTH]x[ORIGINAL_HEIGHT] to [NEW_WIDTH]x[NEW_HEIGHT] in order to to fit the maximum size of [MAX_WIDTH]x[MAX_HEIGHT] pixels. + + -- cgit v1.3 From 82e6e42b9ee62af0e39049e3d789457fe1a41281 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 12 Aug 2025 22:13:51 +0300 Subject: #4527 Crash trying to upload a huge image Raw image permits only a 256 MB buffer so this isn't unexpected. --- indra/llimage/llimagebmp.cpp | 6 ++++++ indra/llimage/llimagedxt.cpp | 6 ++++++ indra/llimage/llimagejpeg.cpp | 6 ++++++ indra/llimagej2coj/llimagej2coj.cpp | 6 ++++++ indra/llkdu/llimagej2ckdu.cpp | 6 ++++++ indra/newview/llfloaterimagepreview.cpp | 4 +++- indra/newview/skins/default/xui/en/notifications.xml | 8 ++++++++ 7 files changed, 41 insertions(+), 1 deletion(-) (limited to 'indra/newview/llfloaterimagepreview.cpp') diff --git a/indra/llimage/llimagebmp.cpp b/indra/llimage/llimagebmp.cpp index 2a328675c2..c8f99380ea 100644 --- a/indra/llimage/llimagebmp.cpp +++ b/indra/llimage/llimagebmp.cpp @@ -558,6 +558,12 @@ bool LLImageBMP::encode(const LLImageRaw* raw_image, F32 encode_time) LL_INFOS() << "Dropping alpha information during BMP encoding" << LL_ENDL; } + if (raw_image->isBufferInvalid()) + { + setLastError("Invalid input, no buffer"); + return false; + } + setSize(raw_image->getWidth(), raw_image->getHeight(), dst_components); U8 magic[14]; diff --git a/indra/llimage/llimagedxt.cpp b/indra/llimage/llimagedxt.cpp index 6b960f9077..c3fd0c5aa8 100644 --- a/indra/llimage/llimagedxt.cpp +++ b/indra/llimage/llimagedxt.cpp @@ -329,6 +329,12 @@ bool LLImageDXT::encodeDXT(const LLImageRaw* raw_image, F32 time, bool explicit_ { llassert_always(raw_image); + if (raw_image->isBufferInvalid()) + { + setLastError("Invalid input, no buffer"); + return false; + } + S32 ncomponents = raw_image->getComponents(); EFileFormat format; switch (ncomponents) diff --git a/indra/llimage/llimagejpeg.cpp b/indra/llimage/llimagejpeg.cpp index 0e7ec365d4..effd33b410 100644 --- a/indra/llimage/llimagejpeg.cpp +++ b/indra/llimage/llimagejpeg.cpp @@ -491,6 +491,12 @@ bool LLImageJPEG::encode( const LLImageRaw* raw_image, F32 encode_time ) resetLastError(); + if (raw_image->isBufferInvalid()) + { + setLastError("Invalid input, no buffer"); + return false; + } + LLImageDataSharedLock lockIn(raw_image); LLImageDataLock lockOut(this); diff --git a/indra/llimagej2coj/llimagej2coj.cpp b/indra/llimagej2coj/llimagej2coj.cpp index c56e94aaa4..431f5aa001 100644 --- a/indra/llimagej2coj/llimagej2coj.cpp +++ b/indra/llimagej2coj/llimagej2coj.cpp @@ -897,6 +897,12 @@ bool LLImageJ2COJ::decodeImpl(LLImageJ2C &base, LLImageRaw &raw_image, F32 decod bool LLImageJ2COJ::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, const char* comment_text, F32 encode_time, bool reversible) { + if (raw_image.isBufferInvalid()) + { + base.setLastError("Invalid input, no buffer"); + return false; + } + JPEG2KEncode encode(comment_text, reversible); bool encoded = encode.encode(raw_image, base); if (!encoded) diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index 0d1f2b3006..b824fd8385 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -662,6 +662,12 @@ bool LLImageJ2CKDU::encodeImpl(LLImageJ2C &base, const LLImageRaw &raw_image, co bool vflip = true; bool hflip = false; + if (raw_image.isBufferInvalid()) + { + base.setLastError("Invalid input, no buffer"); + return false; + } + try { // Set up input image files diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp index 42a5df5d17..f883f04159 100644 --- a/indra/newview/llfloaterimagepreview.cpp +++ b/indra/newview/llfloaterimagepreview.cpp @@ -288,7 +288,9 @@ void LLFloaterImagePreview::onBtnOK() } else { - LLNotificationsUtil::add("ErrorEncodingImage"); + LLSD args; + args["REASON"] = LLImage::getLastThreadError(); + LLNotificationsUtil::add("ErrorEncodingImage", args); LL_WARNS() << "Error encoding image" << LL_ENDL; } } diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 773e7c311b..b182a241d8 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -1320,6 +1320,14 @@ Error encoding snapshot. fail + + Failed to encode image, reason: [REASON] + fail + + Date: Wed, 13 Aug 2025 21:40:53 +0300 Subject: #4541 Cap image upload size to prevent issues --- indra/newview/llfloaterimagepreview.cpp | 12 ++++++++++++ indra/newview/skins/default/xui/en/strings.xml | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'indra/newview/llfloaterimagepreview.cpp') diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp index f883f04159..44e71e33f3 100644 --- a/indra/newview/llfloaterimagepreview.cpp +++ b/indra/newview/llfloaterimagepreview.cpp @@ -425,6 +425,18 @@ bool LLFloaterImagePreview::loadImage(const std::string& src_filename) return false; } + // raw image is limited to 256MB so need at least some upper limit that fits into that + constexpr S32 MAX_IMAGE_AREA = 8096 * 8096; + + if (image_info.getWidth() * image_info.getHeight() > MAX_IMAGE_AREA) + { + LLStringUtil::format_map_t args; + args["PIXELS"] = llformat("%dM", (S32)(MAX_IMAGE_AREA / 1000000)); + + mImageLoadError = LLTrans::getString("texture_load_dimensions_error", args); + return false; + } + // Load the image LLPointer image = LLImageFormatted::createFromType(codec); if (image.isNull()) diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 21db7eba47..c48ba10cac 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -3970,7 +3970,7 @@ Abuse Report [mthnum,datetime,slt]/[day,datetime,slt] none/none - Can't load images larger than [WIDTH]*[HEIGHT] + Can't load images larger than [PIXELS] pixels Incorrect image format. File is empty. Max outfit photo size is [WIDTH]*[HEIGHT]. Please resize or use another image -- cgit v1.3 From 479618097b14c477413086d6a2d4f40a411556ad Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 14 Aug 2025 21:06:31 +0300 Subject: #4541 Fix reused message it was also in use by local bitmaps --- indra/newview/llfloaterimagepreview.cpp | 2 +- indra/newview/skins/default/xui/en/strings.xml | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'indra/newview/llfloaterimagepreview.cpp') diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp index 44e71e33f3..550c3adc27 100644 --- a/indra/newview/llfloaterimagepreview.cpp +++ b/indra/newview/llfloaterimagepreview.cpp @@ -433,7 +433,7 @@ bool LLFloaterImagePreview::loadImage(const std::string& src_filename) LLStringUtil::format_map_t args; args["PIXELS"] = llformat("%dM", (S32)(MAX_IMAGE_AREA / 1000000)); - mImageLoadError = LLTrans::getString("texture_load_dimensions_error", args); + mImageLoadError = LLTrans::getString("texture_load_area_error", args); return false; } diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index c48ba10cac..99c7d7b7d4 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -3970,7 +3970,8 @@ Abuse Report [mthnum,datetime,slt]/[day,datetime,slt] none/none - Can't load images larger than [PIXELS] pixels + Can't load images larger than [PIXELS] pixels + Can't load images larger than [WIDTH]*[HEIGHT] Incorrect image format. File is empty. Max outfit photo size is [WIDTH]*[HEIGHT]. Please resize or use another image -- cgit v1.3 From 1f608d833e16ed7f0762a3f860cec8aedeaf98c3 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> Date: Wed, 15 Oct 2025 20:37:25 +0300 Subject: p#490 Fix missing Lossless check that broke sculpt upload --- indra/newview/llfloaterimagepreview.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'indra/newview/llfloaterimagepreview.cpp') diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp index 550c3adc27..c924807273 100644 --- a/indra/newview/llfloaterimagepreview.cpp +++ b/indra/newview/llfloaterimagepreview.cpp @@ -267,6 +267,14 @@ void LLFloaterImagePreview::onBtnOK() LLPointer formatted = new LLImageJ2C; + if (mRawImagep->getWidth() * mRawImagep->getHeight() <= LL_IMAGE_REZ_LOSSLESS_CUTOFF * LL_IMAGE_REZ_LOSSLESS_CUTOFF) + { + if (gSavedSettings.getBOOL("LosslessJ2CUpload")) + { + formatted->setReversible(true); + } + } + if (formatted->encode(mRawImagep, 0.0f)) { LLFileSystem fmt_file(new_asset_id, LLAssetType::AT_TEXTURE, LLFileSystem::WRITE); -- cgit v1.3 From 7b2c3f7a22b0df319348224072b14448b1d0f54b Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> Date: Fri, 21 Nov 2025 05:31:30 +0200 Subject: #5026 Upload To Folder feature not working --- indra/newview/llfloaterbulkupload.cpp | 3 ++- indra/newview/llfloaterbulkupload.h | 1 + indra/newview/llfloaterimagepreview.cpp | 3 ++- indra/newview/llmaterialeditor.cpp | 7 +++++-- indra/newview/llviewerassetupload.cpp | 22 ++++++++++++---------- indra/newview/llviewermenufile.cpp | 14 ++++++++------ indra/newview/llviewermenufile.h | 2 +- 7 files changed, 31 insertions(+), 21 deletions(-) (limited to 'indra/newview/llfloaterimagepreview.cpp') diff --git a/indra/newview/llfloaterbulkupload.cpp b/indra/newview/llfloaterbulkupload.cpp index b898cb28b6..d11e9949f6 100644 --- a/indra/newview/llfloaterbulkupload.cpp +++ b/indra/newview/llfloaterbulkupload.cpp @@ -41,6 +41,7 @@ LLFloaterBulkUpload::LLFloaterBulkUpload(const LLSD& key) mUploadCost = key["upload_cost"].asInteger(); mUploadCount = key["upload_count"].asInteger(); mHas2kTextures = key["has_2k_textures"].asBoolean(); + mDestinationFolderId = key["dest"]; if (key["files"].isArray()) { const LLSD& files = key["files"]; @@ -125,7 +126,7 @@ void LLFloaterBulkUpload::onUpload2KCheckBox() void LLFloaterBulkUpload::onClickUpload() { - do_bulk_upload(mFiles, mAllow2kTextures); + do_bulk_upload(mFiles, mAllow2kTextures, mDestinationFolderId); closeFloater(); } diff --git a/indra/newview/llfloaterbulkupload.h b/indra/newview/llfloaterbulkupload.h index d07dc8eabe..3d3004d84d 100644 --- a/indra/newview/llfloaterbulkupload.h +++ b/indra/newview/llfloaterbulkupload.h @@ -59,6 +59,7 @@ private: std::vector mFiles; bool mAllow2kTextures = true; bool mHas2kTextures = false; + LLUUID mDestinationFolderId; S32 mUploadCost = 0; S32 mUploadCount = 0; }; diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp index c924807273..82b5fd23fc 100644 --- a/indra/newview/llfloaterimagepreview.cpp +++ b/indra/newview/llfloaterimagepreview.cpp @@ -289,7 +289,8 @@ void LLFloaterImagePreview::onBtnOK() LLFloaterPerms::getNextOwnerPerms("Uploads"), LLFloaterPerms::getGroupPerms("Uploads"), LLFloaterPerms::getEveryonePerms("Uploads"), - expected_upload_cost + expected_upload_cost, + mDestinationFolderId )); upload_new_resource(assetUploadInfo); diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index cac72bb085..cbd95f9cc6 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1987,12 +1987,14 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 ind { // Prespecified material LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor"); + me->mUploadFolder = dest_folder; me->loadMaterial(model_in, filename, index); } else if (model_in.materials.size() == 1) { // Only one material, just load it LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor"); + me->mUploadFolder = dest_folder; me->loadMaterial(model_in, filename, 0); } else @@ -2018,11 +2020,12 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 ind material_list.push_back(LLTrans::getString("material_batch_import_text")); LLFloaterComboOptions::showUI( - [model_in, filename](const std::string& option, S32 index) + [model_in, filename, dest_folder](const std::string& option, S32 index) { if (index >= 0) // -1 on cancel { LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor"); + me->mUploadFolder = dest_folder; me->loadMaterial(model_in, filename, index); } }, @@ -2448,7 +2451,7 @@ void LLMaterialEditor::loadMaterial(const tinygltf::Model &model_in, const std:: if (index == model_in.materials.size()) { // bulk upload all the things - upload_bulk({ filename }, LLFilePicker::FFLOAD_MATERIAL, true, LLUUID::null); + upload_bulk({ filename }, LLFilePicker::FFLOAD_MATERIAL, true, mUploadFolder); return; } diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp index 7d5386110d..5298bd1cfa 100644 --- a/indra/newview/llviewerassetupload.cpp +++ b/indra/newview/llviewerassetupload.cpp @@ -300,17 +300,19 @@ void LLResourceUploadInfo::assignDefaults() { mDescription = "(No Description)"; } - - if (mAssetType == LLAssetType::AT_GLTF || - mAssetType == LLAssetType::AT_GLTF_BIN) + if (mFolderId.isNull()) // don't overwrite if destination is already specified { - mFolderId = LLUUID::null; - } - else - { - mFolderId = gInventory.findUserDefinedCategoryUUIDForType( - (mDestinationFolderType == LLFolderType::FT_NONE) ? - (LLFolderType::EType)mAssetType : mDestinationFolderType); + if (mAssetType == LLAssetType::AT_GLTF || + mAssetType == LLAssetType::AT_GLTF_BIN) + { + mFolderId = LLUUID::null; + } + else + { + mFolderId = gInventory.findUserDefinedCategoryUUIDForType( + (mDestinationFolderType == LLFolderType::FT_NONE) ? + (LLFolderType::EType)mAssetType : mDestinationFolderType); + } } } diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 801ff3c212..fcffde3caf 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -530,7 +530,7 @@ void upload_single_file( return; } -void do_bulk_upload(std::vector filenames, bool allow_2k) +void do_bulk_upload(std::vector filenames, bool allow_2k, const LLUUID& dest) { for (std::vector::const_iterator in_iter = filenames.begin(); in_iter != filenames.end(); ++in_iter) { @@ -650,7 +650,8 @@ void do_bulk_upload(std::vector filenames, bool allow_2k) LLFloaterPerms::getNextOwnerPerms("Uploads"), LLFloaterPerms::getGroupPerms("Uploads"), LLFloaterPerms::getEveryonePerms("Uploads"), - LLAgentBenefitsMgr::current().getTextureUploadCost(raw_image->getWidth(), raw_image->getHeight()) + LLAgentBenefitsMgr::current().getTextureUploadCost(raw_image->getWidth(), raw_image->getHeight()), + dest )); upload_new_resource(assetUploadInfo); @@ -666,7 +667,8 @@ void do_bulk_upload(std::vector filenames, bool allow_2k) LLFloaterPerms::getNextOwnerPerms("Uploads"), LLFloaterPerms::getGroupPerms("Uploads"), LLFloaterPerms::getEveryonePerms("Uploads"), - expected_upload_cost); + expected_upload_cost, + dest); LLResourceUploadInfo::ptr_t uploadInfo(info_p); upload_new_resource(uploadInfo); @@ -687,14 +689,14 @@ void do_bulk_upload(std::vector filenames, bool allow_2k) // Todo: // 1. Decouple bulk upload from material editor // 2. Take into account possiblity of identical textures - LLMaterialEditor::uploadMaterialFromModel(filename, model, i); + LLMaterialEditor::uploadMaterialFromModel(filename, model, i, dest); } } } } } -void do_bulk_upload(std::vector filenames, bool allow_2k, const LLSD& notification, const LLSD& response) +void do_bulk_upload(std::vector filenames, bool allow_2k, const LLSD& notification, const LLSD& response, const LLUUID& dest) { S32 option = LLNotificationsUtil::getSelectedOption(notification, response); if (option != 0) @@ -703,7 +705,7 @@ void do_bulk_upload(std::vector filenames, bool allow_2k, const LLS return; } - do_bulk_upload(filenames, allow_2k); + do_bulk_upload(filenames, allow_2k, dest); } bool get_bulk_upload_expected_cost( diff --git a/indra/newview/llviewermenufile.h b/indra/newview/llviewermenufile.h index 8f7df48a2e..e40dd84bc9 100644 --- a/indra/newview/llviewermenufile.h +++ b/indra/newview/llviewermenufile.h @@ -72,7 +72,7 @@ bool get_bulk_upload_expected_cost( S32& bvh_count, S32& textures_2k_count); -void do_bulk_upload(std::vector filenames, bool allow_2k); +void do_bulk_upload(std::vector filenames, bool allow_2k, const LLUUID &dest_folder); void upload_single_file( const std::vector& filenames, -- cgit v1.3