diff options
Diffstat (limited to '')
-rw-r--r-- | linden/indra/llimage/llimage.cpp | 144 |
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 | ||
314 | void 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 | |||
314 | BOOL LLImageRaw::resize(U16 width, U16 height, S8 components) | 329 | BOOL 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. |
660 | void LLImageRaw::copy(LLImageRaw* src) | 669 | void 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. | ||
833 | BOOL 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 | ||
823 | BOOL LLImageRaw::scale( S32 new_width, S32 new_height, BOOL scale_image_data ) | 878 | BOOL 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; |