6969#include " llviewerassetupload.h"
7070
7171// linden libraries
72+ #include " llfilesystem.h"
7273#include " llnotificationsutil.h"
7374#include " llsdserialize.h"
7475#include " llsdutil.h"
@@ -544,16 +545,9 @@ void do_bulk_upload(std::vector<std::string> filenames, bool allow_2k)
544545 if (LLResourceUploadInfo::findAssetTypeAndCodecOfExtension (ext, asset_type, codec))
545546 {
546547 bool resource_upload = false ;
547- if (asset_type == LLAssetType::AT_TEXTURE && allow_2k )
548+ if (asset_type == LLAssetType::AT_TEXTURE )
548549 {
549- LLPointer<LLImageFormatted> image_frmted = LLImageFormatted::createFromType (codec);
550- if (gDirUtilp ->fileExists (filename) && image_frmted && image_frmted->load (filename))
551- {
552- S32 biased_width = LLImageRaw::biasedDimToPowerOfTwo (image_frmted->getWidth (), LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT );
553- S32 biased_height = LLImageRaw::biasedDimToPowerOfTwo (image_frmted->getHeight (), LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT );
554- expected_upload_cost = LLAgentBenefitsMgr::current ().getTextureUploadCost (biased_width, biased_height);
555- resource_upload = true ;
556- }
550+ resource_upload = true ;
557551 }
558552 else if (LLAgentBenefitsMgr::current ().findUploadCost (asset_type, expected_upload_cost))
559553 {
@@ -562,23 +556,115 @@ void do_bulk_upload(std::vector<std::string> filenames, bool allow_2k)
562556
563557 if (resource_upload)
564558 {
565- LLNewFileResourceUploadInfo* info_p = new LLNewFileResourceUploadInfo (
566- filename,
567- asset_name,
568- asset_name, 0 ,
569- LLFolderType::FT_NONE , LLInventoryType::IT_NONE ,
570- LLFloaterPerms::getNextOwnerPerms (" Uploads" ),
571- LLFloaterPerms::getGroupPerms (" Uploads" ),
572- LLFloaterPerms::getEveryonePerms (" Uploads" ),
573- expected_upload_cost);
574-
575- if (!allow_2k)
559+ if (asset_type == LLAssetType::AT_TEXTURE )
576560 {
577- info_p->setMaxImageSize (1024 );
578- }
579- LLResourceUploadInfo::ptr_t uploadInfo (info_p);
561+ std::string exten = gDirUtilp ->getExtension (filename);
562+ U32 codec = LLImageBase::getCodecFromExtension (exten);
563+
564+ // Load the image
565+ LLPointer<LLImageFormatted> image = LLImageFormatted::createFromType (codec);
566+ if (image.isNull ())
567+ {
568+ LL_WARNS () << " Failed to create image container for " << filename << LL_ENDL ;
569+ continue ;
570+ }
571+ if (!image->load (filename))
572+ {
573+ LL_WARNS () << " Failed to load image: " << filename << LL_ENDL ;
574+ continue ;
575+ }
576+ // Decompress or expand it in a raw image structure
577+ LLPointer<LLImageRaw> raw_image = new LLImageRaw;
578+ if (!image->decode (raw_image, 0 .0f ))
579+ {
580+ LL_WARNS () << " Failed to decode image: " << filename << LL_ENDL ;
581+ continue ;
582+ }
583+ // Check the image constraints
584+ if ((image->getComponents () != 3 ) && (image->getComponents () != 4 ))
585+ {
586+ LL_WARNS () << " Attempted to upload a texture that has " << image->getComponents ()
587+ << " components, but only 3 (RGB) or 4 (RGBA) are allowed." << LL_ENDL ;
588+ continue ;
589+ }
590+ // Downscale images to fit the max_texture_dimensions_*, or 1024 if allow_2k is false
591+ S32 max_width = allow_2k ? gSavedSettings .getS32 (" max_texture_dimension_X" ) : 1024 ;
592+ S32 max_height = allow_2k ? gSavedSettings .getS32 (" max_texture_dimension_Y" ) : 1024 ;
593+
594+ S32 orig_width = raw_image->getWidth ();
595+ S32 orig_height = raw_image->getHeight ();
596+
597+ if (orig_width > max_width || orig_height > max_height)
598+ {
599+ // Calculate scale factors
600+ F32 width_scale = (F32 )max_width / (F32 )orig_width;
601+ F32 height_scale = (F32 )max_height / (F32 )orig_height;
602+ F32 scale = llmin (width_scale, height_scale);
603+
604+ // Calculate new dimensions, preserving aspect ratio
605+ S32 new_width = LLImageRaw::contractDimToPowerOfTwo (llclamp ((S32 )llroundf (orig_width * scale), 4 , max_width));
606+ S32 new_height = LLImageRaw::contractDimToPowerOfTwo (llclamp ((S32 )llroundf (orig_height * scale), 4 , max_height));
607+
608+ if (!raw_image->scale (new_width, new_height))
609+ {
610+ LL_WARNS () << " Failed to scale image from " << orig_width << " x" << orig_height << " to " << new_width << " x"
611+ << new_height << LL_ENDL ;
612+ continue ;
613+ }
614+
615+ // Inform the resident about the resized image
616+ LLSD subs;
617+ subs[" [ORIGINAL_WIDTH]" ] = orig_width;
618+ subs[" [ORIGINAL_HEIGHT]" ] = orig_height;
619+ subs[" [NEW_WIDTH]" ] = new_width;
620+ subs[" [NEW_HEIGHT]" ] = new_height;
621+ subs[" [MAX_WIDTH]" ] = max_width;
622+ subs[" [MAX_HEIGHT]" ] = max_height;
623+ LLNotificationsUtil::add (" ImageUploadResized" , subs);
624+ }
625+
626+ raw_image->biasedScaleToPowerOfTwo (LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT );
627+
628+ LLTransactionID tid;
629+ tid.generate ();
630+ LLAssetID new_asset_id = tid.makeAssetID (gAgent .getSecureSessionID ());
580631
581- upload_new_resource (uploadInfo);
632+ LLPointer<LLImageJ2C> formatted = new LLImageJ2C;
633+
634+ if (formatted->encode (raw_image, 0 .0f ))
635+ {
636+ LLFileSystem fmt_file (new_asset_id, LLAssetType::AT_TEXTURE , LLFileSystem::WRITE );
637+ fmt_file.write (formatted->getData (), formatted->getDataSize ());
638+
639+ LLResourceUploadInfo::ptr_t assetUploadInfo (new LLResourceUploadInfo (
640+ tid, LLAssetType::AT_TEXTURE ,
641+ asset_name,
642+ asset_name, 0 ,
643+ LLFolderType::FT_NONE , LLInventoryType::IT_NONE ,
644+ LLFloaterPerms::getNextOwnerPerms (" Uploads" ),
645+ LLFloaterPerms::getGroupPerms (" Uploads" ),
646+ LLFloaterPerms::getEveryonePerms (" Uploads" ),
647+ LLAgentBenefitsMgr::current ().getTextureUploadCost (raw_image->getWidth (), raw_image->getHeight ())
648+ ));
649+
650+ upload_new_resource (assetUploadInfo);
651+ }
652+ }
653+ else
654+ {
655+ LLNewFileResourceUploadInfo* info_p = new LLNewFileResourceUploadInfo (
656+ filename,
657+ asset_name,
658+ asset_name, 0 ,
659+ LLFolderType::FT_NONE , LLInventoryType::IT_NONE ,
660+ LLFloaterPerms::getNextOwnerPerms (" Uploads" ),
661+ LLFloaterPerms::getGroupPerms (" Uploads" ),
662+ LLFloaterPerms::getEveryonePerms (" Uploads" ),
663+ expected_upload_cost);
664+ LLResourceUploadInfo::ptr_t uploadInfo (info_p);
665+
666+ upload_new_resource (uploadInfo);
667+ }
582668 }
583669 }
584670
@@ -647,8 +733,31 @@ bool get_bulk_upload_expected_cost(
647733 LLPointer<LLImageFormatted> image_frmted = LLImageFormatted::createFromType (codec);
648734 if (gDirUtilp ->fileExists (filename) && image_frmted && image_frmted->load (filename))
649735 {
650- S32 biased_width = LLImageRaw::biasedDimToPowerOfTwo (image_frmted->getWidth (), LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT );
651- S32 biased_height = LLImageRaw::biasedDimToPowerOfTwo (image_frmted->getHeight (), LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT );
736+ S32 biased_width, biased_height;
737+
738+ S32 max_width = allow_2k ? gSavedSettings .getS32 (" max_texture_dimension_X" ) : 1024 ;
739+ S32 max_height = allow_2k ? gSavedSettings .getS32 (" max_texture_dimension_Y" ) : 1024 ;
740+
741+ S32 orig_width = image_frmted->getWidth ();
742+ S32 orig_height = image_frmted->getHeight ();
743+
744+ if (orig_width > max_width || orig_height > max_height)
745+ {
746+ // Calculate scale factors
747+ F32 width_scale = (F32 )max_width / (F32 )orig_width;
748+ F32 height_scale = (F32 )max_height / (F32 )orig_height;
749+ F32 scale = llmin (width_scale, height_scale);
750+
751+ // Calculate new dimensions, preserving aspect ratio
752+ biased_width = LLImageRaw::contractDimToPowerOfTwo (llclamp ((S32 )llroundf (orig_width * scale), 4 , max_width));
753+ biased_height = LLImageRaw::contractDimToPowerOfTwo (llclamp ((S32 )llroundf (orig_height * scale), 4 , max_height));
754+ }
755+ else
756+ {
757+ biased_width = LLImageRaw::biasedDimToPowerOfTwo (orig_width, LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT );
758+ biased_height = LLImageRaw::biasedDimToPowerOfTwo (orig_height, LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT );
759+ }
760+
652761 total_cost += LLAgentBenefitsMgr::current ().getTextureUploadCost (biased_width, biased_height);
653762 S32 area = biased_width * biased_height;
654763 if (area >= LLAgentBenefits::MIN_2K_TEXTURE_AREA )
0 commit comments