summaryrefslogtreecommitdiff
path: root/indra/llimage
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llimage')
-rw-r--r--indra/llimage/CMakeLists.txt2
-rw-r--r--indra/llimage/llimage.cpp32
-rw-r--r--indra/llimage/llimage.h14
-rw-r--r--indra/llimage/llimagedimensionsinfo.cpp139
-rw-r--r--indra/llimage/llimagedimensionsinfo.h139
-rw-r--r--indra/llimage/llimagepng.cpp1
6 files changed, 309 insertions, 18 deletions
diff --git a/indra/llimage/CMakeLists.txt b/indra/llimage/CMakeLists.txt
index 22be4078a1..a69621a57b 100644
--- a/indra/llimage/CMakeLists.txt
+++ b/indra/llimage/CMakeLists.txt
@@ -21,6 +21,7 @@ include_directories(
set(llimage_SOURCE_FILES
llimagebmp.cpp
llimage.cpp
+ llimagedimensionsinfo.cpp
llimagedxt.cpp
llimagej2c.cpp
llimagejpeg.cpp
@@ -35,6 +36,7 @@ set(llimage_HEADER_FILES
llimage.h
llimagebmp.h
+ llimagedimensionsinfo.h
llimagedxt.h
llimagej2c.h
llimagejpeg.h
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index 7d0de18c7c..aa7c8c789a 100644
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -93,9 +93,10 @@ LLImageBase::LLImageBase()
mWidth(0),
mHeight(0),
mComponents(0),
+ mBadBufferAllocation(false),
+ mAllowOverSize(false),
mMemType(LLMemType::MTYPE_IMAGEBASE)
{
- mBadBufferAllocation = FALSE ;
}
// virtual
@@ -134,8 +135,6 @@ void LLImageBase::sanityCheck()
}
}
-BOOL LLImageBase::sSizeOverride = FALSE;
-
// virtual
void LLImageBase::deleteData()
{
@@ -157,23 +156,32 @@ U8* LLImageBase::allocateData(S32 size)
llerrs << llformat("LLImageBase::allocateData called with bad dimensions: %dx%dx%d",mWidth,mHeight,mComponents) << llendl;
}
}
- if (size < 1 || (size > 4096*4096*16 && sSizeOverride == FALSE))
+
+ //make this function thread-safe.
+ static const U32 MAX_BUFFER_SIZE = 4096 * 4096 * 16 ; //256 MB
+ if (size < 1 || size > MAX_BUFFER_SIZE)
{
llinfos << "width: " << mWidth << " height: " << mHeight << " components: " << mComponents << llendl ;
+ if(mAllowOverSize)
+ {
+ llinfos << "Oversize: " << size << llendl ;
+ }
+ else
+ {
llerrs << "LLImageBase::allocateData: bad size: " << size << llendl;
}
-
+ }
if (!mData || size != mDataSize)
{
deleteData(); // virtual
- mBadBufferAllocation = FALSE ;
+ mBadBufferAllocation = false ;
mData = new U8[size];
if (!mData)
{
llwarns << "allocate image data: " << size << llendl;
size = 0 ;
mWidth = mHeight = 0 ;
- mBadBufferAllocation = TRUE ;
+ mBadBufferAllocation = true ;
}
mDataSize = size;
}
@@ -222,7 +230,7 @@ U8* LLImageBase::getData()
return mData;
}
-BOOL LLImageBase::isBufferInvalid()
+bool LLImageBase::isBufferInvalid()
{
return mBadBufferAllocation || mData == NULL ;
}
@@ -258,7 +266,11 @@ LLImageRaw::LLImageRaw(U16 width, U16 height, S8 components)
: LLImageBase()
{
mMemType = LLMemType::MTYPE_IMAGERAW;
- llassert( S32(width) * S32(height) * S32(components) <= MAX_IMAGE_DATA_SIZE );
+ //llassert( S32(width) * S32(height) * S32(components) <= MAX_IMAGE_DATA_SIZE );
+ if(S32(width) * S32(height) * S32(components) > MAX_IMAGE_DATA_SIZE)
+ {
+ llwarns << "over size: width: " << (S32)width << " height: " << (S32)height << " components: " << (S32)components << llendl ;
+ }
allocateDataSize(width, height, components);
++sRawImageCount;
}
@@ -1326,7 +1338,7 @@ LLImageFormatted::LLImageFormatted(S8 codec)
mCodec(codec),
mDecoding(0),
mDecoded(0),
- mDiscardLevel(0)
+ mDiscardLevel(-1)
{
mMemType = LLMemType::MTYPE_IMAGEFORMATTED;
}
diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h
index 686f583886..10444e7f89 100644
--- a/indra/llimage/llimage.h
+++ b/indra/llimage/llimage.h
@@ -48,7 +48,7 @@ const S32 MAX_IMAGE_SIZE = (1<<MAX_IMAGE_MIP); // 2048
const S32 MIN_IMAGE_AREA = MIN_IMAGE_SIZE * MIN_IMAGE_SIZE;
const S32 MAX_IMAGE_AREA = MAX_IMAGE_SIZE * MAX_IMAGE_SIZE;
const S32 MAX_IMAGE_COMPONENTS = 8;
-const S32 MAX_IMAGE_DATA_SIZE = MAX_IMAGE_AREA * MAX_IMAGE_COMPONENTS;
+const S32 MAX_IMAGE_DATA_SIZE = MAX_IMAGE_AREA * MAX_IMAGE_COMPONENTS; //2048 * 2048 * 8 = 16 MB
// Note! These CANNOT be changed without modifying simulator code
// *TODO: change both to 1024 when SIM texture fetching is deprecated
@@ -124,10 +124,12 @@ public:
const U8 *getData() const ;
U8 *getData() ;
- BOOL isBufferInvalid() ;
+ bool isBufferInvalid() ;
void setSize(S32 width, S32 height, S32 ncomponents);
U8* allocateDataSize(S32 width, S32 height, S32 ncomponents, S32 size = -1); // setSize() + allocateData()
+ void enableOverSize() {mAllowOverSize = true ;}
+ void disableOverSize() {mAllowOverSize = false; }
protected:
// special accessor to allow direct setting of mData and mDataSize by LLImageFormatted
@@ -140,8 +142,6 @@ public:
// <= 0 priority means that there's no need for more data.
static F32 calc_download_priority(F32 virtual_size, F32 visible_area, S32 bytes_sent);
- static void setSizeOverride(BOOL enabled) { sSizeOverride = enabled; }
-
static EImageCodec getCodecFromExtension(const std::string& exten);
private:
@@ -153,12 +153,10 @@ private:
S8 mComponents;
- BOOL mBadBufferAllocation ;
-
+ bool mBadBufferAllocation ;
+ bool mAllowOverSize ;
public:
LLMemType::DeclareMemType& mMemType; // debug
-
- static BOOL sSizeOverride;
};
// Raw representation of an image (used for textures, and other uncompressed formats
diff --git a/indra/llimage/llimagedimensionsinfo.cpp b/indra/llimage/llimagedimensionsinfo.cpp
new file mode 100644
index 0000000000..890b49b50a
--- /dev/null
+++ b/indra/llimage/llimagedimensionsinfo.cpp
@@ -0,0 +1,139 @@
+/**
+ * @file llimagedimensionsinfo.cpp
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ *
+ * Copyright (c) 2002-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+#include "stdtypes.h"
+
+#include "llimagejpeg.h"
+
+#include "llimagedimensionsinfo.h"
+
+bool LLImageDimensionsInfo::load(const std::string& src_filename,U32 codec)
+{
+ clean();
+
+ mSrcFilename = src_filename;
+
+ S32 file_size = 0;
+ apr_status_t s = mInfile.open(src_filename, LL_APR_RB, NULL, &file_size);
+
+ if (s != APR_SUCCESS)
+ {
+ setLastError("Unable to open file for reading", src_filename);
+ return false;
+ }
+
+ if (file_size == 0)
+ {
+ setLastError("File is empty",src_filename);
+ return false;
+ }
+
+ switch (codec)
+ {
+ case IMG_CODEC_BMP:
+ return getImageDimensionsBmp();
+ case IMG_CODEC_TGA:
+ return getImageDimensionsTga();
+ case IMG_CODEC_JPEG:
+ return getImageDimensionsJpeg();
+ case IMG_CODEC_PNG:
+ return getImageDimensionsPng();
+ default:
+ return false;
+
+ }
+}
+
+
+bool LLImageDimensionsInfo::getImageDimensionsBmp()
+{
+ const S32 BMP_FILE_HEADER_SIZE = 14;
+
+ mInfile.seek(APR_CUR,BMP_FILE_HEADER_SIZE+4);
+ mWidth = read_reverse_s32();
+ mHeight = read_reverse_s32();
+
+ return true;
+}
+
+bool LLImageDimensionsInfo::getImageDimensionsTga()
+{
+ const S32 TGA_FILE_HEADER_SIZE = 12;
+
+ mInfile.seek(APR_CUR,TGA_FILE_HEADER_SIZE);
+ mWidth = read_byte() | read_byte() << 8;
+ mHeight = read_byte() | read_byte() << 8;
+
+ return true;
+}
+
+bool LLImageDimensionsInfo::getImageDimensionsPng()
+{
+ const S32 PNG_FILE_MARKER_SIZE = 8;
+
+ mInfile.seek(APR_CUR,PNG_FILE_MARKER_SIZE + 8/*header offset+chunk length+chunk type*/);
+ mWidth = read_s32();
+ mHeight = read_s32();
+
+ return true;
+}
+
+
+bool LLImageDimensionsInfo::getImageDimensionsJpeg()
+{
+ clean();
+ FILE *fp = fopen (mSrcFilename.c_str(), "rb");
+ if (fp == NULL)
+ {
+ setLastError("Unable to open file for reading", mSrcFilename);
+ return false;
+ }
+ /* Init jpeg */
+ jpeg_error_mgr jerr;
+ jpeg_decompress_struct cinfo;
+ cinfo.err = jpeg_std_error(&jerr);
+
+ jpeg_create_decompress (&cinfo);
+ jpeg_stdio_src (&cinfo, fp);
+ jpeg_read_header (&cinfo, TRUE);
+ cinfo.out_color_space = JCS_RGB;
+ jpeg_start_decompress (&cinfo);
+
+ mHeight = cinfo.output_width;
+ mHeight = cinfo.output_height;
+
+ jpeg_destroy_decompress(&cinfo);
+ fclose(fp);
+
+ return true;
+}
+
diff --git a/indra/llimage/llimagedimensionsinfo.h b/indra/llimage/llimagedimensionsinfo.h
new file mode 100644
index 0000000000..2c8f675fa1
--- /dev/null
+++ b/indra/llimage/llimagedimensionsinfo.h
@@ -0,0 +1,139 @@
+/**
+ * @file llimagedimentionsinfo.h
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+
+#ifndef LL_LLIMAGEDIMENSIONSINFO_H
+#define LL_LLIMAGEDIMENSIONSINFO_H
+
+//-----------------------------------------------------------------------------
+// LLImageDimensionsInfo
+// helper class to get image dimensions WITHOUT loading image to memore
+// usefull when image may be too large...
+//-----------------------------------------------------------------------------
+class LLImageDimensionsInfo
+{
+public:
+ LLImageDimensionsInfo():
+ mData(NULL)
+ ,mHeight(0)
+ ,mWidth(0)
+ {}
+ ~LLImageDimensionsInfo()
+ {
+ clean();
+ }
+
+ bool load(const std::string& src_filename,U32 codec);
+ S32 getWidth() const { return mWidth;}
+ S32 getHeight() const { return mHeight;}
+
+ const std::string& getLastError()
+ {
+ return mLastError;
+ }
+protected:
+
+ void clean()
+ {
+ mInfile.close();
+ delete[] mData;
+ mData = NULL;
+ mWidth = 0;
+ mHeight = 0;
+ }
+
+ U8* getData()
+ {
+ return mData;
+ }
+
+
+ void setLastError(const std::string& message, const std::string& filename)
+ {
+ std::string error = message;
+ if (!filename.empty())
+ error += std::string(" FILE: ") + filename;
+ mLastError = error;
+ }
+
+
+ bool getImageDimensionsBmp();
+ bool getImageDimensionsTga();
+ bool getImageDimensionsPng();
+ bool getImageDimensionsJpeg();
+
+ S32 read_s32()
+ {
+ char p[4];
+ mInfile.read(&p[0],4);
+ S32 temp = (((S32)p[3]) & 0x000000FF) |
+ (((S32)p[2] << 8 ) & 0x0000FF00) |
+ (((S32)p[1] << 16) & 0x00FF0000) |
+ (((S32)p[0] << 24) & 0xFF000000);
+
+ return temp;
+ }
+ S32 read_reverse_s32()
+ {
+ char p[4];
+ mInfile.read(&p[0],4);
+ S32 temp = (((S32)p[0]) & 0x000000FF) |
+ (((S32)p[1] << 8 ) & 0x0000FF00) |
+ (((S32)p[2] << 16) & 0x00FF0000) |
+ (((S32)p[3] << 24) & 0xFF000000);
+
+ return temp;
+ }
+
+ U8 read_byte()
+ {
+ U8 bt;
+ mInfile.read(&bt,1);
+ return bt;
+ }
+
+ U16 read_short()
+ {
+ return read_byte() << 8 | read_byte();
+ }
+
+protected:
+ LLAPRFile mInfile ;
+ std::string mSrcFilename;
+
+ std::string mLastError;
+
+ U8* mData;
+
+ S32 mWidth;
+ S32 mHeight;
+};
+#endif
diff --git a/indra/llimage/llimagepng.cpp b/indra/llimage/llimagepng.cpp
index b5de104e61..a6ab246a2c 100644
--- a/indra/llimage/llimagepng.cpp
+++ b/indra/llimage/llimagepng.cpp
@@ -135,6 +135,7 @@ BOOL LLImagePNG::encode(const LLImageRaw* raw_image, F32 encode_time)
if (! pngWrapper.writePng(raw_image, mTmpWriteBuffer))
{
setLastError(pngWrapper.getErrorMessage());
+ delete[] mTmpWriteBuffer;
return FALSE;
}