summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMerov Linden <merov@lindenlab.com>2013-12-20 13:49:20 -0800
committerMerov Linden <merov@lindenlab.com>2013-12-20 13:49:20 -0800
commit7372afaae4aa7097ffad1e9c070b8b9d9a611f62 (patch)
treead7aea7e219ae9e91d504e747e17c06ea284b7c8
parent6578144b7eda1dae885e5cc172751203b1d16c2d (diff)
ACME-1236 : WIP : Implement colorTransform filter, grayscale and sepia using it, add parameter to llimage_libtest to use filters
-rwxr-xr-xindra/integration_tests/llimage_libtest/llimage_libtest.cpp34
-rwxr-xr-xindra/llimage/llimage.cpp38
-rwxr-xr-xindra/llimage/llimage.h8
-rw-r--r--indra/newview/llsnapshotlivepreview.cpp4
4 files changed, 72 insertions, 12 deletions
diff --git a/indra/integration_tests/llimage_libtest/llimage_libtest.cpp b/indra/integration_tests/llimage_libtest/llimage_libtest.cpp
index 034c816742..e485136f58 100755
--- a/indra/integration_tests/llimage_libtest/llimage_libtest.cpp
+++ b/indra/integration_tests/llimage_libtest/llimage_libtest.cpp
@@ -83,6 +83,9 @@ static const char USAGE[] = "\n"
" -rev, --reversible\n"
" Set the compression to be lossless (reversible in j2c parlance).\n"
" Only valid for output j2c images.\n"
+" -f, --filter <name>\n"
+" Apply the filter <name> to the input images.\n"
+" Note: so far, only grayscale and sepia are supported.\n"
" -log, --logmetrics <metric>\n"
" Log performance data for <metric>. Results in <metric>.slp\n"
" Note: so far, only ImageCompressionTester has been tested.\n"
@@ -350,6 +353,7 @@ int main(int argc, char** argv)
int blocks_size = -1;
int levels = 0;
bool reversible = false;
+ std::string filter_name = "";
// Init whatever is necessary
ll_init_apr();
@@ -523,6 +527,26 @@ int main(int argc, char** argv)
break;
}
}
+ else if (!strcmp(argv[arg], "--filter") || !strcmp(argv[arg], "-f"))
+ {
+ // '--filter' needs to be specified with a named filter argument
+ // Note: for the moment, only sepia and grayscale are supported
+ if ((arg + 1) < argc)
+ {
+ filter_name = argv[arg+1];
+ }
+ if (((arg + 1) >= argc) || (filter_name[0] == '-'))
+ {
+ // We don't have an argument left in the arg list or the next argument is another option
+ std::cout << "No --filter argument given, no filter will be applied" << std::endl;
+ }
+ else
+ {
+ arg += 1; // Skip that arg now we know it's a valid test name
+ if ((arg + 1) == argc) // Break out of the loop if we reach the end of the arg list
+ break;
+ }
+ }
else if (!strcmp(argv[arg], "--analyzeperformance") || !strcmp(argv[arg], "-a"))
{
analyze_performance = true;
@@ -568,6 +592,16 @@ int main(int argc, char** argv)
std::cout << "Error: Image " << *in_file << " could not be loaded" << std::endl;
continue;
}
+
+ // Apply filter if any
+ if (filter_name == "sepia")
+ {
+ raw_image->filterSepia();
+ }
+ else if (filter_name == "grayscale")
+ {
+ raw_image->filterGrayScale();
+ }
// Save file
if (out_file != out_end)
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index e5281feff0..73e6f48a8d 100755
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -30,6 +30,8 @@
#include "llmath.h"
#include "v4coloru.h"
+#include "m3math.h"
+#include "v3math.h"
#include "llimagebmp.h"
#include "llimagetga.h"
@@ -933,22 +935,42 @@ BOOL LLImageRaw::scale( S32 new_width, S32 new_height, BOOL scale_image_data )
return TRUE ;
}
-// *TODO : Implement real color transform
-// Merov : This is temporary code for testing...
-void LLImageRaw::colorTransform()
+// Filter Operations
+void LLImageRaw::filterGrayScale()
+{
+ LLMatrix3 gray_scale;
+ LLVector3 luminosity(0.2125, 0.7154, 0.0721);
+ gray_scale.setRows(luminosity, luminosity, luminosity);
+ gray_scale.transpose();
+ colorTransform(gray_scale);
+}
+
+void LLImageRaw::filterSepia()
+{
+ LLMatrix3 sepia;
+ sepia.setRows(LLVector3(0.3588, 0.7044, 0.1368),
+ LLVector3(0.2990, 0.5870, 0.1140),
+ LLVector3(0.2392, 0.4696, 0.0912));
+ sepia.transpose();
+ colorTransform(sepia);
+}
+
+// Filter Primitives
+void LLImageRaw::colorTransform(const LLMatrix3 &transform)
{
const S32 components = getComponents();
llassert( components >= 1 && components <= 4 );
S32 pixels = getWidth() * getHeight();
U8* dst_data = getData();
- llinfos << "Merov : Convert the image to Black and White!!! pixels = " << pixels << ", comp = " << components << llendl;
for( S32 i=0; i<pixels; i++ )
{
- U8 gray = (U8)(((U32)(dst_data[0]) + (U32)(dst_data[1]) + (U32)(dst_data[2]))/3);
- dst_data[0] = gray;
- dst_data[1] = gray;
- dst_data[2] = gray;
+ LLVector3 src((F32)(dst_data[VRED]),(F32)(dst_data[VGREEN]),(F32)(dst_data[VBLUE]));
+ LLVector3 dst = src * transform;
+ dst.clamp(0.0f,255.0f);
+ dst_data[VRED] = dst.mV[VRED];
+ dst_data[VGREEN] = dst.mV[VGREEN];
+ dst_data[VBLUE] = dst.mV[VBLUE];
dst_data += components;
}
}
diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h
index 96c37f5436..d6b7e65c76 100755
--- a/indra/llimage/llimage.h
+++ b/indra/llimage/llimage.h
@@ -71,6 +71,7 @@ const S32 HTTP_PACKET_SIZE = 1496;
class LLImageFormatted;
class LLImageRaw;
class LLColor4U;
+class LLMatrix3;
class LLPrivateMemoryPool;
typedef enum e_image_codec
@@ -256,8 +257,11 @@ public:
// Src and dst are same size. Src has 4 components. Dst has 3 components.
void compositeUnscaled4onto3( LLImageRaw* src );
- // Filter operations
- void colorTransform();
+ // Filter Operations
+ void filterGrayScale();
+ void filterSepia();
+ // Filter Primitives
+ void colorTransform(const LLMatrix3 &transform);
protected:
// Create an image from a local file (generally used in tools)
diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp
index ab9788a88b..2931178ace 100644
--- a/indra/newview/llsnapshotlivepreview.cpp
+++ b/indra/newview/llsnapshotlivepreview.cpp
@@ -589,7 +589,7 @@ void LLSnapshotLivePreview::generateThumbnailImage(BOOL force_update)
// Merov : Filter also the thumbnail?
if (getFilter() == 1)
{
- raw->colorTransform();
+ raw->filterGrayScale();
}
mThumbnailImage = LLViewerTextureManager::getLocalTexture(raw.get(), FALSE);
mThumbnailUpToDate = TRUE ;
@@ -698,7 +698,7 @@ BOOL LLSnapshotLivePreview::onIdle( void* snapshot_preview )
// Merov : Time to apply the filter to mPreviewImage!!!
if (previewp->getFilter() == 1)
{
- previewp->mPreviewImage->colorTransform();
+ previewp->mPreviewImage->filterGrayScale();
}
// delete any existing image