aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llimage/llimage.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--linden/indra/llimage/llimage.cpp144
1 files changed, 94 insertions, 50 deletions
diff --git a/linden/indra/llimage/llimage.cpp b/linden/indra/llimage/llimage.cpp
index 32891e7..db983fb 100644
--- a/linden/indra/llimage/llimage.cpp
+++ b/linden/indra/llimage/llimage.cpp
@@ -4,7 +4,7 @@
4 * 4 *
5 * $LicenseInfo:firstyear=2001&license=viewergpl$ 5 * $LicenseInfo:firstyear=2001&license=viewergpl$
6 * 6 *
7 * Copyright (c) 2001-2009, Linden Research, Inc. 7 * Copyright (c) 2001-2010, Linden Research, Inc.
8 * 8 *
9 * Second Life Viewer Source Code 9 * Second Life Viewer Source Code
10 * The source code in this file ("Source Code") is provided by Linden Lab 10 * The source code in this file ("Source Code") is provided by Linden Lab
@@ -154,7 +154,7 @@ U8* LLImageBase::allocateData(S32 size)
154 size = mWidth * mHeight * mComponents; 154 size = mWidth * mHeight * mComponents;
155 if (size <= 0) 155 if (size <= 0)
156 { 156 {
157 llerrs << llformat("LLImageBase::allocateData called with bad dimentions: %dx%dx%d",mWidth,mHeight,mComponents) << llendl; 157 llerrs << llformat("LLImageBase::allocateData called with bad dimensions: %dx%dx%d",mWidth,mHeight,mComponents) << llendl;
158 } 158 }
159 } 159 }
160 else if (size <= 0 || (size > 4096*4096*16 && sSizeOverride == FALSE)) 160 else if (size <= 0 || (size > 4096*4096*16 && sSizeOverride == FALSE))
@@ -311,6 +311,21 @@ void LLImageRaw::deleteData()
311 LLImageBase::deleteData(); 311 LLImageBase::deleteData();
312} 312}
313 313
314void LLImageRaw::setDataAndSize(U8 *data, S32 width, S32 height, S8 components)
315{
316 if(data == getData())
317 {
318 return ;
319 }
320
321 deleteData();
322
323 LLImageBase::setSize(width, height, components) ;
324 LLImageBase::setDataAndSize(data, width * height * components) ;
325
326 sGlobalRawMemory += getDataSize();
327}
328
314BOOL LLImageRaw::resize(U16 width, U16 height, S8 components) 329BOOL LLImageRaw::resize(U16 width, U16 height, S8 components)
315{ 330{
316 if ((getWidth() == width) && (getHeight() == height) && (getComponents() == components)) 331 if ((getWidth() == width) && (getHeight() == height) && (getComponents() == components))
@@ -412,22 +427,17 @@ void LLImageRaw::verticalFlip()
412{ 427{
413 LLMemType mt1((LLMemType::EMemType)mMemType); 428 LLMemType mt1((LLMemType::EMemType)mMemType);
414 S32 row_bytes = getWidth() * getComponents(); 429 S32 row_bytes = getWidth() * getComponents();
415 U8* line_buffer = new U8[row_bytes]; 430 llassert(row_bytes > 0);
416 if (!line_buffer ) 431 std::vector<U8> line_buffer(row_bytes);
417 {
418 llerrs << "Out of memory in LLImageRaw::verticalFlip()" << llendl;
419 return;
420 }
421 S32 mid_row = getHeight() / 2; 432 S32 mid_row = getHeight() / 2;
422 for( S32 row = 0; row < mid_row; row++ ) 433 for( S32 row = 0; row < mid_row; row++ )
423 { 434 {
424 U8* row_a_data = getData() + row * row_bytes; 435 U8* row_a_data = getData() + row * row_bytes;
425 U8* row_b_data = getData() + (getHeight() - 1 - row) * row_bytes; 436 U8* row_b_data = getData() + (getHeight() - 1 - row) * row_bytes;
426 memcpy( line_buffer, row_a_data, row_bytes ); /* Flawfinder: ignore */ 437 memcpy( &line_buffer[0], row_a_data, row_bytes );
427 memcpy( row_a_data, row_b_data, row_bytes ); /* Flawfinder: ignore */ 438 memcpy( row_a_data, row_b_data, row_bytes );
428 memcpy( row_b_data, line_buffer, row_bytes ); /* Flawfinder: ignore */ 439 memcpy( row_b_data, &line_buffer[0], row_bytes );
429 } 440 }
430 delete[] line_buffer;
431} 441}
432 442
433 443
@@ -555,22 +565,21 @@ void LLImageRaw::compositeScaled4onto3(LLImageRaw* src)
555 565
556 llassert( (4 == src->getComponents()) && (3 == dst->getComponents()) ); 566 llassert( (4 == src->getComponents()) && (3 == dst->getComponents()) );
557 567
558 // Vertical: scale but no composite
559 S32 temp_data_size = src->getWidth() * dst->getHeight() * src->getComponents(); 568 S32 temp_data_size = src->getWidth() * dst->getHeight() * src->getComponents();
560 U8* temp_buffer = new U8[ temp_data_size ]; 569 llassert_always(temp_data_size > 0);
570 std::vector<U8> temp_buffer(temp_data_size);
571
572 // Vertical: scale but no composite
561 for( S32 col = 0; col < src->getWidth(); col++ ) 573 for( S32 col = 0; col < src->getWidth(); col++ )
562 { 574 {
563 copyLineScaled( src->getData() + (src->getComponents() * col), temp_buffer + (src->getComponents() * col), src->getHeight(), dst->getHeight(), src->getWidth(), src->getWidth() ); 575 copyLineScaled( src->getData() + (src->getComponents() * col), &temp_buffer[0] + (src->getComponents() * col), src->getHeight(), dst->getHeight(), src->getWidth(), src->getWidth() );
564 } 576 }
565 577
566 // Horizontal: scale and composite 578 // Horizontal: scale and composite
567 for( S32 row = 0; row < dst->getHeight(); row++ ) 579 for( S32 row = 0; row < dst->getHeight(); row++ )
568 { 580 {
569 compositeRowScaled4onto3( temp_buffer + (src->getComponents() * src->getWidth() * row), dst->getData() + (dst->getComponents() * dst->getWidth() * row), src->getWidth(), dst->getWidth() ); 581 compositeRowScaled4onto3( &temp_buffer[0] + (src->getComponents() * src->getWidth() * row), dst->getData() + (dst->getComponents() * dst->getWidth() * row), src->getWidth(), dst->getWidth() );
570 } 582 }
571
572 // Clean up
573 delete[] temp_buffer;
574} 583}
575 584
576 585
@@ -659,10 +668,13 @@ void LLImageRaw::fill( const LLColor4U& color )
659// Src and dst can be any size. Src and dst can each have 3 or 4 components. 668// Src and dst can be any size. Src and dst can each have 3 or 4 components.
660void LLImageRaw::copy(LLImageRaw* src) 669void LLImageRaw::copy(LLImageRaw* src)
661{ 670{
662 LLImageRaw* dst = this; // Just for clarity. 671 if (!src)
672 {
673 llwarns << "LLImageRaw::copy called with a null src pointer" << llendl;
674 return;
675 }
663 676
664 llassert( (3 == src->getComponents()) || (4 == src->getComponents()) ); 677 LLImageRaw* dst = this; // Just for clarity.
665 llassert( (3 == dst->getComponents()) || (4 == dst->getComponents()) );
666 678
667 if( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) ) 679 if( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) )
668 { 680 {
@@ -800,25 +812,68 @@ void LLImageRaw::copyScaled( LLImageRaw* src )
800 return; 812 return;
801 } 813 }
802 814
803 // Vertical
804 S32 temp_data_size = src->getWidth() * dst->getHeight() * getComponents(); 815 S32 temp_data_size = src->getWidth() * dst->getHeight() * getComponents();
805 llassert_always(temp_data_size > 0); 816 llassert_always(temp_data_size > 0);
806 U8* temp_buffer = new U8[ temp_data_size ]; 817 std::vector<U8> temp_buffer(temp_data_size);
818
819 // Vertical
807 for( S32 col = 0; col < src->getWidth(); col++ ) 820 for( S32 col = 0; col < src->getWidth(); col++ )
808 { 821 {
809 copyLineScaled( src->getData() + (getComponents() * col), temp_buffer + (getComponents() * col), src->getHeight(), dst->getHeight(), src->getWidth(), src->getWidth() ); 822 copyLineScaled( src->getData() + (getComponents() * col), &temp_buffer[0] + (getComponents() * col), src->getHeight(), dst->getHeight(), src->getWidth(), src->getWidth() );
810 } 823 }
811 824
812 // Horizontal 825 // Horizontal
813 for( S32 row = 0; row < dst->getHeight(); row++ ) 826 for( S32 row = 0; row < dst->getHeight(); row++ )
814 { 827 {
815 copyLineScaled( temp_buffer + (getComponents() * src->getWidth() * row), dst->getData() + (getComponents() * dst->getWidth() * row), src->getWidth(), dst->getWidth(), 1, 1 ); 828 copyLineScaled( &temp_buffer[0] + (getComponents() * src->getWidth() * row), dst->getData() + (getComponents() * dst->getWidth() * row), src->getWidth(), dst->getWidth(), 1, 1 );
816 } 829 }
817
818 // Clean up
819 delete[] temp_buffer;
820} 830}
821 831
832//scale down image by not blending a pixel with its neighbors.
833BOOL LLImageRaw::scaleDownWithoutBlending( S32 new_width, S32 new_height)
834{
835 LLMemType mt1((LLMemType::EMemType)mMemType);
836
837 S8 c = getComponents() ;
838 llassert((1 == c) || (3 == c) || (4 == c) );
839
840 S32 old_width = getWidth();
841 S32 old_height = getHeight();
842
843 S32 new_data_size = old_width * new_height * c ;
844 llassert_always(new_data_size > 0);
845
846 F32 ratio_x = (F32)old_width / new_width ;
847 F32 ratio_y = (F32)old_height / new_height ;
848 if( ratio_x < 1.0f || ratio_y < 1.0f )
849 {
850 return TRUE; // Nothing to do.
851 }
852 ratio_x -= 1.0f ;
853 ratio_y -= 1.0f ;
854
855 U8* new_data = new U8[new_data_size] ;
856 llassert_always(new_data != NULL) ;
857
858 U8* old_data = getData() ;
859 S32 i, j, k, s, t;
860 for(i = 0, s = 0, t = 0 ; i < new_height ; i++)
861 {
862 for(j = 0 ; j < new_width ; j++)
863 {
864 for(k = 0 ; k < c ; k++)
865 {
866 new_data[s++] = old_data[t++] ;
867 }
868 t += (S32)(ratio_x * c + 0.1f) ;
869 }
870 t += (S32)(ratio_y * old_width * c + 0.1f) ;
871 }
872
873 setDataAndSize(new_data, new_width, new_height, c) ;
874
875 return TRUE ;
876}
822 877
823BOOL LLImageRaw::scale( S32 new_width, S32 new_height, BOOL scale_image_data ) 878BOOL LLImageRaw::scale( S32 new_width, S32 new_height, BOOL scale_image_data )
824{ 879{
@@ -837,12 +892,14 @@ BOOL LLImageRaw::scale( S32 new_width, S32 new_height, BOOL scale_image_data )
837 892
838 if (scale_image_data) 893 if (scale_image_data)
839 { 894 {
840 // Vertical
841 S32 temp_data_size = old_width * new_height * getComponents(); 895 S32 temp_data_size = old_width * new_height * getComponents();
842 U8* temp_buffer = new U8[ temp_data_size ]; 896 llassert_always(temp_data_size > 0);
897 std::vector<U8> temp_buffer(temp_data_size);
898
899 // Vertical
843 for( S32 col = 0; col < old_width; col++ ) 900 for( S32 col = 0; col < old_width; col++ )
844 { 901 {
845 copyLineScaled( getData() + (getComponents() * col), temp_buffer + (getComponents() * col), old_height, new_height, old_width, old_width ); 902 copyLineScaled( getData() + (getComponents() * col), &temp_buffer[0] + (getComponents() * col), old_height, new_height, old_width, old_width );
846 } 903 }
847 904
848 deleteData(); 905 deleteData();
@@ -852,25 +909,15 @@ BOOL LLImageRaw::scale( S32 new_width, S32 new_height, BOOL scale_image_data )
852 // Horizontal 909 // Horizontal
853 for( S32 row = 0; row < new_height; row++ ) 910 for( S32 row = 0; row < new_height; row++ )
854 { 911 {
855 copyLineScaled( temp_buffer + (getComponents() * old_width * row), new_buffer + (getComponents() * new_width * row), old_width, new_width, 1, 1 ); 912 copyLineScaled( &temp_buffer[0] + (getComponents() * old_width * row), new_buffer + (getComponents() * new_width * row), old_width, new_width, 1, 1 );
856 } 913 }
857
858 // Clean up
859 delete[] temp_buffer;
860 } 914 }
861 else 915 else
862 { 916 {
863 // copy out existing image data 917 // copy out existing image data
864 S32 temp_data_size = old_width * old_height * getComponents(); 918 S32 temp_data_size = old_width * old_height * getComponents();
865 U8* temp_buffer = new U8[ temp_data_size ]; 919 std::vector<U8> temp_buffer(temp_data_size);
866 if (!temp_buffer) 920 memcpy(&temp_buffer[0], getData(), temp_data_size);
867 {
868 llwarns << "Out of memory in LLImageRaw::scale: old (w, h, c) = (" << old_width << ", " << old_height << ", " << (S32)getComponents() <<
869 ") ; new (w, h, c) = (" << new_width << ", " << new_height << ", " << (S32)getComponents() << ")" << llendl;
870
871 return FALSE ;
872 }
873 memcpy(temp_buffer, getData(), temp_data_size); /* Flawfinder: ignore */
874 921
875 // allocate new image data, will delete old data 922 // allocate new image data, will delete old data
876 U8* new_buffer = allocateDataSize(new_width, new_height, getComponents()); 923 U8* new_buffer = allocateDataSize(new_width, new_height, getComponents());
@@ -879,7 +926,7 @@ BOOL LLImageRaw::scale( S32 new_width, S32 new_height, BOOL scale_image_data )
879 { 926 {
880 if (row < old_height) 927 if (row < old_height)
881 { 928 {
882 memcpy(new_buffer + (new_width * row * getComponents()), temp_buffer + (old_width * row * getComponents()), getComponents() * llmin(old_width, new_width)); /* Flawfinder: ignore */ 929 memcpy(new_buffer + (new_width * row * getComponents()), &temp_buffer[0] + (old_width * row * getComponents()), getComponents() * llmin(old_width, new_width));
883 if (old_width < new_width) 930 if (old_width < new_width)
884 { 931 {
885 // pad out rest of row with black 932 // pad out rest of row with black
@@ -892,9 +939,6 @@ BOOL LLImageRaw::scale( S32 new_width, S32 new_height, BOOL scale_image_data )
892 memset(new_buffer + (new_width * row * getComponents()), 0, new_width * getComponents()); 939 memset(new_buffer + (new_width * row * getComponents()), 0, new_width * getComponents());
893 } 940 }
894 } 941 }
895
896 // Clean up
897 delete[] temp_buffer;
898 } 942 }
899 943
900 return TRUE ; 944 return TRUE ;
@@ -1234,7 +1278,7 @@ bool LLImageRaw::createFromFile(const std::string &filename, bool j2c_lowest_mip
1234 llassert(image.notNull()); 1278 llassert(image.notNull());
1235 1279
1236 U8 *buffer = image->allocateData(length); 1280 U8 *buffer = image->allocateData(length);
1237 ifs.read ((char*)buffer, length); /* Flawfinder: ignore */ 1281 ifs.read ((char*)buffer, length);
1238 ifs.close(); 1282 ifs.close();
1239 1283
1240 BOOL success; 1284 BOOL success;