void LLFloaterTexturePicker::updateImageStats() { if (mTexturep.notNull()) { //RN: have we received header data for this image? if (mTexturep->getWidth(0) > 0 && mTexturep->getHeight(0) > 0) { std::string formatted_dims = llformat("%d x %d", mTexturep->getWidth(0),mTexturep->getHeight(0)); mResolutionLabel->setTextArg("[DIMENSIONS]", formatted_dims); } else { mResolutionLabel->setTextArg("[DIMENSIONS]", std::string("[? x ?]")); } } }
// note: modifies the argument raw_image!!!! LLPointer<LLImageJ2C> LLViewerImageList::convertToUploadFile(LLPointer<LLImageRaw> raw_image) { raw_image->biasedScaleToPowerOfTwo(LLViewerImage::MAX_IMAGE_SIZE_DEFAULT); LLPointer<LLImageJ2C> compressedImage = new LLImageJ2C(); compressedImage->setRate(0.f); if (gSavedSettings.getBOOL("LosslessJ2CUpload") && (raw_image->getWidth() * raw_image->getHeight() <= LL_IMAGE_REZ_LOSSLESS_CUTOFF * LL_IMAGE_REZ_LOSSLESS_CUTOFF)) compressedImage->setReversible(TRUE); compressedImage->encode(raw_image, 0.0f); return compressedImage; }
void LLFloaterTexturePicker::updateImageStats() { if (mTexturep.notNull()) { //RN: have we received header data for this image? if (mTexturep->getWidth(0) > 0 && mTexturep->getHeight(0) > 0) { std::string formatted_dims = llformat("%d x %d", mTexturep->getWidth(0),mTexturep->getHeight(0)); mResolutionLabel->setTextArg("[DIMENSIONS]", formatted_dims); } else { mResolutionLabel->setTextArg("[DIMENSIONS]", std::string("[? x ?]")); } if (gAgent.isGodlike()) { std::string tstring = "Pick: "; std::string image_id_string = mTexturep->getID().asString(); tstring = tstring + image_id_string.replace(24, 35, 12, '*'); // hide last segment to discourage theft setTitle(tstring); } } }
// Draws image rotated by multiples of 90 degrees void LLJoystickCameraRotate::drawRotatedImage( LLPointer<LLUIImage> image, S32 rotations ) { S32 width = image->getWidth(); S32 height = image->getHeight(); LLTexture* texture = image->getImage(); /* * Scale texture coordinate system * to handle the different between image size and size of texture. * If we will use default matrix, * it may break texture mapping after rotation. * see EXT-2023 Camera floater: arrows became shifted when pressed. */ F32 uv[][2] = { { (F32)width/texture->getWidth(), (F32)height/texture->getHeight() }, { 0.f, (F32)height/texture->getHeight() }, { 0.f, 0.f }, { (F32)width/texture->getWidth(), 0.f } }; gGL.getTexUnit(0)->bind(texture); gGL.color4fv(UI_VERTEX_COLOR.mV); gGL.begin(LLRender::QUADS); { gGL.texCoord2fv( uv[ (rotations + 0) % 4]); gGL.vertex2i(width, height ); gGL.texCoord2fv( uv[ (rotations + 1) % 4]); gGL.vertex2i(0, height ); gGL.texCoord2fv( uv[ (rotations + 2) % 4]); gGL.vertex2i(0, 0); gGL.texCoord2fv( uv[ (rotations + 3) % 4]); gGL.vertex2i(width, 0); } gGL.end(); }
// note: modifies the argument raw_image!!!! LLPointer<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImageRaw> raw_image) { raw_image->biasedScaleToPowerOfTwo(LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); LLPointer<LLImageJ2C> compressedImage = new LLImageJ2C(); compressedImage->setRate(0.f); if (gSavedSettings.getBOOL("LosslessJ2CUpload") && (raw_image->getWidth() * raw_image->getHeight() <= LL_IMAGE_REZ_LOSSLESS_CUTOFF * LL_IMAGE_REZ_LOSSLESS_CUTOFF)) compressedImage->setReversible(TRUE); compressedImage->encode(raw_image, 0.0f); if (!compressedImage->encode(raw_image, 0.0f)) { llinfos << "convertToUploadFile : encode returns with error!!" << llendl; // Clear up the pointer so we don't leak that one compressedImage = NULL; } return compressedImage; }
bool LLImageRaw::createFromFile(const std::string &filename, bool j2c_lowest_mip_only) { std::string name = filename; size_t dotidx = name.rfind('.'); S8 codec = IMG_CODEC_INVALID; std::string exten; deleteData(); // delete any existing data if (dotidx != std::string::npos) { exten = name.substr(dotidx+1); LLStringUtil::toLower(exten); codec = getCodecFromExtension(exten); } else { exten = find_file(name, &codec); name = name + "." + exten; } if (codec == IMG_CODEC_INVALID) { return false; // format not recognized } llifstream ifs(name, llifstream::binary); if (!ifs.is_open()) { // SJB: changed from LL_INFOS() to LL_DEBUGS() to reduce spam LL_DEBUGS() << "Unable to open image file: " << name << LL_ENDL; return false; } ifs.seekg (0, std::ios::end); int length = ifs.tellg(); if (j2c_lowest_mip_only && length > 2048) { length = 2048; } ifs.seekg (0, std::ios::beg); if (!length) { LL_INFOS() << "Zero length file file: " << name << LL_ENDL; return false; } LLPointer<LLImageFormatted> image = LLImageFormatted::createFromType(codec); llassert(image.notNull()); U8 *buffer = image->allocateData(length); ifs.read ((char*)buffer, length); ifs.close(); BOOL success; success = image->updateData(); if (success) { if (j2c_lowest_mip_only && codec == IMG_CODEC_J2C) { S32 width = image->getWidth(); S32 height = image->getHeight(); S32 discard_level = 0; while (width > 1 && height > 1 && discard_level < MAX_DISCARD_LEVEL) { width >>= 1; height >>= 1; discard_level++; } ((LLImageJ2C *)((LLImageFormatted*)image))->setDiscardLevel(discard_level); } success = image->decode(this, 100000.0f); }
void output_image_stats(LLPointer<LLImageFormatted> image, const std::string &filename) { // Print out some statistical data on the image std::cout << "Image stats for : " << filename << ", extension : " << image->getExtension() << std::endl; std::cout << " with : " << (int)(image->getWidth()) << ", height : " << (int)(image->getHeight()) << std::endl; std::cout << " comp : " << (int)(image->getComponents()) << ", levels : " << (int)(image->getDiscardLevel()) << std::endl; std::cout << " head : " << (int)(image->calcHeaderSize()) << ", data : " << (int)(image->getDataSize()) << std::endl; return; }
//virtual BOOL LLNameListCtrl::handleToolTip(S32 x, S32 y, MASK mask) { BOOL handled = FALSE; S32 column_index = getColumnIndexFromOffset(x); LLScrollListItem* hit_item = hitItem(x, y); if (hit_item && column_index == mNameColumnIndex) { // ...this is the column with the avatar name LLUUID avatar_id = hit_item->getUUID(); if (avatar_id.notNull()) { // ...valid avatar id LLScrollListCell* hit_cell = hit_item->getColumn(column_index); if (hit_cell) { S32 row_index = getItemIndex(hit_item); LLRect cell_rect = getCellRect(row_index, column_index); // Convert rect local to screen coordinates LLRect sticky_rect; localRectToScreen(cell_rect, &sticky_rect); // Spawn at right side of cell LLPointer<LLUIImage> icon = LLUI::getUIImage("Info_Small"); LLCoordGL pos( sticky_rect.mRight - info_icon_size, sticky_rect.mTop - (sticky_rect.getHeight() - icon->getHeight())/2 ); // Should we show a group or an avatar inspector? bool is_group = hit_item->getValue()["is_group"].asBoolean(); LLToolTip::Params params; params.background_visible( false ); params.click_callback( boost::bind(&LLNameListCtrl::showInspector, this, avatar_id, is_group) ); params.delay_time(0.0f); // spawn instantly on hover params.image( icon ); params.message(""); params.padding(0); params.pos(pos); params.sticky_rect(sticky_rect); LLToolTipMgr::getInstance()->show(params); handled = TRUE; } } } if (!handled) { handled = LLScrollListCtrl::handleToolTip(x, y, mask); } return handled; }
void LLTextureView::draw() { if (!mFreezeView) { // LLViewerObject *objectp; // S32 te; for_each(mTextureBars.begin(), mTextureBars.end(), DeletePointer()); mTextureBars.clear(); delete mGLTexMemBar; mGLTexMemBar = 0; typedef std::multiset<decode_pair_t, compare_decode_pair > display_list_t; display_list_t display_image_list; if (mPrintList) { llinfos << "ID\tMEM\tBOOST\tPRI\tWIDTH\tHEIGHT\tDISCARD" << llendl; } for (LLViewerImageList::image_priority_list_t::iterator iter = gImageList.mImageList.begin(); iter != gImageList.mImageList.end(); ) { LLPointer<LLViewerImage> imagep = *iter++; S32 cur_discard = imagep->getDiscardLevel(); S32 desired_discard = imagep->mDesiredDiscardLevel; if (mPrintList) { llinfos << imagep->getID() << "\t" << imagep->mTextureMemory << "\t" << imagep->getBoostLevel() << "\t" << imagep->getDecodePriority() << "\t" << imagep->getWidth() << "\t" << imagep->getHeight() << "\t" << cur_discard << llendl; } #if 0 if (imagep->getDontDiscard()) { continue; } if (imagep->isMissingAsset()) { continue; } #endif #define HIGH_PRIORITY 100000000.f F32 pri; if (mOrderFetch) { pri = ((F32)imagep->mFetchPriority)/256.f; } else { pri = imagep->getDecodePriority(); } if (sDebugImages.find(imagep) != sDebugImages.end()) { pri += 4*HIGH_PRIORITY; } if (!mOrderFetch) { #if 1 if (pri < HIGH_PRIORITY && LLSelectMgr::getInstance()) { struct f : public LLSelectedTEFunctor { LLViewerImage* mImage; f(LLViewerImage* image) : mImage(image) {} virtual bool apply(LLViewerObject* object, S32 te) { return (mImage == object->getTEImage(te)); } } func(imagep); const bool firstonly = true; bool match = LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func, firstonly); if (match) { pri += 3*HIGH_PRIORITY; } } #endif #if 1 if (pri < HIGH_PRIORITY && (cur_discard< 0 || desired_discard < cur_discard)) { LLViewerObject *objectp = gHoverView->getLastHoverObject(); if (objectp) { S32 tex_count = objectp->getNumTEs(); for (S32 i = 0; i < tex_count; i++) { if (imagep == objectp->getTEImage(i)) { pri += 2*HIGH_PRIORITY; break; } } } } #endif #if 1 if (pri > 0.f && pri < HIGH_PRIORITY) { if (imagep->mLastPacketTimer.getElapsedTimeF32() < 1.f || imagep->mFetchDeltaTime < 0.25f) { pri += 1*HIGH_PRIORITY; } } #endif } if (pri > 0.0f) { display_image_list.insert(std::make_pair(pri, imagep)); } } if (mPrintList) { mPrintList = FALSE; } static S32 max_count = 50; S32 count = 0; for (display_list_t::iterator iter = display_image_list.begin(); iter != display_image_list.end(); iter++) { LLViewerImage* imagep = iter->second; S32 hilite = 0; F32 pri = iter->first; if (pri >= 1 * HIGH_PRIORITY) { hilite = (S32)((pri+1) / HIGH_PRIORITY) - 1; } if ((hilite || count < max_count-10) && (count < max_count)) { if (addBar(imagep, hilite)) { count++; } } } if (mOrderFetch) sortChildren(LLTextureBar::sort_fetch()); else sortChildren(LLTextureBar::sort()); mGLTexMemBar = new LLGLTexMemBar("gl texmem bar", this); addChild(mGLTexMemBar); reshape(getRect().getWidth(), getRect().getHeight(), TRUE); /* count = gImageList.getNumImages(); std::string info_string; info_string = llformat("Global Info:\nTexture Count: %d", count); mInfoTextp->setText(info_string); */ for (child_list_const_iter_t child_iter = getChildList()->begin(); child_iter != getChildList()->end(); ++child_iter) { LLView *viewp = *child_iter; if (viewp->getRect().mBottom < 0) { viewp->setVisible(FALSE); } } } LLContainerView::draw(); }
void LLTextureBar::draw() { if (!mImagep) { return; } LLColor4 color; if (mImagep->getID() == LLAppViewer::getTextureFetch()->mDebugID) { color = LLColor4::cyan2; } else if (mHilite) { S32 idx = llclamp(mHilite,1,3); if (idx==1) color = LLColor4::orange; else if (idx==2) color = LLColor4::yellow; else color = LLColor4::pink2; } else if (mImagep->mDontDiscard) { color = LLColor4::green4; } else if (mImagep->getBoostLevel()) { color = LLColor4::magenta; } else if (mImagep->getDecodePriority() == 0.0f) { color = LLColor4::grey; color[VALPHA] = .7f; } else { color = LLColor4::white; color[VALPHA] = .7f; } // We need to draw: // The texture UUID or name // The progress bar for the texture, highlighted if it's being download // Various numerical stats. std::string tex_str; S32 left, right; S32 top = 0; S32 bottom = top + 6; LLColor4 clr; LLGLSUIDefault gls_ui; // Name, pixel_area, requested pixel area, decode priority std::string uuid_str; mImagep->mID.toString(uuid_str); uuid_str = uuid_str.substr(0,7); if (mTextureView->mOrderFetch) { tex_str = llformat("%s %7.0f %d(%d) 0x%08x(%8.0f)", uuid_str.c_str(), mImagep->mMaxVirtualSize, mImagep->mDesiredDiscardLevel, mImagep->mRequestedDiscardLevel, mImagep->mFetchPriority, mImagep->getDecodePriority()); } else { tex_str = llformat("%s %7.0f %d(%d) %8.0f(0x%08x)", uuid_str.c_str(), mImagep->mMaxVirtualSize, mImagep->mDesiredDiscardLevel, mImagep->mRequestedDiscardLevel, mImagep->getDecodePriority(), mImagep->mFetchPriority); } LLFontGL::sMonospace->renderUTF8(tex_str, 0, title_x1, getRect().getHeight(), color, LLFontGL::LEFT, LLFontGL::TOP); // State // Hack: mirrored from lltexturefetch.cpp struct { const std::string desc; LLColor4 color; } fetch_state_desc[] = { { "---", LLColor4::red }, // INVALID { "INI", LLColor4::white }, // INIT { "DSK", LLColor4::cyan }, // LOAD_FROM_TEXTURE_CACHE { "DSK", LLColor4::blue }, // CACHE_POST { "NET", LLColor4::green }, // LOAD_FROM_NETWORK { "SIM", LLColor4::green }, // LOAD_FROM_SIMULATOR { "URL", LLColor4::green2 },// LOAD_FROM_HTTP_GET_URL { "HTP", LLColor4::green }, // LOAD_FROM_HTTP_GET_DATA { "DEC", LLColor4::yellow },// DECODE_IMAGE { "DEC", LLColor4::yellow },// DECODE_IMAGE_UPDATE { "WRT", LLColor4::purple },// WRITE_TO_CACHE { "WRT", LLColor4::orange },// WAIT_ON_WRITE { "END", LLColor4::red }, // DONE #define LAST_STATE 12 { "CRE", LLColor4::magenta }, // LAST_STATE+1 { "FUL", LLColor4::green }, // LAST_STATE+2 { "BAD", LLColor4::red }, // LAST_STATE+3 { "MIS", LLColor4::red }, // LAST_STATE+4 { "---", LLColor4::white }, // LAST_STATE+5 }; const S32 fetch_state_desc_size = (S32)(sizeof(fetch_state_desc)/sizeof(fetch_state_desc[0])); S32 state = mImagep->mNeedsCreateTexture ? LAST_STATE+1 : mImagep->mFullyLoaded ? LAST_STATE+2 : mImagep->mMinDiscardLevel > 0 ? LAST_STATE+3 : mImagep->mIsMissingAsset ? LAST_STATE+4 : !mImagep->mIsFetching ? LAST_STATE+5 : mImagep->mFetchState; state = llclamp(state,0,fetch_state_desc_size-1); LLFontGL::sMonospace->renderUTF8(fetch_state_desc[state].desc, 0, title_x2, getRect().getHeight(), fetch_state_desc[state].color, LLFontGL::LEFT, LLFontGL::TOP); LLGLSNoTexture gls_no_texture; // Draw the progress bar. S32 bar_width = 100; S32 bar_left = 280; left = bar_left; right = left + bar_width; gGL.color4f(0.f, 0.f, 0.f, 0.75f); gl_rect_2d(left, top, right, bottom); F32 data_progress = mImagep->mDownloadProgress; if (data_progress > 0.0f) { // Downloaded bytes right = left + llfloor(data_progress * (F32)bar_width); if (right > left) { gGL.color4f(0.f, 0.f, 1.f, 0.75f); gl_rect_2d(left, top, right, bottom); } } S32 pip_width = 6; S32 pip_space = 14; S32 pip_x = title_x3 + pip_space/2; // Draw the packet pip F32 last_event = mImagep->mLastPacketTimer.getElapsedTimeF32(); if (last_event < 1.f) { clr = LLColor4::white; } else { last_event = mImagep->mRequestDeltaTime; if (last_event < 1.f) { clr = LLColor4::green; } else { last_event = mImagep->mFetchDeltaTime; if (last_event < 1.f) { clr = LLColor4::yellow; } } } if (last_event < 1.f) { clr.setAlpha(1.f - last_event); gGL.color4fv(clr.mV); gl_rect_2d(pip_x, top, pip_x + pip_width, bottom); } pip_x += pip_width + pip_space; // we don't want to show bind/resident pips for textures using the default texture if (mImagep->getHasGLTexture()) { // Draw the bound pip last_event = mImagep->sLastFrameTime - mImagep->mLastBindTime; if (last_event < 1.f) { clr = mImagep->getMissed() ? LLColor4::red : LLColor4::magenta1; clr.setAlpha(1.f - last_event); gGL.color4fv(clr.mV); gl_rect_2d(pip_x, top, pip_x + pip_width, bottom); } } pip_x += pip_width + pip_space; { LLGLSUIDefault gls_ui; // draw the packet data // { // std::string num_str = llformat("%3d/%3d", mImagep->mLastPacket+1, mImagep->mPackets); // LLFontGL::sMonospace->renderUTF8(num_str, 0, bar_left + 100, getRect().getHeight(), color, // LLFontGL::LEFT, LLFontGL::TOP); // } // draw the image size at the end { std::string num_str = llformat("%3dx%3d (%d) %7d", mImagep->getWidth(), mImagep->getHeight(), mImagep->getDiscardLevel(), mImagep->mTextureMemory); LLFontGL::sMonospace->renderUTF8(num_str, 0, title_x4, getRect().getHeight(), color, LLFontGL::LEFT, LLFontGL::TOP); } } }
void LLTextureView::draw() { if (!mFreezeView) { // LLViewerObject *objectp; // S32 te; for_each(mTextureBars.begin(), mTextureBars.end(), KillView()); mTextureBars.clear(); if (mGLTexMemBar) { removeChild(mGLTexMemBar); mGLTexMemBar->die(); mGLTexMemBar = 0; } if (mAvatarTexBar) { removeChild(mAvatarTexBar); mAvatarTexBar->die(); mAvatarTexBar = 0; } typedef std::multiset<decode_pair_t, compare_decode_pair > display_list_t; display_list_t display_image_list; if (mPrintList) { llinfos << "ID\tMEM\tBOOST\tPRI\tWIDTH\tHEIGHT\tDISCARD" << llendl; } for (LLViewerTextureList::image_priority_list_t::iterator iter = gTextureList.mImageList.begin(); iter != gTextureList.mImageList.end(); ) { LLPointer<LLViewerFetchedTexture> imagep = *iter++; if(!imagep->hasFetcher()) { continue ; } S32 cur_discard = imagep->getDiscardLevel(); S32 desired_discard = imagep->mDesiredDiscardLevel; if (mPrintList) { S32 tex_mem = imagep->hasGLTexture() ? imagep->getTextureMemory() : 0 ; llinfos << imagep->getID() << "\t" << tex_mem << "\t" << imagep->getBoostLevel() << "\t" << imagep->getDecodePriority() << "\t" << imagep->getWidth() << "\t" << imagep->getHeight() << "\t" << cur_discard << llendl; } if (imagep->getID() == LLAppViewer::getTextureFetch()->mDebugID) { static S32 debug_count = 0; ++debug_count; // for breakpoints } F32 pri; if (mOrderFetch) { pri = ((F32)imagep->mFetchPriority)/256.f; } else { pri = imagep->getDecodePriority(); } pri = llclamp(pri, 0.0f, HIGH_PRIORITY-1.f); if (sDebugImages.find(imagep) != sDebugImages.end()) { pri += 4*HIGH_PRIORITY; } if (!mOrderFetch) { if (pri < HIGH_PRIORITY && LLSelectMgr::getInstance()) { struct f : public LLSelectedTEFunctor { LLViewerFetchedTexture* mImage; f(LLViewerFetchedTexture* image) : mImage(image) {} virtual bool apply(LLViewerObject* object, S32 te) { return (mImage == object->getTEImage(te)); } } func(imagep); const bool firstonly = true; bool match = LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func, firstonly); if (match) { pri += 3*HIGH_PRIORITY; } } if (pri < HIGH_PRIORITY && (cur_discard< 0 || desired_discard < cur_discard)) { LLSelectNode* hover_node = LLSelectMgr::instance().getHoverNode(); if (hover_node) { LLViewerObject *objectp = hover_node->getObject(); if (objectp) { S32 tex_count = objectp->getNumTEs(); for (S32 i = 0; i < tex_count; i++) { if (imagep == objectp->getTEImage(i)) { pri += 2*HIGH_PRIORITY; break; } } } } } if (pri > 0.f && pri < HIGH_PRIORITY) { if (imagep->mLastPacketTimer.getElapsedTimeF32() < 1.f || imagep->mFetchDeltaTime < 0.25f) { pri += 1*HIGH_PRIORITY; } } } if (pri > 0.0f) { display_image_list.insert(std::make_pair(pri, imagep)); } } if (mPrintList) { mPrintList = FALSE; } static S32 max_count = 50; S32 count = 0; mNumTextureBars = 0 ; for (display_list_t::iterator iter = display_image_list.begin(); iter != display_image_list.end(); iter++) { LLViewerFetchedTexture* imagep = iter->second; S32 hilite = 0; F32 pri = iter->first; if (pri >= 1 * HIGH_PRIORITY) { hilite = (S32)((pri+1) / HIGH_PRIORITY) - 1; } if ((hilite || count < max_count-10) && (count < max_count)) { if (addBar(imagep, hilite)) { count++; } } } if (mOrderFetch) sortChildren(LLTextureBar::sort_fetch()); else sortChildren(LLTextureBar::sort()); LLGLTexMemBar::Params tmbp; LLRect tmbr; tmbp.name("gl texmem bar"); tmbp.rect(tmbr); tmbp.follows.flags = FOLLOWS_LEFT|FOLLOWS_TOP; tmbp.texture_view(this); mGLTexMemBar = LLUICtrlFactory::create<LLGLTexMemBar>(tmbp); addChild(mGLTexMemBar); sendChildToFront(mGLTexMemBar); LLAvatarTexBar::Params atbp; LLRect atbr; atbp.name("gl avatartex bar"); atbp.texture_view(this); atbp.rect(atbr); mAvatarTexBar = LLUICtrlFactory::create<LLAvatarTexBar>(atbp); addChild(mAvatarTexBar); sendChildToFront(mAvatarTexBar); reshape(getRect().getWidth(), getRect().getHeight(), TRUE); LLUI::popMatrix(); LLUI::pushMatrix(); LLUI::translate((F32)getRect().mLeft, (F32)getRect().mBottom); for (child_list_const_iter_t child_iter = getChildList()->begin(); child_iter != getChildList()->end(); ++child_iter) { LLView *viewp = *child_iter; if (viewp->getRect().mBottom < 0) { viewp->setVisible(FALSE); } } } LLContainerView::draw(); }
bool LLImageRaw::createFromFile(const std::string &filename, bool j2c_lowest_mip_only) { std::string name = filename; size_t dotidx = name.rfind('.'); S8 codec = IMG_CODEC_INVALID; std::string exten; deleteData(); // delete any existing data if (dotidx != std::string::npos) { exten = name.substr(dotidx+1); LLStringUtil::toLower(exten); codec = getCodecFromExtension(exten); } else { exten = find_file(name, &codec); name = name + "." + exten; } if (codec == IMG_CODEC_INVALID) { return false; // format not recognized } llifstream ifs(name, llifstream::binary); if (!ifs.is_open()) { // SJB: changed from llinfos to lldebugs to reduce spam lldebugs << "Unable to open image file: " << name << llendl; return false; } ifs.seekg (0, std::ios::end); int length = ifs.tellg(); if (j2c_lowest_mip_only && length > 2048) { length = 2048; } ifs.seekg (0, std::ios::beg); if (!length) { llinfos << "Zero length file file: " << name << llendl; return false; } LLPointer<LLImageFormatted> image; switch(codec) { //case IMG_CODEC_RGB: case IMG_CODEC_BMP: image = new LLImageBMP(); break; case IMG_CODEC_TGA: image = new LLImageTGA(); break; case IMG_CODEC_JPEG: image = new LLImageJPEG(); break; case IMG_CODEC_J2C: image = new LLImageJ2C(); break; case IMG_CODEC_DXT: image = new LLImageDXT(); break; default: return false; } llassert(image.notNull()); U8 *buffer = image->allocateData(length); ifs.read ((char*)buffer, length); /* Flawfinder: ignore */ ifs.close(); image->updateData(); if (j2c_lowest_mip_only && codec == IMG_CODEC_J2C) { S32 width = image->getWidth(); S32 height = image->getHeight(); S32 discard_level = 0; while (width > 1 && height > 1 && discard_level < MAX_DISCARD_LEVEL) { width >>= 1; height >>= 1; discard_level++; } ((LLImageJ2C *)((LLImageFormatted*)image))->setDiscardLevel(discard_level); }