void LLFloaterColorPicker::createUI () { // create RGB type area (not really RGB but it's got R,G & B in it.,.. LLPointer<LLImageRaw> raw = new LLImageRaw ( mRGBViewerImageWidth, mRGBViewerImageHeight, mComponents ); U8* bits = raw->getData(); S32 linesize = mRGBViewerImageWidth * mComponents; for ( S32 y = 0; y < mRGBViewerImageHeight; ++y ) { for ( S32 x = 0; x < linesize; x += mComponents ) { F32 rVal, gVal, bVal; hslToRgb ( (F32)x / (F32) ( linesize - 1 ), (F32)y / (F32) ( mRGBViewerImageHeight - 1 ), 0.5f, rVal, gVal, bVal ); * ( bits + x + y * linesize + 0 ) = ( U8 )( rVal * 255.0f ); * ( bits + x + y * linesize + 1 ) = ( U8 )( gVal * 255.0f ); * ( bits + x + y * linesize + 2 ) = ( U8 )( bVal * 255.0f ); } } mRGBImage = LLViewerTextureManager::getLocalTexture( (LLImageRaw*)raw, FALSE ); gGL.getTexUnit(0)->bind(mRGBImage); mRGBImage->setAddressMode(LLTexUnit::TAM_CLAMP); // create palette for ( S32 each = 0; each < numPaletteColumns * numPaletteRows; ++each ) { mPalette.push_back(new LLColor4(LLUIColorTable::instance().getColor(llformat("ColorPaletteEntry%02d", each + 1)))); } }
// allocate the stack LLWorld::LLWorld() : mLandFarClip(DEFAULT_FAR_PLANE), mLastPacketsIn(0), mLastPacketsOut(0), mLastPacketsLost(0), mSpaceTimeUSec(0) { for (S32 i = 0; i < 8; i++) { mEdgeWaterObjects[i] = NULL; } if (gNoRender) { return; } LLPointer<LLImageRaw> raw = new LLImageRaw(1,1,4); U8 *default_texture = raw->getData(); *(default_texture++) = MAX_WATER_COLOR.mV[0]; *(default_texture++) = MAX_WATER_COLOR.mV[1]; *(default_texture++) = MAX_WATER_COLOR.mV[2]; *(default_texture++) = MAX_WATER_COLOR.mV[3]; mDefaultWaterTexturep = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE); gGL.getTexUnit(0)->bind(mDefaultWaterTexturep); mDefaultWaterTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); }
// static void LLFloaterAuction::onClickSnapshot(void* data) { LLFloaterAuction* self = (LLFloaterAuction*)(data); LLPointer<LLImageRaw> raw = new LLImageRaw; gForceRenderLandFence = self->getChild<LLUICtrl>("fence_check")->getValue().asBoolean(); BOOL success = gViewerWindow->rawSnapshot(raw, gViewerWindow->getWindowWidthScaled(), gViewerWindow->getWindowHeightScaled(), TRUE, FALSE, FALSE, FALSE); gForceRenderLandFence = FALSE; if (success) { self->mTransactionID.generate(); self->mImageID = self->mTransactionID.makeAssetID(gAgent.getSecureSessionID()); // <FS:PP> FIRE-8190: Preview function for "UI Sounds" Panel // if(!gSavedSettings.getBOOL("QuietSnapshotsToDisk")) if(!gSavedSettings.getBOOL("PlayModeUISndSnapshot")) // </FS:PP> FIRE-8190: Preview function for "UI Sounds" Panel { gViewerWindow->playSnapshotAnimAndSound(); } llinfos << "Writing TGA..." << llendl; LLPointer<LLImageTGA> tga = new LLImageTGA; tga->encode(raw); LLVFile::writeFile(tga->getData(), tga->getDataSize(), gVFS, self->mImageID, LLAssetType::AT_IMAGE_TGA); raw->biasedScaleToPowerOfTwo(LLViewerTexture::MAX_IMAGE_SIZE_DEFAULT); llinfos << "Writing J2C..." << llendl; LLPointer<LLImageJ2C> j2c = new LLImageJ2C; j2c->encode(raw, 0.0f); LLVFile::writeFile(j2c->getData(), j2c->getDataSize(), gVFS, self->mImageID, LLAssetType::AT_TEXTURE); self->mImage = LLViewerTextureManager::getLocalTexture((LLImageRaw*)raw, FALSE); gGL.getTexUnit(0)->bind(self->mImage); self->mImage->setAddressMode(LLTexUnit::TAM_CLAMP); } else { llwarns << "Unable to take snapshot" << llendl; } }
// static void LLFloaterAuction::onClickSnapshot(void* data) { LLFloaterAuction* self = (LLFloaterAuction*)(data); LLPointer<LLImageRaw> raw = new LLImageRaw; gForceRenderLandFence = self->childGetValue("fence_check").asBoolean(); BOOL success = gViewerWindow->rawSnapshot(raw, gViewerWindow->getWindowWidth(), gViewerWindow->getWindowHeight(), TRUE, FALSE, FALSE, FALSE); gForceRenderLandFence = FALSE; if (success) { self->mTransactionID.generate(); self->mImageID = self->mTransactionID.makeAssetID(gAgent.getSecureSessionID()); if(!gSavedSettings.getBOOL("QuietSnapshotsToDisk")) { gViewerWindow->playSnapshotAnimAndSound(); } llinfos << "Writing TGA..." << llendl; LLPointer<LLImageTGA> tga = new LLImageTGA; tga->encode(raw); LLVFile::writeFile(tga->getData(), tga->getDataSize(), gVFS, self->mImageID, LLAssetType::AT_IMAGE_TGA); raw->biasedScaleToPowerOfTwo(LLViewerImage::MAX_IMAGE_SIZE_DEFAULT); llinfos << "Writing J2C..." << llendl; LLPointer<LLImageJ2C> j2c = new LLImageJ2C; j2c->encode(raw, 0.0f); LLVFile::writeFile(j2c->getData(), j2c->getDataSize(), gVFS, self->mImageID, LLAssetType::AT_TEXTURE); self->mImage = new LLImageGL((LLImageRaw*)raw, FALSE); self->mImage->bind(); self->mImage->setClamp(TRUE, TRUE); } else { llwarns << "Unable to take snapshot" << llendl; } }
void LLFloaterColorPicker:: createUI () { // build the majority of the gui using the factory builder LLUICtrlFactory::getInstance()->buildFloater ( this, "floater_color_picker.xml" ); setVisible ( FALSE ); // create RGB type area (not really RGB but it's got R,G & B in it.,.. LLPointer<LLImageRaw> raw = new LLImageRaw ( mRGBViewerImageWidth, mRGBViewerImageHeight, mComponents ); U8* bits = raw->getData(); S32 linesize = mRGBViewerImageWidth * mComponents; for ( S32 y = 0; y < mRGBViewerImageHeight; ++y ) { for ( S32 x = 0; x < linesize; x += mComponents ) { F32 rVal, gVal, bVal; hslToRgb ( (F32)x / (F32) ( linesize - 1 ), (F32)y / (F32) ( mRGBViewerImageHeight - 1 ), 0.5f, rVal, gVal, bVal ); * ( bits + x + y * linesize + 0 ) = ( U8 )( rVal * 255.0f ); * ( bits + x + y * linesize + 1 ) = ( U8 )( gVal * 255.0f ); * ( bits + x + y * linesize + 2 ) = ( U8 )( bVal * 255.0f ); } } mRGBImage = new LLImageGL ( (LLImageRaw*)raw, FALSE ); gGL.getTexUnit(0)->bind(mRGBImage); mRGBImage->setAddressMode(LLTexUnit::TAM_CLAMP); // create palette for ( S32 each = 0; each < numPaletteColumns * numPaletteRows; ++each ) { std::ostringstream codec; codec << "ColorPaletteEntry" << std::setfill ( '0' ) << std::setw ( 2 ) << each + 1; // argh! const std::string s ( codec.str () ); mPalette.push_back ( new LLColor4 ( gSavedSettings.getColor4 ( s ) ) ); } }
// static void LLPostCard::send(LLPointer<LLImageFormatted> image, const LLSD& postcard_data) { // <FS:ND> Crashfix; image can end up being 0 if( image.isNull() ) { llwarns << "Passed invalid image into LLPostcard::send() [0 pointer]" << llendl; return; } // </FS:ND> LLTransactionID transaction_id; LLAssetID asset_id; transaction_id.generate(); asset_id = transaction_id.makeAssetID(gAgent.getSecureSessionID()); LLVFile::writeFile(image->getData(), image->getDataSize(), gVFS, asset_id, LLAssetType::AT_IMAGE_JPEG); // upload the image std::string url = gAgent.getRegion()->getCapability("SendPostcard"); if (!url.empty()) { llinfos << "Sending postcard via capability" << llendl; // the capability already encodes: agent ID, region ID LL_DEBUGS("Snapshots") << "url: " << url << llendl; LL_DEBUGS("Snapshots") << "body: " << postcard_data << llendl; LL_DEBUGS("Snapshots") << "data size: " << image->getDataSize() << llendl; LLHTTPClient::post(url, postcard_data, new LLPostcardSendResponder(postcard_data, asset_id, LLAssetType::AT_IMAGE_JPEG)); } else { llinfos << "Sending postcard" << llendl; LLSD* data = new LLSD(postcard_data); (*data)["asset-id"] = asset_id; gAssetStorage->storeAssetData(transaction_id, LLAssetType::AT_IMAGE_JPEG, &postcard_upload_callback, (void *)data, FALSE); } }
void LLSurface::createSTexture() { if (!mSTexturep) { // Fill with dummy gray data. LLPointer<LLImageRaw> raw = new LLImageRaw(sTextureSize, sTextureSize, 3); U8 *default_texture = raw->getData(); for (S32 i = 0; i < sTextureSize; i++) { for (S32 j = 0; j < sTextureSize; j++) { *(default_texture + (i*sTextureSize + j)*3) = 128; *(default_texture + (i*sTextureSize + j)*3 + 1) = 128; *(default_texture + (i*sTextureSize + j)*3 + 2) = 128; } } mSTexturep = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE); mSTexturep->dontDiscard(); gGL.getTexUnit(0)->bind(mSTexturep); mSTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); } }
void LLSurface::createWaterTexture() { if (!mWaterTexturep) { // Create the water texture LLPointer<LLImageRaw> raw = new LLImageRaw(sTextureSize/2, sTextureSize/2, 4); U8 *default_texture = raw->getData(); for (S32 i = 0; i < sTextureSize/2; i++) { for (S32 j = 0; j < sTextureSize/2; j++) { *(default_texture + (i*sTextureSize/2 + j)*4) = MAX_WATER_COLOR.mV[0]; *(default_texture + (i*sTextureSize/2 + j)*4 + 1) = MAX_WATER_COLOR.mV[1]; *(default_texture + (i*sTextureSize/2 + j)*4 + 2) = MAX_WATER_COLOR.mV[2]; *(default_texture + (i*sTextureSize/2 + j)*4 + 3) = MAX_WATER_COLOR.mV[3]; } } mWaterTexturep = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE); mWaterTexturep->dontDiscard(); gGL.getTexUnit(0)->bind(mWaterTexturep); mWaterTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); } }
BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, const F32 width, const F32 height) { llassert(mSurfacep); llassert(x >= 0.f); llassert(y >= 0.f); LLTimer gen_timer; /////////////////////////// // // Generate raw data arrays for surface textures // // // These have already been validated by generateComposition. U8* st_data[4]; S32 st_data_size[4]; // for debugging for (S32 i = 0; i < 4; i++) { if (mRawImages[i].isNull()) { // Read back a raw image for this discard level, if it exists mRawImages[i] = new LLImageRaw; S32 min_dim = llmin(mDetailTextures[i]->getWidth(0), mDetailTextures[i]->getHeight(0)); S32 ddiscard = 0; while (min_dim > BASE_SIZE && ddiscard < MAX_DISCARD_LEVEL) { ddiscard++; min_dim /= 2; } mRawImages[i] = mDetailTextures[i]->getCachedRawImage() ; if (!mRawImages[i]) { llwarns << "no cached raw data for terrain detail texture: " << mDetailTextures[i]->getID() << llendl; return FALSE; } if (mDetailTextures[i]->getWidth(ddiscard) != BASE_SIZE || mDetailTextures[i]->getHeight(ddiscard) != BASE_SIZE || mDetailTextures[i]->getComponents() != 3) { LLPointer<LLImageRaw> newraw = new LLImageRaw(BASE_SIZE, BASE_SIZE, 3); newraw->composite(mRawImages[i]); mRawImages[i] = newraw; // deletes old } } st_data[i] = mRawImages[i]->getData(); st_data_size[i] = mRawImages[i]->getDataSize(); } /////////////////////////////////////// // // Generate and clamp x/y bounding box. // // S32 x_begin, y_begin, x_end, y_end; x_begin = (S32)(x * mScaleInv); y_begin = (S32)(y * mScaleInv); x_end = llround( (x + width) * mScaleInv ); y_end = llround( (y + width) * mScaleInv ); if (x_end > mWidth) { llwarns << "x end > width" << llendl; x_end = mWidth; } if (y_end > mWidth) { llwarns << "y end > width" << llendl; y_end = mWidth; } /////////////////////////////////////////// // // Generate target texture information, stride ratios. // // LLViewerImage *texturep; U32 tex_width, tex_height, tex_comps; U32 tex_stride; F32 tex_x_scalef, tex_y_scalef; S32 tex_x_begin, tex_y_begin, tex_x_end, tex_y_end; F32 tex_x_ratiof, tex_y_ratiof; texturep = mSurfacep->getSTexture(); tex_width = texturep->getWidth(); tex_height = texturep->getHeight(); tex_comps = texturep->getComponents(); tex_stride = tex_width * tex_comps; S32 st_comps = 3; S32 st_width = BASE_SIZE; S32 st_height = BASE_SIZE; if (tex_comps != st_comps) { llwarns << "Base texture comps != input texture comps" << llendl; return FALSE; } tex_x_scalef = (F32)tex_width / (F32)mWidth; tex_y_scalef = (F32)tex_height / (F32)mWidth; tex_x_begin = (S32)((F32)x_begin * tex_x_scalef); tex_y_begin = (S32)((F32)y_begin * tex_y_scalef); tex_x_end = (S32)((F32)x_end * tex_x_scalef); tex_y_end = (S32)((F32)y_end * tex_y_scalef); tex_x_ratiof = (F32)mWidth*mScale / (F32)tex_width; tex_y_ratiof = (F32)mWidth*mScale / (F32)tex_height; LLPointer<LLImageRaw> raw = new LLImageRaw(tex_width, tex_height, tex_comps); U8 *rawp = raw->getData(); F32 tex_width_inv = 1.f/tex_width; F32 tex_height_inv = 1.f/tex_height; F32 st_x_stride, st_y_stride; st_x_stride = ((F32)st_width / (F32)mTexScaleX)*((F32)mWidth / (F32)tex_width); st_y_stride = ((F32)st_height / (F32)mTexScaleY)*((F32)mWidth / (F32)tex_height); llassert(st_x_stride > 0.f); llassert(st_y_stride > 0.f); //////////////////////////////// // // Iterate through the target texture, striding through the // subtextures and interpolating appropriately. // // F32 sti, stj; S32 st_offset; sti = (tex_x_begin * st_x_stride) - st_width*(llfloor((tex_x_begin * st_x_stride)/st_width)); stj = (tex_y_begin * st_y_stride) - st_height*(llfloor((tex_y_begin * st_y_stride)/st_height)); st_offset = (llfloor(stj * st_width) + llfloor(sti)) * st_comps; for (S32 j = tex_y_begin; j < tex_y_end; j++) { U32 offset = j * tex_stride + tex_x_begin * tex_comps; sti = (tex_x_begin * st_x_stride) - st_width*((U32)(tex_x_begin * st_x_stride)/st_width); for (S32 i = tex_x_begin; i < tex_x_end; i++) { S32 tex0, tex1; F32 composition = getValueScaled(i*tex_x_ratiof, j*tex_y_ratiof); tex0 = llfloor( composition ); tex0 = llclamp(tex0, 0, 3); composition -= tex0; tex1 = tex0 + 1; tex1 = llclamp(tex1, 0, 3); F32 xy_int_i, xy_int_j; xy_int_i = i * tex_width_inv; xy_int_j = j * tex_height_inv; st_offset = (lltrunc(sti) + lltrunc(stj)*st_width) * st_comps; for (U32 k = 0; k < tex_comps; k++) { // Linearly interpolate based on composition. if (st_offset >= st_data_size[tex0] || st_offset >= st_data_size[tex1]) { // SJB: This shouldn't be happening, but does... Rounding error? //llwarns << "offset 0 [" << tex0 << "] =" << st_offset << " >= size=" << st_data_size[tex0] << llendl; //llwarns << "offset 1 [" << tex1 << "] =" << st_offset << " >= size=" << st_data_size[tex1] << llendl; } else { F32 a = *(st_data[tex0] + st_offset); F32 b = *(st_data[tex1] + st_offset); rawp[ offset ] = (U8)lltrunc( a + composition * (b - a) ); } offset++; st_offset++; } sti += st_x_stride; if (sti >= st_width) { sti -= st_width; } } stj += st_y_stride; if (stj >= st_height) { stj -= st_height; } } texturep->setSubImage(raw, tex_x_begin, tex_y_begin, tex_x_end - tex_x_begin, tex_y_end - tex_y_begin); LLSurface::sTextureUpdateTime += gen_timer.getElapsedTimeF32(); LLSurface::sTexelsUpdated += (tex_x_end - tex_x_begin) * (tex_y_end - tex_y_begin); for (S32 i = 0; i < 4; i++) { // Un-boost detatil textures (will get re-boosted if rendering in high detail) mDetailTextures[i]->setBoostLevel(LLViewerImageBoostLevel::BOOST_NONE); mDetailTextures[i]->setMinDiscardLevel(MAX_DISCARD_LEVEL + 1); } return TRUE; }
void render_disconnected_background() { if (!gDisconnectedImagep && gDisconnected) { llinfos << "Loading last bitmap..." << llendl; std::string temp_str; temp_str = gDirUtilp->getLindenUserDir() + gDirUtilp->getDirDelimiter() + SCREEN_LAST_FILENAME; LLPointer<LLImageBMP> image_bmp = new LLImageBMP; if( !image_bmp->load(temp_str) ) { //llinfos << "Bitmap load failed" << llendl; return; } LLPointer<LLImageRaw> raw = new LLImageRaw; if (!image_bmp->decode(raw, 0.0f)) { llinfos << "Bitmap decode failed" << llendl; gDisconnectedImagep = NULL; return; } U8 *rawp = raw->getData(); S32 npixels = (S32)image_bmp->getWidth()*(S32)image_bmp->getHeight(); for (S32 i = 0; i < npixels; i++) { S32 sum = 0; sum = *rawp + *(rawp+1) + *(rawp+2); sum /= 3; *rawp = ((S32)sum*6 + *rawp)/7; rawp++; *rawp = ((S32)sum*6 + *rawp)/7; rawp++; *rawp = ((S32)sum*6 + *rawp)/7; rawp++; } raw->expandToPowerOfTwo(); gDisconnectedImagep = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE ); gStartTexture = gDisconnectedImagep; } // Make sure the progress view always fills the entire window. S32 width = gViewerWindow->getWindowWidthScaled(); S32 height = gViewerWindow->getWindowHeightScaled(); if (gDisconnectedImagep) { if (LLGLSLShader::sNoFixedFunction) { gUIProgram.bind(); } LLGLSUIDefault gls_ui; gViewerWindow->setup2DRender(); gGL.pushMatrix(); { // scale ui to reflect UIScaleFactor // this can't be done in setup2DRender because it requires a // pushMatrix/popMatrix pair const LLVector2& display_scale = gViewerWindow->getDisplayScale(); gGL.scalef(display_scale.mV[VX], display_scale.mV[VY], 1.f); gGL.getTexUnit(0)->bind(gDisconnectedImagep); gGL.color4f(1.f, 1.f, 1.f, 1.f); gl_rect_2d_simple_tex(width, height); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } gGL.popMatrix(); gGL.flush(); if (LLGLSLShader::sNoFixedFunction) { gUIProgram.unbind(); } } }
void render_disconnected_background() { if (!gDisconnectedImagep && gDisconnected) { llinfos << "Loading last bitmap..." << llendl; char temp_str[MAX_PATH]; /* Flawfinder: ignore */ strncpy(temp_str, gDirUtilp->getLindenUserDir().c_str(), MAX_PATH -1); /* Flawfinder: ignore */ temp_str[MAX_PATH -1] = '\0'; strncat(temp_str, gDirUtilp->getDirDelimiter().c_str(), MAX_PATH - strlen(temp_str) -1); /* Flawfinder: ignore */ strcat(temp_str, SCREEN_LAST_FILENAME); /* Flawfinder: ignore */ LLPointer<LLImageBMP> image_bmp = new LLImageBMP; if( !image_bmp->load(temp_str) ) { //llinfos << "Bitmap load failed" << llendl; return; } gDisconnectedImagep = new LLImageGL( FALSE ); LLPointer<LLImageRaw> raw = new LLImageRaw; if (!image_bmp->decode(raw)) { llinfos << "Bitmap decode failed" << llendl; gDisconnectedImagep = NULL; return; } U8 *rawp = raw->getData(); S32 npixels = (S32)image_bmp->getWidth()*(S32)image_bmp->getHeight(); for (S32 i = 0; i < npixels; i++) { S32 sum = 0; sum = *rawp + *(rawp+1) + *(rawp+2); sum /= 3; *rawp = ((S32)sum*6 + *rawp)/7; rawp++; *rawp = ((S32)sum*6 + *rawp)/7; rawp++; *rawp = ((S32)sum*6 + *rawp)/7; rawp++; } raw->expandToPowerOfTwo(); gDisconnectedImagep->createGLTexture(0, raw); gStartImageGL = gDisconnectedImagep; LLImageGL::unbindTexture(0, GL_TEXTURE_2D); } // Make sure the progress view always fills the entire window. S32 width = gViewerWindow->getWindowWidth(); S32 height = gViewerWindow->getWindowHeight(); if (gDisconnectedImagep) { LLGLSUIDefault gls_ui; gViewerWindow->setup2DRender(); glPushMatrix(); { // scale ui to reflect UIScaleFactor // this can't be done in setup2DRender because it requires a // pushMatrix/popMatrix pair const LLVector2& display_scale = gViewerWindow->getDisplayScale(); glScalef(display_scale.mV[VX], display_scale.mV[VY], 1.f); LLViewerImage::bindTexture(gDisconnectedImagep); glColor4f(1.f, 1.f, 1.f, 1.f); gl_rect_2d_simple_tex(width, height); LLImageGL::unbindTexture(0, GL_TEXTURE_2D); } glPopMatrix(); } }
// static void LLWebProfile::post(LLPointer<LLImageFormatted> image, const LLSD& config, const std::string& url) { if (dynamic_cast<LLImagePNG*>(image.get()) == 0) { llwarns << "Image to upload is not a PNG" << llendl; llassert(dynamic_cast<LLImagePNG*>(image.get()) != 0); return; } const std::string boundary = "----------------------------0123abcdefab"; LLSD headers = LLViewerMedia::getHeaders(); headers["Cookie"] = getAuthCookie(); headers["Content-Type"] = "multipart/form-data; boundary=" + boundary; std::ostringstream body; // *NOTE: The order seems to matter. body << "--" << boundary << "\r\n" << "Content-Disposition: form-data; name=\"key\"\r\n\r\n" << config["key"].asString() << "\r\n"; body << "--" << boundary << "\r\n" << "Content-Disposition: form-data; name=\"AWSAccessKeyId\"\r\n\r\n" << config["AWSAccessKeyId"].asString() << "\r\n"; body << "--" << boundary << "\r\n" << "Content-Disposition: form-data; name=\"acl\"\r\n\r\n" << config["acl"].asString() << "\r\n"; body << "--" << boundary << "\r\n" << "Content-Disposition: form-data; name=\"Content-Type\"\r\n\r\n" << config["Content-Type"].asString() << "\r\n"; body << "--" << boundary << "\r\n" << "Content-Disposition: form-data; name=\"policy\"\r\n\r\n" << config["policy"].asString() << "\r\n"; body << "--" << boundary << "\r\n" << "Content-Disposition: form-data; name=\"signature\"\r\n\r\n" << config["signature"].asString() << "\r\n"; body << "--" << boundary << "\r\n" << "Content-Disposition: form-data; name=\"success_action_redirect\"\r\n\r\n" << config["success_action_redirect"].asString() << "\r\n"; body << "--" << boundary << "\r\n" << "Content-Disposition: form-data; name=\"file\"; filename=\"snapshot.png\"\r\n" << "Content-Type: image/png\r\n\r\n"; // Insert the image data. // *FIX: Treating this as a string will probably screw it up ... U8* image_data = image->getData(); for (S32 i = 0; i < image->getDataSize(); ++i) { body << image_data[i]; } body << "\r\n--" << boundary << "--\r\n"; // postRaw() takes ownership of the buffer and releases it later. size_t size = body.str().size(); U8 *data = new U8[size]; memcpy(data, body.str().data(), size); // Send request, successful upload will trigger posting metadata. LLHTTPClient::postRaw(url, data, size, new LLWebProfileResponders::PostImageResponder(), headers); }
// static void LLWebProfile::post(LLPointer<LLImageFormatted> image, const LLSD& config, const std::string& url) { if (dynamic_cast<LLImagePNG*>(image.get()) == 0) { LL_WARNS() << "Image to upload is not a PNG" << LL_ENDL; llassert(dynamic_cast<LLImagePNG*>(image.get()) != 0); return; } const std::string boundary = "----------------------------0123abcdefab"; AIHTTPHeaders headers; headers.addHeader("Accept", "*/*"); headers.addHeader("Cookie", LLWebProfile::getAuthCookie()); headers.addHeader("User-Agent", LLViewerMedia::getCurrentUserAgent()); headers.addHeader("Content-Type", "multipart/form-data; boundary=" + boundary); std::ostringstream body; // *NOTE: The order seems to matter. body << "--" << boundary << "\r\n" << "Content-Disposition: form-data; name=\"key\"\r\n\r\n" << config["key"].asString() << "\r\n"; body << "--" << boundary << "\r\n" << "Content-Disposition: form-data; name=\"AWSAccessKeyId\"\r\n\r\n" << config["AWSAccessKeyId"].asString() << "\r\n"; body << "--" << boundary << "\r\n" << "Content-Disposition: form-data; name=\"acl\"\r\n\r\n" << config["acl"].asString() << "\r\n"; body << "--" << boundary << "\r\n" << "Content-Disposition: form-data; name=\"Content-Type\"\r\n\r\n" << config["Content-Type"].asString() << "\r\n"; body << "--" << boundary << "\r\n" << "Content-Disposition: form-data; name=\"policy\"\r\n\r\n" << config["policy"].asString() << "\r\n"; body << "--" << boundary << "\r\n" << "Content-Disposition: form-data; name=\"signature\"\r\n\r\n" << config["signature"].asString() << "\r\n"; body << "--" << boundary << "\r\n" << "Content-Disposition: form-data; name=\"success_action_redirect\"\r\n\r\n" << config["success_action_redirect"].asString() << "\r\n"; body << "--" << boundary << "\r\n" << "Content-Disposition: form-data; name=\"file\"; filename=\"snapshot.png\"\r\n" << "Content-Type: image/png\r\n\r\n"; size_t const body_size = body.str().size(); std::ostringstream footer; footer << "\r\n--" << boundary << "--\r\n"; size_t const footer_size = footer.str().size(); size_t size = body_size + image->getDataSize() + footer_size; // postRaw() takes ownership of the buffer and releases it later. U8* data = new U8 [size]; memcpy(data, body.str().data(), body_size); // Insert the image data. memcpy(data + body_size, image->getData(), image->getDataSize()); memcpy(data + body_size + image->getDataSize(), footer.str().data(), footer_size); // Send request, successful upload will trigger posting metadata. LLHTTPClient::postRaw(url, data, size, new LLWebProfileResponders::PostImageResponder(), headers/*,*/ DEBUG_CURLIO_PARAM(debug_off), no_keep_alive); }
// Create the baked texture, send it out to the server, then wait for it to come // back so we can switch to using it. void LLViewerTexLayerSetBuffer::doUpload() { LLViewerTexLayerSet* layer_set = getViewerTexLayerSet(); LL_INFOS() << "Uploading baked " << layer_set->getBodyRegionName() << LL_ENDL; LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_BAKES); // Don't need caches since we're baked now. (note: we won't *really* be baked // until this image is sent to the server and the Avatar Appearance message is received.) layer_set->deleteCaches(); // Get the COLOR information from our texture U8* baked_color_data = new U8[ mFullWidth * mFullHeight * 4 ]; glReadPixels(mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, GL_RGBA, GL_UNSIGNED_BYTE, baked_color_data ); stop_glerror(); // Get the MASK information from our texture LLGLSUIDefault gls_ui; LLPointer<LLImageRaw> baked_mask_image = new LLImageRaw(mFullWidth, mFullHeight, 1 ); U8* baked_mask_data = baked_mask_image->getData(); layer_set->gatherMorphMaskAlpha(baked_mask_data, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight); // Create the baked image from our color and mask information const S32 baked_image_components = 5; // red green blue [bump] clothing LLPointer<LLImageRaw> baked_image = new LLImageRaw( mFullWidth, mFullHeight, baked_image_components ); U8* baked_image_data = baked_image->getData(); S32 i = 0; for (S32 u=0; u < mFullWidth; u++) { for (S32 v=0; v < mFullHeight; v++) { baked_image_data[5*i + 0] = baked_color_data[4*i + 0]; baked_image_data[5*i + 1] = baked_color_data[4*i + 1]; baked_image_data[5*i + 2] = baked_color_data[4*i + 2]; baked_image_data[5*i + 3] = baked_color_data[4*i + 3]; // alpha should be correct for eyelashes. baked_image_data[5*i + 4] = baked_mask_data[i]; i++; } } LLPointer<LLImageJ2C> compressedImage = new LLImageJ2C; const char* comment_text = LINDEN_J2C_COMMENT_PREFIX "RGBHM"; // writes into baked_color_data. 5 channels (rgb, heightfield/alpha, mask) if (compressedImage->encode(baked_image, comment_text)) { LLTransactionID tid; tid.generate(); const LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); if (LLVFile::writeFile(compressedImage->getData(), compressedImage->getDataSize(), gVFS, asset_id, LLAssetType::AT_TEXTURE)) { // Read back the file and validate. BOOL valid = FALSE; LLPointer<LLImageJ2C> integrity_test = new LLImageJ2C; S32 file_size = 0; U8* data = LLVFile::readFile(gVFS, LLImageBase::getPrivatePool(), asset_id, LLAssetType::AT_TEXTURE, &file_size); if (data) { valid = integrity_test->validate(data, file_size); // integrity_test will delete 'data' } else { integrity_test->setLastError("Unable to read entire file"); } if (valid) { const bool highest_lod = layer_set->isLocalTextureDataFinal(); // Baked_upload_data is owned by the responder and deleted after the request completes. LLBakedUploadData* baked_upload_data = new LLBakedUploadData(gAgentAvatarp, layer_set, asset_id, highest_lod); // upload ID is used to avoid overlaps, e.g. when the user rapidly makes two changes outside of Face Edit. mUploadID = asset_id; // Upload the image const std::string url = gAgent.getRegion()->getCapability("UploadBakedTexture"); if(!url.empty() && !LLPipeline::sForceOldBakedUpload // toggle debug setting UploadBakedTexOld to change between the new caps method and old method && (mUploadFailCount < (BAKE_UPLOAD_ATTEMPTS - 1))) // Try last ditch attempt via asset store if cap upload is failing. { LLSD body = LLSD::emptyMap(); // The responder will call LLViewerTexLayerSetBuffer::onTextureUploadComplete() LLHTTPClient::post(url, body, new LLSendTexLayerResponder(body, mUploadID, LLAssetType::AT_TEXTURE, baked_upload_data)); LL_INFOS() << "Baked texture upload via capability of " << mUploadID << " to " << url << LL_ENDL; } else { gAssetStorage->storeAssetData(tid, LLAssetType::AT_TEXTURE, LLViewerTexLayerSetBuffer::onTextureUploadComplete, baked_upload_data, TRUE, // temp_file TRUE, // is_priority TRUE); // store_local LL_INFOS() << "Baked texture upload via Asset Store." << LL_ENDL; } if (highest_lod) { // Sending the final LOD for the baked texture. All done, pause // the upload timer so we know how long it took. mNeedsUpload = FALSE; mNeedsUploadTimer.pause(); } else { // Sending a lower level LOD for the baked texture. Restart the upload timer. mNumLowresUploads++; mNeedsUploadTimer.unpause(); mNeedsUploadTimer.reset(); } // Print out notification that we uploaded this texture. if (gSavedSettings.getBOOL("DebugAvatarRezTime")) { const std::string lod_str = highest_lod ? "HighRes" : "LowRes"; LLSD args; args["EXISTENCE"] = llformat("%d",(U32)layer_set->getAvatar()->debugGetExistenceTimeElapsedF32()); args["TIME"] = llformat("%d",(U32)mNeedsUploadTimer.getElapsedTimeF32()); args["BODYREGION"] = layer_set->getBodyRegionName(); args["RESOLUTION"] = lod_str; LLNotificationsUtil::add("AvatarRezSelfBakedTextureUploadNotification",args); LL_DEBUGS("Avatar") << self_av_string() << "Uploading [ name: " << layer_set->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUploadTimer.getElapsedTimeF32() << " ]" << LL_ENDL; } } else { // The read back and validate operation failed. Remove the uploaded file. mUploadPending = FALSE; LLVFile file(gVFS, asset_id, LLAssetType::AT_TEXTURE, LLVFile::WRITE); file.remove(); LL_INFOS() << "Unable to create baked upload file (reason: corrupted)." << LL_ENDL; } } } else { // The VFS write file operation failed. mUploadPending = FALSE; LL_INFOS() << "Unable to create baked upload file (reason: failed to write file)" << LL_ENDL; } delete [] baked_color_data; }
BOOL LLSurface::generateWaterTexture(const F32 x, const F32 y, const F32 width, const F32 height) { if (!getWaterTexture()) { return FALSE; } S32 tex_width = mWaterTexturep->getWidth(); S32 tex_height = mWaterTexturep->getHeight(); S32 tex_comps = mWaterTexturep->getComponents(); S32 tex_stride = tex_width * tex_comps; LLPointer<LLImageRaw> raw = new LLImageRaw(tex_width, tex_height, tex_comps); U8 *rawp = raw->getData(); F32 scale = 256.f * getMetersPerGrid() / (F32)tex_width; F32 scale_inv = 1.f / scale; S32 x_begin, y_begin, x_end, y_end; x_begin = llround(x * scale_inv); y_begin = llround(y * scale_inv); x_end = llround((x + width) * scale_inv); y_end = llround((y + width) * scale_inv); if (x_end > tex_width) { x_end = tex_width; } if (y_end > tex_width) { y_end = tex_width; } LLVector3d origin_global = from_region_handle(getRegion()->getHandle()); // OK, for now, just have the composition value equal the height at the point. LLVector3 location; LLColor4U coloru; const F32 WATER_HEIGHT = getWaterHeight(); S32 i, j, offset; for (j = y_begin; j < y_end; j++) { for (i = x_begin; i < x_end; i++) { //F32 nv[2]; //nv[0] = i/256.f; //nv[1] = j/256.f; // const S32 modulation = noise2(nv)*40; offset = j*tex_stride + i*tex_comps; location.mV[VX] = i*scale; location.mV[VY] = j*scale; // Sample multiple points const F32 height = resolveHeightRegion(location); if (height > WATER_HEIGHT) { // Above water... coloru = MAX_WATER_COLOR; coloru.mV[3] = ABOVE_WATERLINE_ALPHA; *(rawp + offset++) = coloru.mV[0]; *(rawp + offset++) = coloru.mV[1]; *(rawp + offset++) = coloru.mV[2]; *(rawp + offset++) = coloru.mV[3]; } else { // Want non-linear curve for transparency gradient coloru = MAX_WATER_COLOR; const F32 frac = 1.f - 2.f/(2.f - (height - WATER_HEIGHT)); S32 alpha = 64 + llround((255-64)*frac); alpha = llmin(llround((F32)MAX_WATER_COLOR.mV[3]), alpha); alpha = llmax(64, alpha); coloru.mV[3] = alpha; *(rawp + offset++) = coloru.mV[0]; *(rawp + offset++) = coloru.mV[1]; *(rawp + offset++) = coloru.mV[2]; *(rawp + offset++) = coloru.mV[3]; } } } if (!mWaterTexturep->hasGLTexture()) { mWaterTexturep->createGLTexture(0, raw); } mWaterTexturep->setSubImage(raw, x_begin, y_begin, x_end - x_begin, y_end - y_begin); return TRUE; }