diff options
author | Ankur Ahlawat <anchor@lindenlab.com> | 2017-11-16 01:59:00 -0800 |
---|---|---|
committer | Ankur Ahlawat <anchor@lindenlab.com> | 2017-11-16 01:59:00 -0800 |
commit | 93100236ae34eaa9cd3fa314e7e770339c13eba7 (patch) | |
tree | e384d0f81f46900a95a33d0b6b92cbf285e624bf /indra/llimage | |
parent | a416dee2cc8c802bba24803c43805fd7fa0f484c (diff) | |
parent | b6d22de58850fc9a5b34eeb5b7930e5845bfc42d (diff) |
Merged lindenlab/viewer-release into default
Diffstat (limited to 'indra/llimage')
-rw-r--r-- | indra/llimage/llimage.cpp | 60 | ||||
-rw-r--r-- | indra/llimage/llimage.h | 3 | ||||
-rw-r--r-- | indra/llimage/llimagepng.cpp | 4 | ||||
-rw-r--r-- | indra/llimage/llpngwrapper.cpp | 8 | ||||
-rw-r--r-- | indra/llimage/llpngwrapper.h | 2 |
5 files changed, 68 insertions, 9 deletions
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp index a07ea14621..ad765b6415 100644 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -1436,7 +1436,7 @@ void LLImageRaw::copyScaled( LLImageRaw* src ) bool LLImageRaw::scale( S32 new_width, S32 new_height, bool scale_image_data ) { S32 components = getComponents(); - if (! ((1 == components) || (3 == components) || (4 == components) )) + if (components != 1 && components != 3 && components != 4) { LL_WARNS() << "Invalid getComponents value (" << components << ")" << LL_ENDL; return false; @@ -1512,6 +1512,55 @@ bool LLImageRaw::scale( S32 new_width, S32 new_height, bool scale_image_data ) return true ; } +LLPointer<LLImageRaw> LLImageRaw::scaled(S32 new_width, S32 new_height) +{ + LLPointer<LLImageRaw> result; + + S32 components = getComponents(); + if (components != 1 && components != 3 && components != 4) + { + LL_WARNS() << "Invalid getComponents value (" << components << ")" << LL_ENDL; + return result; + } + + if (isBufferInvalid()) + { + LL_WARNS() << "Invalid image buffer" << LL_ENDL; + return result; + } + + S32 old_width = getWidth(); + S32 old_height = getHeight(); + + if ((old_width == new_width) && (old_height == new_height)) + { + result = new LLImageRaw(old_width, old_height, components); + if (!result) + { + LL_WARNS() << "Failed to allocate new image" << LL_ENDL; + return result; + } + memcpy(result->getData(), getData(), getDataSize()); + } + else + { + S32 new_data_size = new_width * new_height * components; + + if (new_data_size > 0) + { + result = new LLImageRaw(new_width, new_height, components); + if (!result) + { + LL_WARNS() << "Failed to allocate new image" << LL_ENDL; + return result; + } + bilinear_scale(getData(), old_width, old_height, components, old_width*components, result->getData(), new_width, new_height, components, new_width*components); + } + } + + return result; +} + void LLImageRaw::copyLineScaled( U8* in, U8* out, S32 in_pixel_len, S32 out_pixel_len, S32 in_pixel_step, S32 out_pixel_step ) { const S32 components = getComponents(); @@ -1785,10 +1834,13 @@ static std::string find_file(std::string &name, S8 *codec) #endif EImageCodec LLImageBase::getCodecFromExtension(const std::string& exten) { - for (int i=0; i<(int)(NUM_FILE_EXTENSIONS); i++) + if (!exten.empty()) { - if (exten == file_extensions[i].exten) - return file_extensions[i].codec; + for (int i = 0; i < (int)(NUM_FILE_EXTENSIONS); i++) + { + if (exten == file_extensions[i].exten) + return file_extensions[i].codec; + } } return IMG_CODEC_INVALID; } diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h index d0bd4a2aef..958c9fad3d 100644 --- a/indra/llimage/llimage.h +++ b/indra/llimage/llimage.h @@ -215,7 +215,8 @@ public: void expandToPowerOfTwo(S32 max_dim = MAX_IMAGE_SIZE, bool scale_image = true); void contractToPowerOfTwo(S32 max_dim = MAX_IMAGE_SIZE, bool scale_image = true); void biasedScaleToPowerOfTwo(S32 max_dim = MAX_IMAGE_SIZE); - bool scale( S32 new_width, S32 new_height, bool scale_image = true ); + bool scale(S32 new_width, S32 new_height, bool scale_image = true); + LLPointer<LLImageRaw> scaled(S32 new_width, S32 new_height); // Fill the buffer with a constant color void fill( const LLColor4U& color ); diff --git a/indra/llimage/llimagepng.cpp b/indra/llimage/llimagepng.cpp index a299602d79..a4823ed859 100644 --- a/indra/llimage/llimagepng.cpp +++ b/indra/llimage/llimagepng.cpp @@ -124,12 +124,12 @@ bool LLImagePNG::encode(const LLImageRaw* raw_image, F32 encode_time) // Temporary buffer to hold the encoded image. Note: the final image // size should be much smaller due to compression. - U32 bufferSize = getWidth() * getHeight() * getComponents() + 1024; + U32 bufferSize = getWidth() * getHeight() * getComponents() + 8192; U8* tmpWriteBuffer = new U8[ bufferSize ]; // Delegate actual encoding work to wrapper LLPngWrapper pngWrapper; - if (! pngWrapper.writePng(raw_image, tmpWriteBuffer)) + if (!pngWrapper.writePng(raw_image, tmpWriteBuffer, bufferSize)) { setLastError(pngWrapper.getErrorMessage()); delete[] tmpWriteBuffer; diff --git a/indra/llimage/llpngwrapper.cpp b/indra/llimage/llpngwrapper.cpp index da289ea889..eb70b78a36 100644 --- a/indra/llimage/llpngwrapper.cpp +++ b/indra/llimage/llpngwrapper.cpp @@ -112,6 +112,11 @@ void LLPngWrapper::readDataCallback(png_structp png_ptr, png_bytep dest, png_siz void LLPngWrapper::writeDataCallback(png_structp png_ptr, png_bytep src, png_size_t length) { PngDataInfo *dataInfo = (PngDataInfo *) png_get_io_ptr(png_ptr); + if (dataInfo->mOffset + length > dataInfo->mDataSize) + { + png_error(png_ptr, "Data write error. Requested data size exceeds available data size."); + return; + } U8 *dest = &dataInfo->mData[dataInfo->mOffset]; memcpy(dest, src, length); dataInfo->mOffset += static_cast<U32>(length); @@ -272,7 +277,7 @@ void LLPngWrapper::updateMetaData() // Method to write raw image into PNG at dest. The raw scanline begins // at the bottom of the image per SecondLife conventions. -BOOL LLPngWrapper::writePng(const LLImageRaw* rawImage, U8* dest) +BOOL LLPngWrapper::writePng(const LLImageRaw* rawImage, U8* dest, size_t destSize) { try { @@ -313,6 +318,7 @@ BOOL LLPngWrapper::writePng(const LLImageRaw* rawImage, U8* dest) PngDataInfo dataPtr; dataPtr.mData = dest; dataPtr.mOffset = 0; + dataPtr.mDataSize = destSize; png_set_write_fn(mWritePngPtr, &dataPtr, &writeDataCallback, &writeFlush); // Setup image params diff --git a/indra/llimage/llpngwrapper.h b/indra/llimage/llpngwrapper.h index 27d7df3bef..8d42317b0f 100644 --- a/indra/llimage/llpngwrapper.h +++ b/indra/llimage/llpngwrapper.h @@ -45,7 +45,7 @@ public: BOOL isValidPng(U8* src); BOOL readPng(U8* src, S32 dataSize, LLImageRaw* rawImage, ImageInfo *infop = NULL); - BOOL writePng(const LLImageRaw* rawImage, U8* dst); + BOOL writePng(const LLImageRaw* rawImage, U8* dst, size_t destSize); U32 getFinalSize(); const std::string& getErrorMessage(); |