PageRenderTime 36ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/llimage/llimage.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 1758 lines | 1347 code | 235 blank | 176 comment | 260 complexity | 86f37f85c8005a11967191de9d7e77ec MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llimage.cpp
  3. * @brief Base class for images.
  4. *
  5. * $LicenseInfo:firstyear=2001&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #include "linden_common.h"
  27. #include "llimage.h"
  28. #include "llmath.h"
  29. #include "v4coloru.h"
  30. #include "llmemtype.h"
  31. #include "llimagebmp.h"
  32. #include "llimagetga.h"
  33. #include "llimagej2c.h"
  34. #include "llimagejpeg.h"
  35. #include "llimagepng.h"
  36. #include "llimagedxt.h"
  37. #include "llimageworker.h"
  38. #include "llmemory.h"
  39. //---------------------------------------------------------------------------
  40. // LLImage
  41. //---------------------------------------------------------------------------
  42. //static
  43. std::string LLImage::sLastErrorMessage;
  44. LLMutex* LLImage::sMutex = NULL;
  45. LLPrivateMemoryPool* LLImageBase::sPrivatePoolp = NULL ;
  46. //static
  47. void LLImage::initClass()
  48. {
  49. sMutex = new LLMutex(NULL);
  50. LLImageBase::createPrivatePool() ;
  51. }
  52. //static
  53. void LLImage::cleanupClass()
  54. {
  55. delete sMutex;
  56. sMutex = NULL;
  57. LLImageBase::destroyPrivatePool() ;
  58. }
  59. //static
  60. const std::string& LLImage::getLastError()
  61. {
  62. static const std::string noerr("No Error");
  63. return sLastErrorMessage.empty() ? noerr : sLastErrorMessage;
  64. }
  65. //static
  66. void LLImage::setLastError(const std::string& message)
  67. {
  68. LLMutexLock m(sMutex);
  69. sLastErrorMessage = message;
  70. }
  71. //---------------------------------------------------------------------------
  72. // LLImageBase
  73. //---------------------------------------------------------------------------
  74. LLImageBase::LLImageBase()
  75. : mData(NULL),
  76. mDataSize(0),
  77. mWidth(0),
  78. mHeight(0),
  79. mComponents(0),
  80. mBadBufferAllocation(false),
  81. mAllowOverSize(false),
  82. mMemType(LLMemType::MTYPE_IMAGEBASE)
  83. {
  84. }
  85. // virtual
  86. LLImageBase::~LLImageBase()
  87. {
  88. deleteData(); // virtual
  89. }
  90. //static
  91. void LLImageBase::createPrivatePool()
  92. {
  93. if(!sPrivatePoolp)
  94. {
  95. sPrivatePoolp = LLPrivateMemoryPoolManager::getInstance()->newPool(LLPrivateMemoryPool::STATIC_THREADED) ;
  96. }
  97. }
  98. //static
  99. void LLImageBase::destroyPrivatePool()
  100. {
  101. if(sPrivatePoolp)
  102. {
  103. LLPrivateMemoryPoolManager::getInstance()->deletePool(sPrivatePoolp) ;
  104. sPrivatePoolp = NULL ;
  105. }
  106. }
  107. // virtual
  108. void LLImageBase::dump()
  109. {
  110. llinfos << "LLImageBase mComponents " << mComponents
  111. << " mData " << mData
  112. << " mDataSize " << mDataSize
  113. << " mWidth " << mWidth
  114. << " mHeight " << mHeight
  115. << llendl;
  116. }
  117. // virtual
  118. void LLImageBase::sanityCheck()
  119. {
  120. if (mWidth > MAX_IMAGE_SIZE
  121. || mHeight > MAX_IMAGE_SIZE
  122. || mDataSize > (S32)MAX_IMAGE_DATA_SIZE
  123. || mComponents > (S8)MAX_IMAGE_COMPONENTS
  124. )
  125. {
  126. llerrs << "Failed LLImageBase::sanityCheck "
  127. << "width " << mWidth
  128. << "height " << mHeight
  129. << "datasize " << mDataSize
  130. << "components " << mComponents
  131. << "data " << mData
  132. << llendl;
  133. }
  134. }
  135. // virtual
  136. void LLImageBase::deleteData()
  137. {
  138. FREE_MEM(sPrivatePoolp, mData) ;
  139. mData = NULL;
  140. mDataSize = 0;
  141. }
  142. // virtual
  143. U8* LLImageBase::allocateData(S32 size)
  144. {
  145. LLMemType mt1(mMemType);
  146. if (size < 0)
  147. {
  148. size = mWidth * mHeight * mComponents;
  149. if (size <= 0)
  150. {
  151. llerrs << llformat("LLImageBase::allocateData called with bad dimensions: %dx%dx%d",mWidth,mHeight,(S32)mComponents) << llendl;
  152. }
  153. }
  154. //make this function thread-safe.
  155. static const U32 MAX_BUFFER_SIZE = 4096 * 4096 * 16 ; //256 MB
  156. if (size < 1 || size > MAX_BUFFER_SIZE)
  157. {
  158. llinfos << "width: " << mWidth << " height: " << mHeight << " components: " << mComponents << llendl ;
  159. if(mAllowOverSize)
  160. {
  161. llinfos << "Oversize: " << size << llendl ;
  162. }
  163. else
  164. {
  165. llerrs << "LLImageBase::allocateData: bad size: " << size << llendl;
  166. }
  167. }
  168. if (!mData || size != mDataSize)
  169. {
  170. deleteData(); // virtual
  171. mBadBufferAllocation = false ;
  172. mData = (U8*)ALLOCATE_MEM(sPrivatePoolp, size);
  173. if (!mData)
  174. {
  175. llwarns << "Failed to allocate image data size [" << size << "]" << llendl;
  176. size = 0 ;
  177. mWidth = mHeight = 0 ;
  178. mBadBufferAllocation = true ;
  179. }
  180. mDataSize = size;
  181. }
  182. return mData;
  183. }
  184. // virtual
  185. U8* LLImageBase::reallocateData(S32 size)
  186. {
  187. LLMemType mt1(mMemType);
  188. U8 *new_datap = (U8*)ALLOCATE_MEM(sPrivatePoolp, size);
  189. if (!new_datap)
  190. {
  191. llwarns << "Out of memory in LLImageBase::reallocateData" << llendl;
  192. return 0;
  193. }
  194. if (mData)
  195. {
  196. S32 bytes = llmin(mDataSize, size);
  197. memcpy(new_datap, mData, bytes); /* Flawfinder: ignore */
  198. FREE_MEM(sPrivatePoolp, mData) ;
  199. }
  200. mData = new_datap;
  201. mDataSize = size;
  202. return mData;
  203. }
  204. const U8* LLImageBase::getData() const
  205. {
  206. if(mBadBufferAllocation)
  207. {
  208. llerrs << "Bad memory allocation for the image buffer!" << llendl ;
  209. }
  210. return mData;
  211. } // read only
  212. U8* LLImageBase::getData()
  213. {
  214. if(mBadBufferAllocation)
  215. {
  216. llerrs << "Bad memory allocation for the image buffer!" << llendl ;
  217. }
  218. return mData;
  219. }
  220. bool LLImageBase::isBufferInvalid()
  221. {
  222. return mBadBufferAllocation || mData == NULL ;
  223. }
  224. void LLImageBase::setSize(S32 width, S32 height, S32 ncomponents)
  225. {
  226. mWidth = width;
  227. mHeight = height;
  228. mComponents = ncomponents;
  229. }
  230. U8* LLImageBase::allocateDataSize(S32 width, S32 height, S32 ncomponents, S32 size)
  231. {
  232. setSize(width, height, ncomponents);
  233. return allocateData(size); // virtual
  234. }
  235. //---------------------------------------------------------------------------
  236. // LLImageRaw
  237. //---------------------------------------------------------------------------
  238. S32 LLImageRaw::sGlobalRawMemory = 0;
  239. S32 LLImageRaw::sRawImageCount = 0;
  240. LLImageRaw::LLImageRaw()
  241. : LLImageBase()
  242. {
  243. mMemType = LLMemType::MTYPE_IMAGERAW;
  244. ++sRawImageCount;
  245. }
  246. LLImageRaw::LLImageRaw(U16 width, U16 height, S8 components)
  247. : LLImageBase()
  248. {
  249. mMemType = LLMemType::MTYPE_IMAGERAW;
  250. //llassert( S32(width) * S32(height) * S32(components) <= MAX_IMAGE_DATA_SIZE );
  251. allocateDataSize(width, height, components);
  252. ++sRawImageCount;
  253. }
  254. LLImageRaw::LLImageRaw(U8 *data, U16 width, U16 height, S8 components)
  255. : LLImageBase()
  256. {
  257. mMemType = LLMemType::MTYPE_IMAGERAW;
  258. if(allocateDataSize(width, height, components))
  259. {
  260. memcpy(getData(), data, width*height*components);
  261. }
  262. ++sRawImageCount;
  263. }
  264. //LLImageRaw::LLImageRaw(const std::string& filename, bool j2c_lowest_mip_only)
  265. // : LLImageBase()
  266. //{
  267. // createFromFile(filename, j2c_lowest_mip_only);
  268. //}
  269. LLImageRaw::~LLImageRaw()
  270. {
  271. // NOTE: ~LLimageBase() call to deleteData() calls LLImageBase::deleteData()
  272. // NOT LLImageRaw::deleteData()
  273. deleteData();
  274. --sRawImageCount;
  275. }
  276. // virtual
  277. U8* LLImageRaw::allocateData(S32 size)
  278. {
  279. U8* res = LLImageBase::allocateData(size);
  280. sGlobalRawMemory += getDataSize();
  281. return res;
  282. }
  283. // virtual
  284. U8* LLImageRaw::reallocateData(S32 size)
  285. {
  286. sGlobalRawMemory -= getDataSize();
  287. U8* res = LLImageBase::reallocateData(size);
  288. sGlobalRawMemory += getDataSize();
  289. return res;
  290. }
  291. // virtual
  292. void LLImageRaw::deleteData()
  293. {
  294. sGlobalRawMemory -= getDataSize();
  295. LLImageBase::deleteData();
  296. }
  297. void LLImageRaw::setDataAndSize(U8 *data, S32 width, S32 height, S8 components)
  298. {
  299. if(data == getData())
  300. {
  301. return ;
  302. }
  303. deleteData();
  304. LLImageBase::setSize(width, height, components) ;
  305. LLImageBase::setDataAndSize(data, width * height * components) ;
  306. sGlobalRawMemory += getDataSize();
  307. }
  308. BOOL LLImageRaw::resize(U16 width, U16 height, S8 components)
  309. {
  310. if ((getWidth() == width) && (getHeight() == height) && (getComponents() == components))
  311. {
  312. return TRUE;
  313. }
  314. // Reallocate the data buffer.
  315. deleteData();
  316. allocateDataSize(width,height,components);
  317. return TRUE;
  318. }
  319. #if 0
  320. U8 * LLImageRaw::getSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height) const
  321. {
  322. LLMemType mt1(mMemType);
  323. U8 *data = new U8[width*height*getComponents()];
  324. // Should do some simple bounds checking
  325. if (!data)
  326. {
  327. llerrs << "Out of memory in LLImageRaw::getSubImage" << llendl;
  328. return NULL;
  329. }
  330. U32 i;
  331. for (i = y_pos; i < y_pos+height; i++)
  332. {
  333. memcpy(data + i*width*getComponents(), /* Flawfinder: ignore */
  334. getData() + ((y_pos + i)*getWidth() + x_pos)*getComponents(), getComponents()*width);
  335. }
  336. return data;
  337. }
  338. #endif
  339. BOOL LLImageRaw::setSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height,
  340. const U8 *data, U32 stride, BOOL reverse_y)
  341. {
  342. if (!getData())
  343. {
  344. return FALSE;
  345. }
  346. if (!data)
  347. {
  348. return FALSE;
  349. }
  350. // Should do some simple bounds checking
  351. U32 i;
  352. for (i = 0; i < height; i++)
  353. {
  354. const U32 row = reverse_y ? height - 1 - i : i;
  355. const U32 from_offset = row * ((stride == 0) ? width*getComponents() : stride);
  356. const U32 to_offset = (y_pos + i)*getWidth() + x_pos;
  357. memcpy(getData() + to_offset*getComponents(), /* Flawfinder: ignore */
  358. data + from_offset, getComponents()*width);
  359. }
  360. return TRUE;
  361. }
  362. void LLImageRaw::clear(U8 r, U8 g, U8 b, U8 a)
  363. {
  364. llassert( getComponents() <= 4 );
  365. // This is fairly bogus, but it'll do for now.
  366. U8 *pos = getData();
  367. U32 x, y;
  368. for (x = 0; x < getWidth(); x++)
  369. {
  370. for (y = 0; y < getHeight(); y++)
  371. {
  372. *pos = r;
  373. pos++;
  374. if (getComponents() == 1)
  375. {
  376. continue;
  377. }
  378. *pos = g;
  379. pos++;
  380. if (getComponents() == 2)
  381. {
  382. continue;
  383. }
  384. *pos = b;
  385. pos++;
  386. if (getComponents() == 3)
  387. {
  388. continue;
  389. }
  390. *pos = a;
  391. pos++;
  392. }
  393. }
  394. }
  395. // Reverses the order of the rows in the image
  396. void LLImageRaw::verticalFlip()
  397. {
  398. LLMemType mt1(mMemType);
  399. S32 row_bytes = getWidth() * getComponents();
  400. llassert(row_bytes > 0);
  401. std::vector<U8> line_buffer(row_bytes);
  402. S32 mid_row = getHeight() / 2;
  403. for( S32 row = 0; row < mid_row; row++ )
  404. {
  405. U8* row_a_data = getData() + row * row_bytes;
  406. U8* row_b_data = getData() + (getHeight() - 1 - row) * row_bytes;
  407. memcpy( &line_buffer[0], row_a_data, row_bytes );
  408. memcpy( row_a_data, row_b_data, row_bytes );
  409. memcpy( row_b_data, &line_buffer[0], row_bytes );
  410. }
  411. }
  412. void LLImageRaw::expandToPowerOfTwo(S32 max_dim, BOOL scale_image)
  413. {
  414. // Find new sizes
  415. S32 new_width = MIN_IMAGE_SIZE;
  416. S32 new_height = MIN_IMAGE_SIZE;
  417. while( (new_width < getWidth()) && (new_width < max_dim) )
  418. {
  419. new_width <<= 1;
  420. }
  421. while( (new_height < getHeight()) && (new_height < max_dim) )
  422. {
  423. new_height <<= 1;
  424. }
  425. scale( new_width, new_height, scale_image );
  426. }
  427. void LLImageRaw::contractToPowerOfTwo(S32 max_dim, BOOL scale_image)
  428. {
  429. // Find new sizes
  430. S32 new_width = max_dim;
  431. S32 new_height = max_dim;
  432. while( (new_width > getWidth()) && (new_width > MIN_IMAGE_SIZE) )
  433. {
  434. new_width >>= 1;
  435. }
  436. while( (new_height > getHeight()) && (new_height > MIN_IMAGE_SIZE) )
  437. {
  438. new_height >>= 1;
  439. }
  440. scale( new_width, new_height, scale_image );
  441. }
  442. void LLImageRaw::biasedScaleToPowerOfTwo(S32 max_dim)
  443. {
  444. // Strong bias towards rounding down (to save bandwidth)
  445. // No bias would mean THRESHOLD == 1.5f;
  446. const F32 THRESHOLD = 1.75f;
  447. // Find new sizes
  448. S32 larger_w = max_dim; // 2^n >= mWidth
  449. S32 smaller_w = max_dim; // 2^(n-1) <= mWidth
  450. while( (smaller_w > getWidth()) && (smaller_w > MIN_IMAGE_SIZE) )
  451. {
  452. larger_w = smaller_w;
  453. smaller_w >>= 1;
  454. }
  455. S32 new_width = ( (F32)getWidth() / smaller_w > THRESHOLD ) ? larger_w : smaller_w;
  456. S32 larger_h = max_dim; // 2^m >= mHeight
  457. S32 smaller_h = max_dim; // 2^(m-1) <= mHeight
  458. while( (smaller_h > getHeight()) && (smaller_h > MIN_IMAGE_SIZE) )
  459. {
  460. larger_h = smaller_h;
  461. smaller_h >>= 1;
  462. }
  463. S32 new_height = ( (F32)getHeight() / smaller_h > THRESHOLD ) ? larger_h : smaller_h;
  464. scale( new_width, new_height );
  465. }
  466. // Calculates (U8)(255*(a/255.f)*(b/255.f) + 0.5f). Thanks, Jim Blinn!
  467. inline U8 LLImageRaw::fastFractionalMult( U8 a, U8 b )
  468. {
  469. U32 i = a * b + 128;
  470. return U8((i + (i>>8)) >> 8);
  471. }
  472. void LLImageRaw::composite( LLImageRaw* src )
  473. {
  474. LLImageRaw* dst = this; // Just for clarity.
  475. llassert(3 == src->getComponents());
  476. llassert(3 == dst->getComponents());
  477. if( 3 == dst->getComponents() )
  478. {
  479. if( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) )
  480. {
  481. // No scaling needed
  482. if( 3 == src->getComponents() )
  483. {
  484. copyUnscaled( src ); // alpha is one so just copy the data.
  485. }
  486. else
  487. {
  488. compositeUnscaled4onto3( src );
  489. }
  490. }
  491. else
  492. {
  493. if( 3 == src->getComponents() )
  494. {
  495. copyScaled( src ); // alpha is one so just copy the data.
  496. }
  497. else
  498. {
  499. compositeScaled4onto3( src );
  500. }
  501. }
  502. }
  503. }
  504. // Src and dst can be any size. Src has 4 components. Dst has 3 components.
  505. void LLImageRaw::compositeScaled4onto3(LLImageRaw* src)
  506. {
  507. LLMemType mt1(mMemType);
  508. llinfos << "compositeScaled4onto3" << llendl;
  509. LLImageRaw* dst = this; // Just for clarity.
  510. llassert( (4 == src->getComponents()) && (3 == dst->getComponents()) );
  511. S32 temp_data_size = src->getWidth() * dst->getHeight() * src->getComponents();
  512. llassert_always(temp_data_size > 0);
  513. std::vector<U8> temp_buffer(temp_data_size);
  514. // Vertical: scale but no composite
  515. for( S32 col = 0; col < src->getWidth(); col++ )
  516. {
  517. copyLineScaled( src->getData() + (src->getComponents() * col), &temp_buffer[0] + (src->getComponents() * col), src->getHeight(), dst->getHeight(), src->getWidth(), src->getWidth() );
  518. }
  519. // Horizontal: scale and composite
  520. for( S32 row = 0; row < dst->getHeight(); row++ )
  521. {
  522. compositeRowScaled4onto3( &temp_buffer[0] + (src->getComponents() * src->getWidth() * row), dst->getData() + (dst->getComponents() * dst->getWidth() * row), src->getWidth(), dst->getWidth() );
  523. }
  524. }
  525. // Src and dst are same size. Src has 4 components. Dst has 3 components.
  526. void LLImageRaw::compositeUnscaled4onto3( LLImageRaw* src )
  527. {
  528. /*
  529. //test fastFractionalMult()
  530. {
  531. U8 i = 255;
  532. U8 j = 255;
  533. do
  534. {
  535. do
  536. {
  537. llassert( fastFractionalMult(i, j) == (U8)(255*(i/255.f)*(j/255.f) + 0.5f) );
  538. } while( j-- );
  539. } while( i-- );
  540. }
  541. */
  542. LLImageRaw* dst = this; // Just for clarity.
  543. llassert( (3 == src->getComponents()) || (4 == src->getComponents()) );
  544. llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) );
  545. U8* src_data = src->getData();
  546. U8* dst_data = dst->getData();
  547. S32 pixels = getWidth() * getHeight();
  548. while( pixels-- )
  549. {
  550. U8 alpha = src_data[3];
  551. if( alpha )
  552. {
  553. if( 255 == alpha )
  554. {
  555. dst_data[0] = src_data[0];
  556. dst_data[1] = src_data[1];
  557. dst_data[2] = src_data[2];
  558. }
  559. else
  560. {
  561. U8 transparency = 255 - alpha;
  562. dst_data[0] = fastFractionalMult( dst_data[0], transparency ) + fastFractionalMult( src_data[0], alpha );
  563. dst_data[1] = fastFractionalMult( dst_data[1], transparency ) + fastFractionalMult( src_data[1], alpha );
  564. dst_data[2] = fastFractionalMult( dst_data[2], transparency ) + fastFractionalMult( src_data[2], alpha );
  565. }
  566. }
  567. src_data += 4;
  568. dst_data += 3;
  569. }
  570. }
  571. // Fill the buffer with a constant color
  572. void LLImageRaw::fill( const LLColor4U& color )
  573. {
  574. S32 pixels = getWidth() * getHeight();
  575. if( 4 == getComponents() )
  576. {
  577. U32* data = (U32*) getData();
  578. for( S32 i = 0; i < pixels; i++ )
  579. {
  580. data[i] = color.mAll;
  581. }
  582. }
  583. else
  584. if( 3 == getComponents() )
  585. {
  586. U8* data = getData();
  587. for( S32 i = 0; i < pixels; i++ )
  588. {
  589. data[0] = color.mV[0];
  590. data[1] = color.mV[1];
  591. data[2] = color.mV[2];
  592. data += 3;
  593. }
  594. }
  595. }
  596. // Src and dst can be any size. Src and dst can each have 3 or 4 components.
  597. void LLImageRaw::copy(LLImageRaw* src)
  598. {
  599. if (!src)
  600. {
  601. llwarns << "LLImageRaw::copy called with a null src pointer" << llendl;
  602. return;
  603. }
  604. LLImageRaw* dst = this; // Just for clarity.
  605. if( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) )
  606. {
  607. // No scaling needed
  608. if( src->getComponents() == dst->getComponents() )
  609. {
  610. copyUnscaled( src );
  611. }
  612. else
  613. if( 3 == src->getComponents() )
  614. {
  615. copyUnscaled3onto4( src );
  616. }
  617. else
  618. {
  619. // 4 == src->getComponents()
  620. copyUnscaled4onto3( src );
  621. }
  622. }
  623. else
  624. {
  625. // Scaling needed
  626. // No scaling needed
  627. if( src->getComponents() == dst->getComponents() )
  628. {
  629. copyScaled( src );
  630. }
  631. else
  632. if( 3 == src->getComponents() )
  633. {
  634. copyScaled3onto4( src );
  635. }
  636. else
  637. {
  638. // 4 == src->getComponents()
  639. copyScaled4onto3( src );
  640. }
  641. }
  642. }
  643. // Src and dst are same size. Src and dst have same number of components.
  644. void LLImageRaw::copyUnscaled(LLImageRaw* src)
  645. {
  646. LLImageRaw* dst = this; // Just for clarity.
  647. llassert( (1 == src->getComponents()) || (3 == src->getComponents()) || (4 == src->getComponents()) );
  648. llassert( src->getComponents() == dst->getComponents() );
  649. llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) );
  650. memcpy( dst->getData(), src->getData(), getWidth() * getHeight() * getComponents() ); /* Flawfinder: ignore */
  651. }
  652. // Src and dst can be any size. Src has 3 components. Dst has 4 components.
  653. void LLImageRaw::copyScaled3onto4(LLImageRaw* src)
  654. {
  655. llassert( (3 == src->getComponents()) && (4 == getComponents()) );
  656. // Slow, but simple. Optimize later if needed.
  657. LLImageRaw temp( src->getWidth(), src->getHeight(), 4);
  658. temp.copyUnscaled3onto4( src );
  659. copyScaled( &temp );
  660. }
  661. // Src and dst can be any size. Src has 4 components. Dst has 3 components.
  662. void LLImageRaw::copyScaled4onto3(LLImageRaw* src)
  663. {
  664. llassert( (4 == src->getComponents()) && (3 == getComponents()) );
  665. // Slow, but simple. Optimize later if needed.
  666. LLImageRaw temp( src->getWidth(), src->getHeight(), 3);
  667. temp.copyUnscaled4onto3( src );
  668. copyScaled( &temp );
  669. }
  670. // Src and dst are same size. Src has 4 components. Dst has 3 components.
  671. void LLImageRaw::copyUnscaled4onto3( LLImageRaw* src )
  672. {
  673. LLImageRaw* dst = this; // Just for clarity.
  674. llassert( (3 == dst->getComponents()) && (4 == src->getComponents()) );
  675. llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) );
  676. S32 pixels = getWidth() * getHeight();
  677. U8* src_data = src->getData();
  678. U8* dst_data = dst->getData();
  679. for( S32 i=0; i<pixels; i++ )
  680. {
  681. dst_data[0] = src_data[0];
  682. dst_data[1] = src_data[1];
  683. dst_data[2] = src_data[2];
  684. src_data += 4;
  685. dst_data += 3;
  686. }
  687. }
  688. // Src and dst are same size. Src has 3 components. Dst has 4 components.
  689. void LLImageRaw::copyUnscaled3onto4( LLImageRaw* src )
  690. {
  691. LLImageRaw* dst = this; // Just for clarity.
  692. llassert( 3 == src->getComponents() );
  693. llassert( 4 == dst->getComponents() );
  694. llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) );
  695. S32 pixels = getWidth() * getHeight();
  696. U8* src_data = src->getData();
  697. U8* dst_data = dst->getData();
  698. for( S32 i=0; i<pixels; i++ )
  699. {
  700. dst_data[0] = src_data[0];
  701. dst_data[1] = src_data[1];
  702. dst_data[2] = src_data[2];
  703. dst_data[3] = 255;
  704. src_data += 3;
  705. dst_data += 4;
  706. }
  707. }
  708. // Src and dst can be any size. Src and dst have same number of components.
  709. void LLImageRaw::copyScaled( LLImageRaw* src )
  710. {
  711. LLMemType mt1(mMemType);
  712. LLImageRaw* dst = this; // Just for clarity.
  713. llassert_always( (1 == src->getComponents()) || (3 == src->getComponents()) || (4 == src->getComponents()) );
  714. llassert_always( src->getComponents() == dst->getComponents() );
  715. if( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) )
  716. {
  717. memcpy( dst->getData(), src->getData(), getWidth() * getHeight() * getComponents() ); /* Flawfinder: ignore */
  718. return;
  719. }
  720. S32 temp_data_size = src->getWidth() * dst->getHeight() * getComponents();
  721. llassert_always(temp_data_size > 0);
  722. std::vector<U8> temp_buffer(temp_data_size);
  723. // Vertical
  724. for( S32 col = 0; col < src->getWidth(); col++ )
  725. {
  726. copyLineScaled( src->getData() + (getComponents() * col), &temp_buffer[0] + (getComponents() * col), src->getHeight(), dst->getHeight(), src->getWidth(), src->getWidth() );
  727. }
  728. // Horizontal
  729. for( S32 row = 0; row < dst->getHeight(); row++ )
  730. {
  731. copyLineScaled( &temp_buffer[0] + (getComponents() * src->getWidth() * row), dst->getData() + (getComponents() * dst->getWidth() * row), src->getWidth(), dst->getWidth(), 1, 1 );
  732. }
  733. }
  734. #if 0
  735. //scale down image by not blending a pixel with its neighbors.
  736. BOOL LLImageRaw::scaleDownWithoutBlending( S32 new_width, S32 new_height)
  737. {
  738. LLMemType mt1(mMemType);
  739. S8 c = getComponents() ;
  740. llassert((1 == c) || (3 == c) || (4 == c) );
  741. S32 old_width = getWidth();
  742. S32 old_height = getHeight();
  743. S32 new_data_size = old_width * new_height * c ;
  744. llassert_always(new_data_size > 0);
  745. F32 ratio_x = (F32)old_width / new_width ;
  746. F32 ratio_y = (F32)old_height / new_height ;
  747. if( ratio_x < 1.0f || ratio_y < 1.0f )
  748. {
  749. return TRUE; // Nothing to do.
  750. }
  751. ratio_x -= 1.0f ;
  752. ratio_y -= 1.0f ;
  753. U8* new_data = allocateMemory(new_data_size) ;
  754. llassert_always(new_data != NULL) ;
  755. U8* old_data = getData() ;
  756. S32 i, j, k, s, t;
  757. for(i = 0, s = 0, t = 0 ; i < new_height ; i++)
  758. {
  759. for(j = 0 ; j < new_width ; j++)
  760. {
  761. for(k = 0 ; k < c ; k++)
  762. {
  763. new_data[s++] = old_data[t++] ;
  764. }
  765. t += (S32)(ratio_x * c + 0.1f) ;
  766. }
  767. t += (S32)(ratio_y * old_width * c + 0.1f) ;
  768. }
  769. setDataAndSize(new_data, new_width, new_height, c) ;
  770. return TRUE ;
  771. }
  772. #endif
  773. BOOL LLImageRaw::scale( S32 new_width, S32 new_height, BOOL scale_image_data )
  774. {
  775. LLMemType mt1(mMemType);
  776. llassert((1 == getComponents()) || (3 == getComponents()) || (4 == getComponents()) );
  777. S32 old_width = getWidth();
  778. S32 old_height = getHeight();
  779. if( (old_width == new_width) && (old_height == new_height) )
  780. {
  781. return TRUE; // Nothing to do.
  782. }
  783. // Reallocate the data buffer.
  784. if (scale_image_data)
  785. {
  786. S32 temp_data_size = old_width * new_height * getComponents();
  787. llassert_always(temp_data_size > 0);
  788. std::vector<U8> temp_buffer(temp_data_size);
  789. // Vertical
  790. for( S32 col = 0; col < old_width; col++ )
  791. {
  792. copyLineScaled( getData() + (getComponents() * col), &temp_buffer[0] + (getComponents() * col), old_height, new_height, old_width, old_width );
  793. }
  794. deleteData();
  795. U8* new_buffer = allocateDataSize(new_width, new_height, getComponents());
  796. // Horizontal
  797. for( S32 row = 0; row < new_height; row++ )
  798. {
  799. copyLineScaled( &temp_buffer[0] + (getComponents() * old_width * row), new_buffer + (getComponents() * new_width * row), old_width, new_width, 1, 1 );
  800. }
  801. }
  802. else
  803. {
  804. // copy out existing image data
  805. S32 temp_data_size = old_width * old_height * getComponents();
  806. std::vector<U8> temp_buffer(temp_data_size);
  807. memcpy(&temp_buffer[0], getData(), temp_data_size);
  808. // allocate new image data, will delete old data
  809. U8* new_buffer = allocateDataSize(new_width, new_height, getComponents());
  810. for( S32 row = 0; row < new_height; row++ )
  811. {
  812. if (row < old_height)
  813. {
  814. memcpy(new_buffer + (new_width * row * getComponents()), &temp_buffer[0] + (old_width * row * getComponents()), getComponents() * llmin(old_width, new_width));
  815. if (old_width < new_width)
  816. {
  817. // pad out rest of row with black
  818. memset(new_buffer + (getComponents() * ((new_width * row) + old_width)), 0, getComponents() * (new_width - old_width));
  819. }
  820. }
  821. else
  822. {
  823. // pad remaining rows with black
  824. memset(new_buffer + (new_width * row * getComponents()), 0, new_width * getComponents());
  825. }
  826. }
  827. }
  828. return TRUE ;
  829. }
  830. void LLImageRaw::copyLineScaled( U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len, S32 in_pixel_step, S32 out_pixel_step )
  831. {
  832. const S32 components = getComponents();
  833. llassert( components >= 1 && components <= 4 );
  834. const F32 ratio = F32(in_pixel_len) / out_pixel_len; // ratio of old to new
  835. const F32 norm_factor = 1.f / ratio;
  836. S32 goff = components >= 2 ? 1 : 0;
  837. S32 boff = components >= 3 ? 2 : 0;
  838. for( S32 x = 0; x < out_pixel_len; x++ )
  839. {
  840. // Sample input pixels in range from sample0 to sample1.
  841. // Avoid floating point accumulation error... don't just add ratio each time. JC
  842. const F32 sample0 = x * ratio;
  843. const F32 sample1 = (x+1) * ratio;
  844. const S32 index0 = llfloor(sample0); // left integer (floor)
  845. const S32 index1 = llfloor(sample1); // right integer (floor)
  846. const F32 fract0 = 1.f - (sample0 - F32(index0)); // spill over on left
  847. const F32 fract1 = sample1 - F32(index1); // spill-over on right
  848. if( index0 == index1 )
  849. {
  850. // Interval is embedded in one input pixel
  851. S32 t0 = x * out_pixel_step * components;
  852. S32 t1 = index0 * in_pixel_step * components;
  853. U8* outp = out + t0;
  854. U8* inp = in + t1;
  855. for (S32 i = 0; i < components; ++i)
  856. {
  857. *outp = *inp;
  858. ++outp;
  859. ++inp;
  860. }
  861. }
  862. else
  863. {
  864. // Left straddle
  865. S32 t1 = index0 * in_pixel_step * components;
  866. F32 r = in[t1 + 0] * fract0;
  867. F32 g = in[t1 + goff] * fract0;
  868. F32 b = in[t1 + boff] * fract0;
  869. F32 a = 0;
  870. if( components == 4)
  871. {
  872. a = in[t1 + 3] * fract0;
  873. }
  874. // Central interval
  875. if (components < 4)
  876. {
  877. for( S32 u = index0 + 1; u < index1; u++ )
  878. {
  879. S32 t2 = u * in_pixel_step * components;
  880. r += in[t2 + 0];
  881. g += in[t2 + goff];
  882. b += in[t2 + boff];
  883. }
  884. }
  885. else
  886. {
  887. for( S32 u = index0 + 1; u < index1; u++ )
  888. {
  889. S32 t2 = u * in_pixel_step * components;
  890. r += in[t2 + 0];
  891. g += in[t2 + 1];
  892. b += in[t2 + 2];
  893. a += in[t2 + 3];
  894. }
  895. }
  896. // right straddle
  897. // Watch out for reading off of end of input array.
  898. if( fract1 && index1 < in_pixel_len )
  899. {
  900. S32 t3 = index1 * in_pixel_step * components;
  901. if (components < 4)
  902. {
  903. U8 in0 = in[t3 + 0];
  904. U8 in1 = in[t3 + goff];
  905. U8 in2 = in[t3 + boff];
  906. r += in0 * fract1;
  907. g += in1 * fract1;
  908. b += in2 * fract1;
  909. }
  910. else
  911. {
  912. U8 in0 = in[t3 + 0];
  913. U8 in1 = in[t3 + 1];
  914. U8 in2 = in[t3 + 2];
  915. U8 in3 = in[t3 + 3];
  916. r += in0 * fract1;
  917. g += in1 * fract1;
  918. b += in2 * fract1;
  919. a += in3 * fract1;
  920. }
  921. }
  922. r *= norm_factor;
  923. g *= norm_factor;
  924. b *= norm_factor;
  925. a *= norm_factor; // skip conditional
  926. S32 t4 = x * out_pixel_step * components;
  927. out[t4 + 0] = U8(llround(r));
  928. if (components >= 2)
  929. out[t4 + 1] = U8(llround(g));
  930. if (components >= 3)
  931. out[t4 + 2] = U8(llround(b));
  932. if( components == 4)
  933. out[t4 + 3] = U8(llround(a));
  934. }
  935. }
  936. }
  937. void LLImageRaw::compositeRowScaled4onto3( U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len )
  938. {
  939. llassert( getComponents() == 3 );
  940. const S32 IN_COMPONENTS = 4;
  941. const S32 OUT_COMPONENTS = 3;
  942. const F32 ratio = F32(in_pixel_len) / out_pixel_len; // ratio of old to new
  943. const F32 norm_factor = 1.f / ratio;
  944. for( S32 x = 0; x < out_pixel_len; x++ )
  945. {
  946. // Sample input pixels in range from sample0 to sample1.
  947. // Avoid floating point accumulation error... don't just add ratio each time. JC
  948. const F32 sample0 = x * ratio;
  949. const F32 sample1 = (x+1) * ratio;
  950. const S32 index0 = S32(sample0); // left integer (floor)
  951. const S32 index1 = S32(sample1); // right integer (floor)
  952. const F32 fract0 = 1.f - (sample0 - F32(index0)); // spill over on left
  953. const F32 fract1 = sample1 - F32(index1); // spill-over on right
  954. U8 in_scaled_r;
  955. U8 in_scaled_g;
  956. U8 in_scaled_b;
  957. U8 in_scaled_a;
  958. if( index0 == index1 )
  959. {
  960. // Interval is embedded in one input pixel
  961. S32 t1 = index0 * IN_COMPONENTS;
  962. in_scaled_r = in[t1 + 0];
  963. in_scaled_g = in[t1 + 0];
  964. in_scaled_b = in[t1 + 0];
  965. in_scaled_a = in[t1 + 0];
  966. }
  967. else
  968. {
  969. // Left straddle
  970. S32 t1 = index0 * IN_COMPONENTS;
  971. F32 r = in[t1 + 0] * fract0;
  972. F32 g = in[t1 + 1] * fract0;
  973. F32 b = in[t1 + 2] * fract0;
  974. F32 a = in[t1 + 3] * fract0;
  975. // Central interval
  976. for( S32 u = index0 + 1; u < index1; u++ )
  977. {
  978. S32 t2 = u * IN_COMPONENTS;
  979. r += in[t2 + 0];
  980. g += in[t2 + 1];
  981. b += in[t2 + 2];
  982. a += in[t2 + 3];
  983. }
  984. // right straddle
  985. // Watch out for reading off of end of input array.
  986. if( fract1 && index1 < in_pixel_len )
  987. {
  988. S32 t3 = index1 * IN_COMPONENTS;
  989. r += in[t3 + 0] * fract1;
  990. g += in[t3 + 1] * fract1;
  991. b += in[t3 + 2] * fract1;
  992. a += in[t3 + 3] * fract1;
  993. }
  994. r *= norm_factor;
  995. g *= norm_factor;
  996. b *= norm_factor;
  997. a *= norm_factor;
  998. in_scaled_r = U8(llround(r));
  999. in_scaled_g = U8(llround(g));
  1000. in_scaled_b = U8(llround(b));
  1001. in_scaled_a = U8(llround(a));
  1002. }
  1003. if( in_scaled_a )
  1004. {
  1005. if( 255 == in_scaled_a )
  1006. {
  1007. out[0] = in_scaled_r;
  1008. out[1] = in_scaled_g;
  1009. out[2] = in_scaled_b;
  1010. }
  1011. else
  1012. {
  1013. U8 transparency = 255 - in_scaled_a;
  1014. out[0] = fastFractionalMult( out[0], transparency ) + fastFractionalMult( in_scaled_r, in_scaled_a );
  1015. out[1] = fastFractionalMult( out[1], transparency ) + fastFractionalMult( in_scaled_g, in_scaled_a );
  1016. out[2] = fastFractionalMult( out[2], transparency ) + fastFractionalMult( in_scaled_b, in_scaled_a );
  1017. }
  1018. }
  1019. out += OUT_COMPONENTS;
  1020. }
  1021. }
  1022. //----------------------------------------------------------------------------
  1023. static struct
  1024. {
  1025. const char* exten;
  1026. EImageCodec codec;
  1027. }
  1028. file_extensions[] =
  1029. {
  1030. { "bmp", IMG_CODEC_BMP },
  1031. { "tga", IMG_CODEC_TGA },
  1032. { "j2c", IMG_CODEC_J2C },
  1033. { "jp2", IMG_CODEC_J2C },
  1034. { "texture", IMG_CODEC_J2C },
  1035. { "jpg", IMG_CODEC_JPEG },
  1036. { "jpeg", IMG_CODEC_JPEG },
  1037. { "mip", IMG_CODEC_DXT },
  1038. { "dxt", IMG_CODEC_DXT },
  1039. { "png", IMG_CODEC_PNG }
  1040. };
  1041. #define NUM_FILE_EXTENSIONS LL_ARRAY_SIZE(file_extensions)
  1042. #if 0
  1043. static std::string find_file(std::string &name, S8 *codec)
  1044. {
  1045. std::string tname;
  1046. for (int i=0; i<(int)(NUM_FILE_EXTENSIONS); i++)
  1047. {
  1048. tname = name + "." + std::string(file_extensions[i].exten);
  1049. llifstream ifs(tname, llifstream::binary);
  1050. if (ifs.is_open())
  1051. {
  1052. ifs.close();
  1053. if (codec)
  1054. *codec = file_extensions[i].codec;
  1055. return std::string(file_extensions[i].exten);
  1056. }
  1057. }
  1058. return std::string("");
  1059. }
  1060. #endif
  1061. EImageCodec LLImageBase::getCodecFromExtension(const std::string& exten)
  1062. {
  1063. for (int i=0; i<(int)(NUM_FILE_EXTENSIONS); i++)
  1064. {
  1065. if (exten == file_extensions[i].exten)
  1066. return file_extensions[i].codec;
  1067. }
  1068. return IMG_CODEC_INVALID;
  1069. }
  1070. #if 0
  1071. bool LLImageRaw::createFromFile(const std::string &filename, bool j2c_lowest_mip_only)
  1072. {
  1073. std::string name = filename;
  1074. size_t dotidx = name.rfind('.');
  1075. S8 codec = IMG_CODEC_INVALID;
  1076. std::string exten;
  1077. deleteData(); // delete any existing data
  1078. if (dotidx != std::string::npos)
  1079. {
  1080. exten = name.substr(dotidx+1);
  1081. LLStringUtil::toLower(exten);
  1082. codec = getCodecFromExtension(exten);
  1083. }
  1084. else
  1085. {
  1086. exten = find_file(name, &codec);
  1087. name = name + "." + exten;
  1088. }
  1089. if (codec == IMG_CODEC_INVALID)
  1090. {
  1091. return false; // format not recognized
  1092. }
  1093. llifstream ifs(name, llifstream::binary);
  1094. if (!ifs.is_open())
  1095. {
  1096. // SJB: changed from llinfos to lldebugs to reduce spam
  1097. lldebugs << "Unable to open image file: " << name << llendl;
  1098. return false;
  1099. }
  1100. ifs.seekg (0, std::ios::end);
  1101. int length = ifs.tellg();
  1102. if (j2c_lowest_mip_only && length > 2048)
  1103. {
  1104. length = 2048;
  1105. }
  1106. ifs.seekg (0, std::ios::beg);
  1107. if (!length)
  1108. {
  1109. llinfos << "Zero length file file: " << name << llendl;
  1110. return false;
  1111. }
  1112. LLPointer<LLImageFormatted> image = LLImageFormatted::createFromType(codec);
  1113. llassert(image.notNull());
  1114. U8 *buffer = image->allocateData(length);
  1115. ifs.read ((char*)buffer, length);
  1116. ifs.close();
  1117. BOOL success;
  1118. success = image->updateData();
  1119. if (success)
  1120. {
  1121. if (j2c_lowest_mip_only && codec == IMG_CODEC_J2C)
  1122. {
  1123. S32 width = image->getWidth();
  1124. S32 height = image->getHeight();
  1125. S32 discard_level = 0;
  1126. while (width > 1 && height > 1 && discard_level < MAX_DISCARD_LEVEL)
  1127. {
  1128. width >>= 1;
  1129. height >>= 1;
  1130. discard_level++;
  1131. }
  1132. ((LLImageJ2C *)((LLImageFormatted*)image))->setDiscardLevel(discard_level);
  1133. }
  1134. success = image->decode(this, 100000.0f);
  1135. }
  1136. image = NULL; // deletes image
  1137. if (!success)
  1138. {
  1139. deleteData();
  1140. llwarns << "Unable to decode image" << name << llendl;
  1141. return false;
  1142. }
  1143. return true;
  1144. }
  1145. #endif
  1146. //---------------------------------------------------------------------------
  1147. // LLImageFormatted
  1148. //---------------------------------------------------------------------------
  1149. //static
  1150. S32 LLImageFormatted::sGlobalFormattedMemory = 0;
  1151. LLImageFormatted::LLImageFormatted(S8 codec)
  1152. : LLImageBase(),
  1153. mCodec(codec),
  1154. mDecoding(0),
  1155. mDecoded(0),
  1156. mDiscardLevel(-1)
  1157. {
  1158. mMemType = LLMemType::MTYPE_IMAGEFORMATTED;
  1159. }
  1160. // virtual
  1161. LLImageFormatted::~LLImageFormatted()
  1162. {
  1163. // NOTE: ~LLimageBase() call to deleteData() calls LLImageBase::deleteData()
  1164. // NOT LLImageFormatted::deleteData()
  1165. deleteData();
  1166. }
  1167. //----------------------------------------------------------------------------
  1168. //virtual
  1169. void LLImageFormatted::resetLastError()
  1170. {
  1171. LLImage::setLastError("");
  1172. }
  1173. //virtual
  1174. void LLImageFormatted::setLastError(const std::string& message, const std::string& filename)
  1175. {
  1176. std::string error = message;
  1177. if (!filename.empty())
  1178. error += std::string(" FILE: ") + filename;
  1179. LLImage::setLastError(error);
  1180. }
  1181. //----------------------------------------------------------------------------
  1182. // static
  1183. LLImageFormatted* LLImageFormatted::createFromType(S8 codec)
  1184. {
  1185. LLImageFormatted* image;
  1186. switch(codec)
  1187. {
  1188. case IMG_CODEC_BMP:
  1189. image = new LLImageBMP();
  1190. break;
  1191. case IMG_CODEC_TGA:
  1192. image = new LLImageTGA();
  1193. break;
  1194. case IMG_CODEC_JPEG:
  1195. image = new LLImageJPEG();
  1196. break;
  1197. case IMG_CODEC_PNG:
  1198. image = new LLImagePNG();
  1199. break;
  1200. case IMG_CODEC_J2C:
  1201. image = new LLImageJ2C();
  1202. break;
  1203. case IMG_CODEC_DXT:
  1204. image = new LLImageDXT();
  1205. break;
  1206. default:
  1207. image = NULL;
  1208. break;
  1209. }
  1210. return image;
  1211. }
  1212. // static
  1213. LLImageFormatted* LLImageFormatted::createFromExtension(const std::string& instring)
  1214. {
  1215. std::string exten;
  1216. size_t dotidx = instring.rfind('.');
  1217. if (dotidx != std::string::npos)
  1218. {
  1219. exten = instring.substr(dotidx+1);
  1220. }
  1221. else
  1222. {
  1223. exten = instring;
  1224. }
  1225. S8 codec = getCodecFromExtension(exten);
  1226. return createFromType(codec);
  1227. }
  1228. //----------------------------------------------------------------------------
  1229. // virtual
  1230. void LLImageFormatted::dump()
  1231. {
  1232. LLImageBase::dump();
  1233. llinfos << "LLImageFormatted"
  1234. << " mDecoding " << mDecoding
  1235. << " mCodec " << S32(mCodec)
  1236. << " mDecoded " << mDecoded
  1237. << llendl;
  1238. }
  1239. //----------------------------------------------------------------------------
  1240. S32 LLImageFormatted::calcDataSize(S32 discard_level)
  1241. {
  1242. if (discard_level < 0)
  1243. {
  1244. discard_level = mDiscardLevel;
  1245. }
  1246. S32 w = getWidth() >> discard_level;
  1247. S32 h = getHeight() >> discard_level;
  1248. w = llmax(w, 1);
  1249. h = llmax(h, 1);
  1250. return w * h * getComponents();
  1251. }
  1252. S32 LLImageFormatted::calcDiscardLevelBytes(S32 bytes)
  1253. {
  1254. llassert(bytes >= 0);
  1255. S32 discard_level = 0;
  1256. while (1)
  1257. {
  1258. S32 bytes_needed = calcDataSize(discard_level); // virtual
  1259. if (bytes_needed <= bytes)
  1260. {
  1261. break;
  1262. }
  1263. discard_level++;
  1264. if (discard_level > MAX_IMAGE_MIP)
  1265. {
  1266. return -1;
  1267. }
  1268. }
  1269. return discard_level;
  1270. }
  1271. //----------------------------------------------------------------------------
  1272. // Subclasses that can handle more than 4 channels should override this function.
  1273. BOOL LLImageFormatted::decodeChannels(LLImageRaw* raw_image,F32 decode_time, S32 first_channel, S32 max_channel)
  1274. {
  1275. llassert( (first_channel == 0) && (max_channel == 4) );
  1276. return decode( raw_image, decode_time ); // Loads first 4 channels by default.
  1277. }
  1278. //----------------------------------------------------------------------------
  1279. // virtual
  1280. U8* LLImageFormatted::allocateData(S32 size)
  1281. {
  1282. U8* res = LLImageBase::allocateData(size); // calls deleteData()
  1283. sGlobalFormattedMemory += getDataSize();
  1284. return res;
  1285. }
  1286. // virtual
  1287. U8* LLImageFormatted::reallocateData(S32 size)
  1288. {
  1289. sGlobalFormattedMemory -= getDataSize();
  1290. U8* res = LLImageBase::reallocateData(size);
  1291. sGlobalFormattedMemory += getDataSize();
  1292. return res;
  1293. }
  1294. // virtual
  1295. void LLImageFormatted::deleteData()
  1296. {
  1297. sGlobalFormattedMemory -= getDataSize();
  1298. LLImageBase::deleteData();
  1299. }
  1300. //----------------------------------------------------------------------------
  1301. // virtual
  1302. void LLImageFormatted::sanityCheck()
  1303. {
  1304. LLImageBase::sanityCheck();
  1305. if (mCodec >= IMG_CODEC_EOF)
  1306. {
  1307. llerrs << "Failed LLImageFormatted::sanityCheck "
  1308. << "decoding " << S32(mDecoding)
  1309. << "decoded " << S32(mDecoded)
  1310. << "codec " << S32(mCodec)
  1311. << llendl;
  1312. }
  1313. }
  1314. //----------------------------------------------------------------------------
  1315. BOOL LLImageFormatted::copyData(U8 *data, S32 size)
  1316. {
  1317. if ( data && ((data != getData()) || (size != getDataSize())) )
  1318. {
  1319. deleteData();
  1320. allocateData(size);
  1321. memcpy(getData(), data, size); /* Flawfinder: ignore */
  1322. }
  1323. return TRUE;
  1324. }
  1325. // LLImageFormatted becomes the owner of data
  1326. void LLImageFormatted::setData(U8 *data, S32 size)
  1327. {
  1328. if (data && data != getData())
  1329. {
  1330. deleteData();
  1331. setDataAndSize(data, size); // Access private LLImageBase members
  1332. sGlobalFormattedMemory += getDataSize();
  1333. }
  1334. }
  1335. void LLImageFormatted::appendData(U8 *data, S32 size)
  1336. {
  1337. if (data)
  1338. {
  1339. if (!getData())
  1340. {
  1341. setData(data, size);
  1342. }
  1343. else
  1344. {
  1345. S32 cursize = getDataSize();
  1346. S32 newsize = cursize + size;
  1347. reallocateData(newsize);
  1348. memcpy(getData() + cursize, data, size);
  1349. FREE_MEM(LLImageBase::getPrivatePool(), data);
  1350. }
  1351. }
  1352. }
  1353. //----------------------------------------------------------------------------
  1354. BOOL LLImageFormatted::load(const std::string &filename)
  1355. {
  1356. resetLastError();
  1357. S32 file_size = 0;
  1358. LLAPRFile infile ;
  1359. infile.open(filename, LL_APR_RB, NULL, &file_size);
  1360. apr_file_t* apr_file = infile.getFileHandle();
  1361. if (!apr_file)
  1362. {
  1363. setLastError("Unable to open file for reading", filename);
  1364. return FALSE;
  1365. }
  1366. if (file_size == 0)
  1367. {
  1368. setLastError("File is empty",filename);
  1369. return FALSE;
  1370. }
  1371. BOOL res;
  1372. U8 *data = allocateData(file_size);
  1373. apr_size_t bytes_read = file_size;
  1374. apr_status_t s = apr_file_read(apr_file, data, &bytes_read); // modifies bytes_read
  1375. if (s != APR_SUCCESS || (S32) bytes_read != file_size)
  1376. {
  1377. deleteData();
  1378. setLastError("Unable to read entire file",filename);
  1379. res = FALSE;
  1380. }
  1381. else
  1382. {
  1383. res = updateData();
  1384. }
  1385. return res;
  1386. }
  1387. BOOL LLImageFormatted::save(const std::string &filename)
  1388. {
  1389. resetLastError();
  1390. LLAPRFile outfile ;
  1391. outfile.open(filename, LL_APR_WB);
  1392. if (!outfile.getFileHandle())
  1393. {
  1394. setLastError("Unable to open file for writing", filename);
  1395. return FALSE;
  1396. }
  1397. outfile.write(getData(), getDataSize());
  1398. outfile.close() ;
  1399. return TRUE;
  1400. }
  1401. // BOOL LLImageFormatted::save(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type)
  1402. // Depricated to remove VFS dependency.
  1403. // Use:
  1404. // LLVFile::writeFile(image->getData(), image->getDataSize(), vfs, uuid, type);
  1405. //----------------------------------------------------------------------------
  1406. S8 LLImageFormatted::getCodec() const
  1407. {
  1408. return mCodec;
  1409. }
  1410. //============================================================================
  1411. static void avg4_colors4(const U8* a, const U8* b, const U8* c, const U8* d, U8* dst)
  1412. {
  1413. dst[0] = (U8)(((U32)(a[0]) + b[0] + c[0] + d[0])>>2);
  1414. dst[1] = (U8)(((U32)(a[1]) + b[1] + c[1] + d[1])>>2);
  1415. dst[2] = (U8)(((U32)(a[2]) + b[2] + c[2] + d[2])>>2);
  1416. dst[3] = (U8)(((U32)(a[3]) + b[3] + c[3] + d[3])>>2);
  1417. }
  1418. static void avg4_colors3(const U8* a, const U8* b, const U8* c, const U8* d, U8* dst)
  1419. {
  1420. dst[0] = (U8)(((U32)(a[0]) + b[0] + c[0] + d[0])>>2);
  1421. dst[1] = (U8)(((U32)(a[1]) + b[1] + c[1] + d[1])>>2);
  1422. dst[2] = (U8)(((U32)(a[2]) + b[2] + c[2] + d[2])>>2);
  1423. }
  1424. static void avg4_colors2(const U8* a, const U8* b, const U8* c, const U8* d, U8* dst)
  1425. {
  1426. dst[0] = (U8)(((U32)(a[0]) + b[0] + c[0] + d[0])>>2);
  1427. dst[1] = (U8)(((U32)(a[1]) + b[1] + c[1] + d[1])>>2);
  1428. }
  1429. //static
  1430. void LLImageBase::generateMip(const U8* indata, U8* mipdata, S32 width, S32 height, S32 nchannels)
  1431. {
  1432. llassert(width > 0 && height > 0);
  1433. U8* data = mipdata;
  1434. S32 in_width = width*2;
  1435. for (S32 h=0; h<height; h++)
  1436. {
  1437. for (S32 w=0; w<width; w++)
  1438. {
  1439. switch(nchannels)
  1440. {
  1441. case 4:
  1442. avg4_colors4(indata, indata+4, indata+4*in_width, indata+4*in_width+4, data);
  1443. break;
  1444. case 3:
  1445. avg4_colors3(indata, indata+3, indata+3*in_width, indata+3*in_width+3, data);
  1446. break;
  1447. case 2:
  1448. avg4_colors2(indata, indata+2, indata+2*in_width, indata+2*in_width+2, data);
  1449. break;
  1450. case 1:
  1451. *(U8*)data = (U8)(((U32)(indata[0]) + indata[1] + indata[in_width] + indata[in_width+1])>>2);
  1452. break;
  1453. default:
  1454. llerrs << "generateMmip called with bad num channels" << llendl;
  1455. }
  1456. indata += nchannels*2;
  1457. data += nchannels;
  1458. }
  1459. indata += nchannels*in_width; // skip odd lines
  1460. }
  1461. }
  1462. //============================================================================
  1463. //static
  1464. F32 LLImageBase::calc_download_priority(F32 virtual_size, F32 visible_pixels, S32 bytes_sent)
  1465. {
  1466. F32 w_priority;
  1467. F32 bytes_weight = 1.f;
  1468. if (!bytes_sent)
  1469. {
  1470. bytes_weight = 20.f;
  1471. }
  1472. else if (bytes_sent < 1000)
  1473. {
  1474. bytes_weight = 1.f;
  1475. }
  1476. else if (bytes_sent < 2000)
  1477. {
  1478. bytes_weight = 1.f/1.5f;
  1479. }
  1480. else if (bytes_sent < 4000)
  1481. {
  1482. bytes_weight = 1.f/3.f;
  1483. }
  1484. else if (bytes_sent < 8000)
  1485. {
  1486. bytes_weight = 1.f/6.f;
  1487. }
  1488. else if (bytes_sent < 16000)
  1489. {
  1490. bytes_weight = 1.f/12.f;
  1491. }
  1492. else if (bytes_sent < 32000)
  1493. {
  1494. bytes_weight = 1.f/20.f;
  1495. }
  1496. else if (bytes_sent < 64000)
  1497. {
  1498. bytes_weight = 1.f/32.f;
  1499. }
  1500. else
  1501. {
  1502. bytes_weight = 1.f/64.f;
  1503. }
  1504. bytes_weight *= bytes_weight;
  1505. //llinfos << "VS: " << virtual_size << llendl;
  1506. F32 virtual_size_factor = virtual_size / (10.f*10.f);
  1507. // The goal is for weighted priority to be <= 0 when we've reached a point where
  1508. // we've sent enough data.
  1509. //llinfos << "BytesSent: " << bytes_sent << llendl;
  1510. //llinfos << "BytesWeight: " << bytes_weight << llendl;
  1511. //llinfos << "PreLog: " << bytes_weight * virtual_size_factor << llendl;
  1512. w_priority = (F32)log10(bytes_weight * virtual_size_factor);
  1513. //llinfos << "PreScale: " << w_priority << llendl;
  1514. // We don't want to affect how MANY bytes we send based on the visible pixels, but the order
  1515. // in which they're sent. We post-multiply so we don't change the zero point.
  1516. if (w_priority > 0.f)
  1517. {
  1518. F32 pixel_weight = (F32)log10(visible_pixels + 1)*3.0f;
  1519. w_priority *= pixel_weight;
  1520. }
  1521. return w_priority;
  1522. }
  1523. //============================================================================