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 calculationmaster
parent
afdcd356db
commit
533390a531
|
|
@ -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<LLUICtrl>("ok_btn")->setCommitCallback(boost::bind(&LLFloaterNameDesc::onBtnOK, this));
|
||||
getChild<LLUICtrl>("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<LLImageJ2C> 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<LLUICtrl>("name_form")->getValue().asString(),
|
||||
getChild<LLUICtrl>("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<LLImageFormatted> 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;
|
||||
|
|
|
|||
|
|
@ -126,6 +126,8 @@ public:
|
|||
|
||||
void clearAllPreviewTextures();
|
||||
|
||||
void onBtnOK();
|
||||
|
||||
protected:
|
||||
static void onPreviewTypeCommit(LLUICtrl*,void*);
|
||||
void draw() override;
|
||||
|
|
|
|||
|
|
@ -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<std::string> 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<LLImageFormatted> 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<std::string> 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);
|
||||
|
||||
upload_new_resource(uploadInfo);
|
||||
// Load the image
|
||||
LLPointer<LLImageFormatted> 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<LLImageRaw> 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());
|
||||
|
||||
LLPointer<LLImageJ2C> 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<LLImageFormatted> 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)
|
||||
|
|
|
|||
|
|
@ -12619,4 +12619,15 @@ are wearing now.
|
|||
Unable to apply material to the water exclusion surface.
|
||||
<tag>fail</tag>
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="notify.tga"
|
||||
name="ImageUploadResized"
|
||||
type="alertmodal">
|
||||
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.
|
||||
<usetemplate
|
||||
ignoretext="Image Upload Resized"
|
||||
name="okignore"
|
||||
yestext="OK"/>
|
||||
</notification>
|
||||
</notifications>
|
||||
|
|
|
|||
Loading…
Reference in New Issue