aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llimage/llimage.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--linden/indra/llimage/llimage.cpp283
1 files changed, 75 insertions, 208 deletions
diff --git a/linden/indra/llimage/llimage.cpp b/linden/indra/llimage/llimage.cpp
index acd6aef..eb4ff46 100644
--- a/linden/indra/llimage/llimage.cpp
+++ b/linden/indra/llimage/llimage.cpp
@@ -36,7 +36,7 @@
36#include "llmath.h" 36#include "llmath.h"
37#include "stdtypes.h" 37#include "stdtypes.h"
38#include "v4coloru.h" 38#include "v4coloru.h"
39#include "llmemory.h" 39#include "llmemtype.h"
40 40
41#include "llimage.h" 41#include "llimage.h"
42#include "llimagebmp.h" 42#include "llimagebmp.h"
@@ -133,7 +133,7 @@ U8* LLImageBase::allocateData(S32 size)
133 llerrs << llformat("LLImageBase::allocateData called with bad dimentions: %dx%dx%d",mWidth,mHeight,mComponents) << llendl; 133 llerrs << llformat("LLImageBase::allocateData called with bad dimentions: %dx%dx%d",mWidth,mHeight,mComponents) << llendl;
134 } 134 }
135 } 135 }
136 else if ((size <= 0 || size > 4096*4096*16) && sSizeOverride == FALSE) 136 else if (size <= 0 || (size > 4096*4096*16 && sSizeOverride == FALSE))
137 { 137 {
138 llerrs << "LLImageBase::allocateData: bad size: " << size << llendl; 138 llerrs << "LLImageBase::allocateData: bad size: " << size << llendl;
139 } 139 }
@@ -167,7 +167,7 @@ U8* LLImageBase::reallocateData(S32 size)
167 if (mData) 167 if (mData)
168 { 168 {
169 S32 bytes = llmin(mDataSize, size); 169 S32 bytes = llmin(mDataSize, size);
170 memcpy(new_datap, mData, bytes); 170 memcpy(new_datap, mData, bytes); /* Flawfinder: ignore */
171 delete[] mData; 171 delete[] mData;
172 } 172 }
173 mData = new_datap; 173 mData = new_datap;
@@ -216,7 +216,8 @@ LLImageRaw::LLImageRaw(U8 *data, U16 width, U16 height, S8 components)
216 : LLImageBase() 216 : LLImageBase()
217{ 217{
218 mMemType = LLMemType::MTYPE_IMAGERAW; 218 mMemType = LLMemType::MTYPE_IMAGERAW;
219 copyData(data, width, height, components); 219 allocateDataSize(width, height, components);
220 memcpy(getData(), data, width*height*components);
220 ++sRawImageCount; 221 ++sRawImageCount;
221} 222}
222 223
@@ -258,16 +259,6 @@ void LLImageRaw::deleteData()
258 LLImageBase::deleteData(); 259 LLImageBase::deleteData();
259} 260}
260 261
261BOOL LLImageRaw::copyData(U8 *data, U16 width, U16 height, S8 components)
262{
263 if (!resize(width, height, components))
264 {
265 return FALSE;
266 }
267 memcpy(getData(), data, width*height*components);
268 return TRUE;
269}
270
271BOOL LLImageRaw::resize(U16 width, U16 height, S8 components) 262BOOL LLImageRaw::resize(U16 width, U16 height, S8 components)
272{ 263{
273 if ((getWidth() == width) && (getHeight() == height) && (getComponents() == components)) 264 if ((getWidth() == width) && (getHeight() == height) && (getComponents() == components))
@@ -288,11 +279,16 @@ U8 * LLImageRaw::getSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height) const
288 U8 *data = new U8[width*height*getComponents()]; 279 U8 *data = new U8[width*height*getComponents()];
289 280
290 // Should do some simple bounds checking 281 // Should do some simple bounds checking
282 if (!data)
283 {
284 llerrs << "Out of memory in LLImageRaw::getSubImage" << llendl;
285 return NULL;
286 }
291 287
292 U32 i; 288 U32 i;
293 for (i = y_pos; i < y_pos+height; i++) 289 for (i = y_pos; i < y_pos+height; i++)
294 { 290 {
295 memcpy(data + i*width*getComponents(), 291 memcpy(data + i*width*getComponents(), /* Flawfinder: ignore */
296 getData() + ((y_pos + i)*getWidth() + x_pos)*getComponents(), getComponents()*width); 292 getData() + ((y_pos + i)*getWidth() + x_pos)*getComponents(), getComponents()*width);
297 } 293 }
298 return data; 294 return data;
@@ -328,7 +324,7 @@ BOOL LLImageRaw::setSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height,
328 { 324 {
329 from_offset = i*width*getComponents(); 325 from_offset = i*width*getComponents();
330 } 326 }
331 memcpy(getData() + to_offset*getComponents(), 327 memcpy(getData() + to_offset*getComponents(), /* Flawfinder: ignore */
332 data + from_offset, getComponents()*width); 328 data + from_offset, getComponents()*width);
333 } 329 }
334 } 330 }
@@ -345,7 +341,7 @@ BOOL LLImageRaw::setSubImage(U32 x_pos, U32 y_pos, U32 width, U32 height,
345 { 341 {
346 from_offset = (height - 1 - i)*width*getComponents(); 342 from_offset = (height - 1 - i)*width*getComponents();
347 } 343 }
348 memcpy(getData() + to_offset*getComponents(), 344 memcpy(getData() + to_offset*getComponents(), /* Flawfinder: ignore */
349 data + from_offset, getComponents()*width); 345 data + from_offset, getComponents()*width);
350 } 346 }
351 } 347 }
@@ -392,14 +388,19 @@ void LLImageRaw::verticalFlip()
392 LLMemType mt1((LLMemType::EMemType)mMemType); 388 LLMemType mt1((LLMemType::EMemType)mMemType);
393 S32 row_bytes = getWidth() * getComponents(); 389 S32 row_bytes = getWidth() * getComponents();
394 U8* line_buffer = new U8[row_bytes]; 390 U8* line_buffer = new U8[row_bytes];
391 if (!line_buffer )
392 {
393 llerrs << "Out of memory in LLImageRaw::verticalFlip()" << llendl;
394 return;
395 }
395 S32 mid_row = getHeight() / 2; 396 S32 mid_row = getHeight() / 2;
396 for( S32 row = 0; row < mid_row; row++ ) 397 for( S32 row = 0; row < mid_row; row++ )
397 { 398 {
398 U8* row_a_data = getData() + row * row_bytes; 399 U8* row_a_data = getData() + row * row_bytes;
399 U8* row_b_data = getData() + (getHeight() - 1 - row) * row_bytes; 400 U8* row_b_data = getData() + (getHeight() - 1 - row) * row_bytes;
400 memcpy( line_buffer, row_a_data, row_bytes ); 401 memcpy( line_buffer, row_a_data, row_bytes ); /* Flawfinder: ignore */
401 memcpy( row_a_data, row_b_data, row_bytes ); 402 memcpy( row_a_data, row_b_data, row_bytes ); /* Flawfinder: ignore */
402 memcpy( row_b_data, line_buffer, row_bytes ); 403 memcpy( row_b_data, line_buffer, row_bytes ); /* Flawfinder: ignore */
403 } 404 }
404 delete[] line_buffer; 405 delete[] line_buffer;
405} 406}
@@ -691,7 +692,7 @@ void LLImageRaw::copyUnscaled(LLImageRaw* src)
691 llassert( src->getComponents() == dst->getComponents() ); 692 llassert( src->getComponents() == dst->getComponents() );
692 llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) ); 693 llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) );
693 694
694 memcpy( dst->getData(), src->getData(), getWidth() * getHeight() * getComponents() ); 695 memcpy( dst->getData(), src->getData(), getWidth() * getHeight() * getComponents() ); /* Flawfinder: ignore */
695} 696}
696 697
697 698
@@ -775,7 +776,7 @@ void LLImageRaw::copyScaled( LLImageRaw* src )
775 776
776 if( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) ) 777 if( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) )
777 { 778 {
778 memcpy( dst->getData(), src->getData(), getWidth() * getHeight() * getComponents() ); 779 memcpy( dst->getData(), src->getData(), getWidth() * getHeight() * getComponents() ); /* Flawfinder: ignore */
779 return; 780 return;
780 } 781 }
781 782
@@ -841,7 +842,12 @@ void LLImageRaw::scale( S32 new_width, S32 new_height, BOOL scale_image_data )
841 // copy out existing image data 842 // copy out existing image data
842 S32 temp_data_size = old_width * old_height * getComponents(); 843 S32 temp_data_size = old_width * old_height * getComponents();
843 U8* temp_buffer = new U8[ temp_data_size ]; 844 U8* temp_buffer = new U8[ temp_data_size ];
844 memcpy(temp_buffer, getData(), temp_data_size); 845 if (!temp_buffer)
846 {
847 llerrs << "Out of memory in LLImageRaw::scale( S32 new_width, S32 new_height, BOOL scale_image_data )" << llendl;
848 return;
849 }
850 memcpy(temp_buffer, getData(), temp_data_size); /* Flawfinder: ignore */
845 851
846 // allocate new image data, will delete old data 852 // allocate new image data, will delete old data
847 U8* new_buffer = allocateDataSize(new_width, new_height, getComponents()); 853 U8* new_buffer = allocateDataSize(new_width, new_height, getComponents());
@@ -850,7 +856,7 @@ void LLImageRaw::scale( S32 new_width, S32 new_height, BOOL scale_image_data )
850 { 856 {
851 if (row < old_height) 857 if (row < old_height)
852 { 858 {
853 memcpy(new_buffer + (new_width * row * getComponents()), temp_buffer + (old_width * row * getComponents()), getComponents() * llmin(old_width, new_width)); 859 memcpy(new_buffer + (new_width * row * getComponents()), temp_buffer + (old_width * row * getComponents()), getComponents() * llmin(old_width, new_width)); /* Flawfinder: ignore */
854 if (old_width < new_width) 860 if (old_width < new_width)
855 { 861 {
856 // pad out rest of row with black 862 // pad out rest of row with black
@@ -1204,7 +1210,7 @@ bool LLImageRaw::createFromFile(const LLString &filename, bool j2c_lowest_mip_on
1204 llassert(image.notNull()); 1210 llassert(image.notNull());
1205 1211
1206 U8 *buffer = image->allocateData(length); 1212 U8 *buffer = image->allocateData(length);
1207 ifs.read ((char*)buffer, length); 1213 ifs.read ((char*)buffer, length); /* Flawfinder: ignore */
1208 ifs.close(); 1214 ifs.close();
1209 1215
1210 image->updateData(); 1216 image->updateData();
@@ -1243,25 +1249,8 @@ bool LLImageRaw::createFromFile(const LLString &filename, bool j2c_lowest_mip_on
1243//static 1249//static
1244S32 LLImageFormatted::sGlobalFormattedMemory = 0; 1250S32 LLImageFormatted::sGlobalFormattedMemory = 0;
1245 1251
1246//static
1247LLWorkerThread* LLImageFormatted::sWorkerThread = NULL;
1248
1249//static
1250void LLImageFormatted::initClass(bool threaded, bool run_always)
1251{
1252 sWorkerThread = new LLWorkerThread(threaded, run_always);
1253}
1254
1255//static
1256void LLImageFormatted::cleanupClass()
1257{
1258 delete sWorkerThread;
1259 sWorkerThread = NULL;
1260}
1261
1262
1263LLImageFormatted::LLImageFormatted(S8 codec) 1252LLImageFormatted::LLImageFormatted(S8 codec)
1264 : LLImageBase(), LLWorkerClass(sWorkerThread, "ImageFormatted"), 1253 : LLImageBase(),
1265 mCodec(codec), 1254 mCodec(codec),
1266 mDecoding(0), 1255 mDecoding(0),
1267 mDecoded(0), 1256 mDecoded(0),
@@ -1276,64 +1265,14 @@ LLImageFormatted::~LLImageFormatted()
1276 // NOTE: ~LLimageBase() call to deleteData() calls LLImageBase::deleteData() 1265 // NOTE: ~LLimageBase() call to deleteData() calls LLImageBase::deleteData()
1277 // NOT LLImageFormatted::deleteData() 1266 // NOT LLImageFormatted::deleteData()
1278 deleteData(); 1267 deleteData();
1279 releaseDecodedData();
1280}
1281
1282//----------------------------------------------------------------------------
1283
1284//virtual
1285void LLImageFormatted::startWork(S32 param)
1286{
1287 if (mDecoding) llerrs << "WTF?" << llendl;
1288}
1289
1290bool LLImageFormatted::doWork(S32 param)
1291{
1292 if (!(isWorking())) llerrs << "WTF?" << llendl;
1293 llassert(mDecodedImage.notNull());
1294 if (param == 0)
1295 {
1296 // Decode primary channels
1297 mDecoded = decode(mDecodedImage, .001f); // 1ms
1298 }
1299 else
1300 {
1301 // Decode aux channel
1302 mDecoded = decode(mDecodedImage, .001f, param, param); // 1ms
1303 }
1304 if (mDecoded)
1305 {
1306 return true;
1307 }
1308 else
1309 {
1310 return false;
1311 }
1312}
1313
1314void LLImageFormatted::endWork(S32 param, bool aborted)
1315{
1316 if (mDecoding) llerrs << "WTF?" << llendl;
1317 if (!mDecoded) llerrs << "WTF?" << llendl;
1318} 1268}
1319 1269
1320//---------------------------------------------------------------------------- 1270//----------------------------------------------------------------------------
1321 1271
1322// static 1272// static
1323LLImageFormatted* LLImageFormatted::createFromExtension(const LLString& instring) 1273LLImageFormatted* LLImageFormatted::createFromType(S8 codec)
1324{ 1274{
1325 LLString exten; 1275 LLImageFormatted* image;
1326 size_t dotidx = instring.rfind('.');
1327 if (dotidx != LLString::npos)
1328 {
1329 exten = instring.substr(dotidx+1);
1330 }
1331 else
1332 {
1333 exten = instring;
1334 }
1335 S8 codec = get_codec(exten);
1336 LLPointer<LLImageFormatted> image;
1337 switch(codec) 1276 switch(codec)
1338 { 1277 {
1339 case IMG_CODEC_BMP: 1278 case IMG_CODEC_BMP:
@@ -1354,10 +1293,28 @@ LLImageFormatted* LLImageFormatted::createFromExtension(const LLString& instring
1354 image = new LLImageDXT(); 1293 image = new LLImageDXT();
1355 break; 1294 break;
1356 default: 1295 default:
1296 image = NULL;
1357 break; 1297 break;
1358 } 1298 }
1359 return image; 1299 return image;
1360} 1300}
1301
1302// static
1303LLImageFormatted* LLImageFormatted::createFromExtension(const LLString& instring)
1304{
1305 LLString exten;
1306 size_t dotidx = instring.rfind('.');
1307 if (dotidx != LLString::npos)
1308 {
1309 exten = instring.substr(dotidx+1);
1310 }
1311 else
1312 {
1313 exten = instring;
1314 }
1315 S8 codec = get_codec(exten);
1316 return createFromType(codec);
1317}
1361//---------------------------------------------------------------------------- 1318//----------------------------------------------------------------------------
1362 1319
1363// virtual 1320// virtual
@@ -1374,15 +1331,6 @@ void LLImageFormatted::dump()
1374 1331
1375//---------------------------------------------------------------------------- 1332//----------------------------------------------------------------------------
1376 1333
1377void LLImageFormatted::readHeader(U8* data, S32 size)
1378{
1379 if (size <= 0)
1380 {
1381 size = calcHeaderSize();
1382 }
1383 copyData(data, size); // calls updateData()
1384}
1385
1386S32 LLImageFormatted::calcDataSize(S32 discard_level) 1334S32 LLImageFormatted::calcDataSize(S32 discard_level)
1387{ 1335{
1388 if (discard_level < 0) 1336 if (discard_level < 0)
@@ -1426,82 +1374,6 @@ BOOL LLImageFormatted::decode(LLImageRaw* raw_image,F32 decode_time, S32 first_
1426 return decode( raw_image, decode_time ); // Loads first 4 channels by default. 1374 return decode( raw_image, decode_time ); // Loads first 4 channels by default.
1427} 1375}
1428 1376
1429// virtual
1430BOOL LLImageFormatted::requestDecodedData(LLPointer<LLImageRaw>& raw, S32 discard, F32 decode_time)
1431{
1432 llassert(getData() && getDataSize());
1433 // For most codecs, only mDiscardLevel data is available. (see LLImageDXT for exception)
1434 if (discard >= 0 && discard != mDiscardLevel)
1435 {
1436 llerrs << "Request for invalid discard level" << llendl;
1437 }
1438 if (haveWork())
1439 {
1440 checkWork();
1441 }
1442 if (!mDecoded)
1443 {
1444 if (!haveWork())
1445 {
1446 llassert(!mDecoding);
1447 mDecodedImage = new LLImageRaw(getWidth(), getHeight(), getComponents());
1448 addWork(0);
1449 }
1450 return FALSE;
1451 }
1452 else
1453 {
1454 llassert(mDecodedImage.notNull());
1455 llassert(!mDecoding);
1456 raw = mDecodedImage;
1457 return TRUE;
1458 }
1459}
1460
1461BOOL LLImageFormatted::requestDecodedAuxData(LLPointer<LLImageRaw>& raw, S32 channel,
1462 S32 discard, F32 decode_time)
1463{
1464 llassert(getData() && getDataSize());
1465 // For most codecs, only mDiscardLevel data is available. (see LLImageDXT for exception)
1466 if (discard >= 0 && discard != mDiscardLevel)
1467 {
1468 llerrs << "Request for invalid discard level" << llendl;
1469 }
1470 if (haveWork())
1471 {
1472 checkWork();
1473 }
1474 if (!mDecoded)
1475 {
1476 if (!haveWork())
1477 {
1478 llassert(!mDecoding);
1479 mDecodedImage = new LLImageRaw(getWidth(), getHeight(), 1);
1480 addWork(channel);
1481 }
1482 return FALSE;
1483 }
1484 else
1485 {
1486 llassert(mDecodedImage.notNull());
1487 llassert(!mDecoding);
1488 raw = mDecodedImage;
1489 return TRUE;
1490 }
1491}
1492
1493
1494// virtual
1495void LLImageFormatted::releaseDecodedData()
1496{
1497 if (mDecoded || mDecoding)
1498 {
1499 mDecodedImage = NULL; // deletes image
1500 mDecoded = FALSE;
1501 mDecoding = FALSE;
1502 }
1503}
1504
1505//---------------------------------------------------------------------------- 1377//----------------------------------------------------------------------------
1506 1378
1507// virtual 1379// virtual
@@ -1549,47 +1421,42 @@ void LLImageFormatted::sanityCheck()
1549 1421
1550BOOL LLImageFormatted::copyData(U8 *data, S32 size) 1422BOOL LLImageFormatted::copyData(U8 *data, S32 size)
1551{ 1423{
1552 if (data && data != getData()) 1424 if ( (data && data != getData()) || (size != getDataSize()) )
1553 { 1425 {
1554 deleteData(); 1426 deleteData();
1555 allocateData(size); 1427 allocateData(size);
1556 memcpy(getData(), data, size); 1428 memcpy(getData(), data, size); /* Flawfinder: ignore */
1557 } 1429 }
1558 updateData(); // virtual
1559
1560 return TRUE; 1430 return TRUE;
1561} 1431}
1562 1432
1563BOOL LLImageFormatted::appendData(U8 *data, S32 size) 1433// LLImageFormatted becomes the owner of data
1434void LLImageFormatted::setData(U8 *data, S32 size)
1564{ 1435{
1565 LLMemType mt1((LLMemType::EMemType)mMemType); 1436 if (data && data != getData())
1566 S32 old_size = getDataSize();
1567 U8* old_data = getData();
1568 S32 new_size = old_size + size;
1569 U8* new_data = new U8[new_size];
1570 // resize the image
1571 setDataAndSize(new_data, new_size);
1572 // copy the old data and delete it
1573 memcpy(new_data, old_data, old_size);
1574 delete old_data;
1575 // if we have new data, copy it and call updateData()
1576 if (data)
1577 { 1437 {
1578 memcpy(new_data + old_size, data, size); 1438 deleteData();
1579 updateData(); // virtual 1439 setDataAndSize(data, size); // Access private LLImageBase members
1440 sGlobalFormattedMemory += getDataSize();
1580 } 1441 }
1581 return TRUE;
1582} 1442}
1583 1443
1584BOOL LLImageFormatted::setData(U8 *data, S32 size) 1444void LLImageFormatted::appendData(U8 *data, S32 size)
1585{ 1445{
1586 if (data && data != getData()) 1446 if (data)
1587 { 1447 {
1588 deleteData(); 1448 if (!getData())
1589 setDataAndSize(data, size); // Access private LLImageBase members 1449 {
1590 sGlobalFormattedMemory += getDataSize(); 1450 setData(data, size);
1451 }
1452 else
1453 {
1454 S32 cursize = getDataSize();
1455 S32 newsize = cursize + size;
1456 reallocateData(newsize);
1457 memcpy(getData() + cursize, data, size);
1458 }
1591 } 1459 }
1592 return updateData(); // virtual
1593} 1460}
1594 1461
1595//---------------------------------------------------------------------------- 1462//----------------------------------------------------------------------------
@@ -1662,8 +1529,6 @@ S8 LLImageFormatted::getCodec() const
1662 1529
1663//============================================================================ 1530//============================================================================
1664 1531
1665//----------------------------------------------------------------------------
1666
1667static void avg4_colors4(const U8* a, const U8* b, const U8* c, const U8* d, U8* dst) 1532static void avg4_colors4(const U8* a, const U8* b, const U8* c, const U8* d, U8* dst)
1668{ 1533{
1669 dst[0] = (U8)(((U32)(a[0]) + b[0] + c[0] + d[0])>>2); 1534 dst[0] = (U8)(((U32)(a[0]) + b[0] + c[0] + d[0])>>2);
@@ -1789,3 +1654,5 @@ F32 LLImageBase::calc_download_priority(F32 virtual_size, F32 visible_pixels, S3
1789 1654
1790 return w_priority; 1655 return w_priority;
1791} 1656}
1657
1658//============================================================================