llimage.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:41k
源码类别:

游戏引擎

开发平台:

C++ Builder

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