--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mmserv/thumbnailengine/ImaamiSrc/DCIetd.cpp Tue Feb 02 01:08:46 2010 +0200
@@ -0,0 +1,512 @@
+/*
+* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:
+* CDCIETD
+* Display specific color contrast enhancement,
+* Image Enhancement for Transflective Displays version 2,
+* IETD 2.
+*
+*/
+
+
+
+// Include Files
+#include <e32std.h> // The basic definitions
+#include <fbs.h> // For FBS bitmap
+#include "DCIetd.h" // The DCIetd class
+
+
+// MEMBER FUNCTIONS
+//=============================================================================
+
+
+
+
+/*
+-----------------------------------------------------------------------------
+
+ CDCIetd
+
+ Constructor
+
+ Default constructor, initializes member variables to initial values
+
+ Return Values: none
+
+-----------------------------------------------------------------------------
+*/
+CDCIetd::CDCIetd()
+{
+ // Set default values for parameters (from init file)
+ iParameters.aWhitePixels = WhitePixels;
+ iParameters.aBlackPixels = BlackPixels;
+ iParameters.aStretchLimit = StretchLimit;
+ iParameters.aSaturationGain = SaturationGain;
+ iParameters.aBitLimit = BitLimit;
+ iParameters.aWBC = WBC;
+ iParameters.aDBC = DBC;
+}
+
+
+
+
+/*
+-----------------------------------------------------------------------------
+
+ CDCIetd
+
+ NewLC
+
+ Factory function to instantiate the class.
+ This function leaves the class pointer to the cleanup stack
+ May leave with KErrNoMemory if no memory available
+
+ Return Values: CDCIetd* self: pointer to the class instance
+
+-----------------------------------------------------------------------------
+*/
+CDCIetd* CDCIetd::NewLC()
+{
+ CDCIetd* self = new (ELeave) CDCIetd();
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ return self;
+}
+
+
+
+
+/*
+-----------------------------------------------------------------------------
+
+ CDCIetd
+
+ NewL
+
+ Factory function to instantiate the class.
+ May leave with KErrNoMemory if no memory available
+
+ Return Values: CDCIetd* self: pointer to the class instance
+
+-----------------------------------------------------------------------------
+*/
+CDCIetd* CDCIetd::NewL()
+{
+ CDCIetd* self = CDCIetd::NewLC();
+ CleanupStack::Pop();
+ return self;
+}
+
+
+
+
+/*
+-----------------------------------------------------------------------------
+
+ CDCIetd
+
+ ConstructL
+
+ Second phase constructor. Does nothing at the moment
+
+ Return Values: none
+
+ -----------------------------------------------------------------------------
+*/
+void CDCIetd::ConstructL()
+{
+ // This function is intentionally left blank.
+}
+
+
+
+
+/*
+-----------------------------------------------------------------------------
+
+ CDCIetd
+
+ Destructor
+
+ Return Values: none
+
+-----------------------------------------------------------------------------
+*/
+CDCIetd::~CDCIetd()
+{
+ // This function is intentionally left blank.
+}
+
+
+
+
+/*
+-----------------------------------------------------------------------------
+
+ CDCIetd
+
+ Analyze
+
+ Analyze image referenced by aBPtr
+
+ Return Values: none
+
+-----------------------------------------------------------------------------
+*/
+// Analyze image referenced by aBPtr
+void CDCIetd::Analyze(CFbsBitmap& aBPtr)
+{
+
+ //EColor16M image is needed
+ if (aBPtr.DisplayMode() != EColor16M) return;
+
+ //Do analysis
+ GatherHistograms(aBPtr);
+ MakeMappings();
+}
+
+
+
+
+/*
+-----------------------------------------------------------------------------
+
+ CDCIetd
+
+ ProcessL
+
+ Process image referenced by aImage (modify aImage).
+ May leave with KErrNoMemory if no memory available
+
+ Return Values: none
+
+-----------------------------------------------------------------------------
+*/
+void CDCIetd::ProcessL (CFbsBitmap& aImage) // image reference
+{
+ TUint r, g, b; // Color components
+ TUint lum; // Brightness estimate
+ TInt dr, dg, db; // Differences to brightness
+ TUint8* dataPtr; // Pointer to data
+
+ //EColor16M image is needed
+ if (aImage.DisplayMode() != EColor16M) return;
+
+ //Line Buffer and pointer to the data
+ TUint imageWidth = aImage.SizeInPixels().iWidth;
+ TUint scanLineLengthInBytes = aImage.ScanLineLength(imageWidth, aImage.DisplayMode());
+
+ //Allocate buffer for scanline
+ iScanLineBuffer = HBufC8::NewMaxL(scanLineLengthInBytes);
+ //Pointer to scanline
+ TPtr8 linePtr = iScanLineBuffer->Des();
+
+ //Step through image pixels and do stretching
+ //and saturation increase
+ //---------------------------------------------
+
+ //Read all lines
+ for (TInt lineNo=0; lineNo<aImage.SizeInPixels().iHeight; ++lineNo)
+ {
+ //Get line
+ aImage.GetScanLine(linePtr, TPoint(0, lineNo), imageWidth, aImage.DisplayMode());
+ //CHECK! CONST_CAST not used in every algorithm which way is better?
+ dataPtr = CONST_CAST(TUint8*, linePtr.Ptr());
+
+ //Step through pixels in line
+ for (TUint x=0; x < imageWidth; ++x)
+ {
+ // Map color componets according to mapping LUTs
+ b = iMap[2][*dataPtr++];
+ g = iMap[1][*dataPtr++];
+ r = iMap[0][*dataPtr++];
+
+ //Compute brightness estimate
+ //lum=0.299r+0.587g+0.114b; //true Y
+ //lum=(32768+19595*r+38470*g+7471*b)>>16; //Y
+ //lum = (r+g+b)/3; //Simple approximation
+ lum=(r+(g<<1)+b)>>2; //More effective simple approximation
+
+ //Compute componentwise differences to luminance
+ dr = r-lum;
+ dg = g-lum;
+ db = b-lum;
+
+ //Increase differences => saturation increases.
+ //Use gain parameter for adjusting the strength of the effect.
+ b += iParameters.aSaturationGain*db/32;
+ g += iParameters.aSaturationGain*dg/32;
+ r += iParameters.aSaturationGain*dr/32;
+
+ //Save data to same image & same pixels
+ dataPtr -= 3;
+
+ //Limit to available dynamic range [0,255].
+ *dataPtr++ = Limit255(b);
+ *dataPtr++ = Limit255(g);
+ *dataPtr++ = Limit255(r);
+ }
+
+ //Save line
+ aImage.SetScanLine(linePtr, lineNo);
+ }
+
+ //Free memory
+ delete(iScanLineBuffer);
+ iScanLineBuffer = 0;
+}
+
+
+
+
+/*
+-----------------------------------------------------------------------------
+
+ CDCIetd
+
+ GatherHistograms
+
+ Gather histograms and make cumulative histogram.
+
+ Return Values: none
+
+-----------------------------------------------------------------------------
+*/
+void CDCIetd::GatherHistograms (const CFbsBitmap& aImage) // Pointer to the image bitmap
+{
+ const TUint8* dataPtr; //Pointer to data
+ TInt lineNo; //Line number
+ TUint x; //Pixel index
+ TUint color; //Color index
+ TUint count; // Number of colors in each component
+
+ //Compute image width & allocate scan line memory
+ TUint imageWidth = aImage.SizeInPixels().iWidth;
+ TUint histScanLineLengthInBytes = aImage.ScanLineLength(imageWidth, aImage.DisplayMode());
+ iScanLineBuffer = HBufC8::NewMaxL(histScanLineLengthInBytes);
+
+ //Pointer to line
+ TPtr8 linePtr = iScanLineBuffer->Des();
+
+ //Clear histograms
+ Mem::FillZ(iHistogram, sizeof(iHistogram));
+
+ // Read all lines and gather histograms
+ for (lineNo=0; lineNo<aImage.SizeInPixels().iHeight; lineNo++)
+ {
+ //Get line
+ aImage.GetScanLine(linePtr, TPoint(0, lineNo), imageWidth, aImage.DisplayMode());
+ dataPtr = linePtr.Ptr();
+
+ //Step through pixels
+ for (x=imageWidth; x != 0; --x)
+ {
+ ++iHistogram[2][*dataPtr++]; // Increase Blue bin value
+ ++iHistogram[1][*dataPtr++]; // Increase Green bin value
+ ++iHistogram[0][*dataPtr++]; // Increase Red bin value
+ }
+ }
+
+ //Make cumulative histograms & count colors in each histogram
+ for (color=0; color<3; ++color)
+ {
+ // Count used colors
+ count=0;
+ for (x=0; x<256; ++x)
+ {
+ if (iHistogram[color][x]>0) count++;
+ }
+
+ // Compute increased stretch limit if a color component has less colors than iBitLimit.
+ // Otherwise use predetermined stretch limit.
+ if (count<iParameters.aBitLimit)
+ iReducedStretchLimit[color] = (TUint8)(iParameters.aStretchLimit*count/iParameters.aBitLimit+255-255*count/iParameters.aBitLimit);
+ else
+ iReducedStretchLimit[color] = iParameters.aStretchLimit;
+
+ //Make cumulative histogram
+ for (x=1; x<256; ++x)
+ iHistogram[color][x] += iHistogram[color][x-1];
+
+ }
+
+ //Free memory
+ delete(iScanLineBuffer);
+ iScanLineBuffer = 0;
+}
+
+
+
+
+/*
+-----------------------------------------------------------------------------
+
+ CDCIetd
+
+ MakeMappings
+
+ Make mapping function look-up table (LUT).
+
+ Return Values: none
+
+-----------------------------------------------------------------------------
+*/
+void CDCIetd::MakeMappings()
+{
+ TUint MinBins[3];// Smallest existing values in histogram
+ TUint MaxBins[3];// Largest existing values in histogram
+ TUint minBin; // Minimum of smallest existing values
+ TUint maxBin; // Maximum of largest existing values
+ TUint x; // Index
+
+ // Stretching limit variables
+ TUint minShift;
+ TUint maxShift;
+ TUint totalShift;
+
+ TUint color; //Color index
+
+ //Step through colors
+ for (color=0; color<3; ++color)
+ {
+ // Find smallest existing values in histograms, discard darkest pixels
+ // according to blackpixels parameter
+ x = 0; // Start from fist bin
+ MinBins[color] = iParameters.aBlackPixels * iHistogram[color][255]/1000; // Compute value to be found
+ while (x < 255 && (TUint)iHistogram[color][x] < MinBins[color])
+ ++x; // Find from histogram
+
+ MinBins[color] = x; // Save bin index = start of stretching part of LUT
+
+ // Find largest existing values in histograms, discard brightest pixels
+ // according to whitepixels parameter
+ x = 255; // Start from last bin
+ //Compute value to be found
+ MaxBins[color] = iHistogram[color][255] - iParameters.aWhitePixels * iHistogram[color][255]/1000;
+ while (x > 0 && (TUint)iHistogram[color][x] > MaxBins[color])
+ --x; // Find from histogram
+
+ MaxBins[color] = x; // Save bin index = end of stretching part of LUT
+ }
+
+ //Find minimum of all colors
+ minBin=255;
+ for (color=0; color<3; color++)
+ {
+ if (minBin>MinBins[color]) minBin=MinBins[color];
+ }
+
+ //Find maximum of all colors
+ maxBin=0;
+ for (color=0; color<3; color++)
+ {
+ if (maxBin<MaxBins[color]) maxBin=MaxBins[color];
+ }
+
+ //Adjust white and dark balance within limits given in parameters (maximum correction).
+ //0 means that largest(or smallest) of all values is used => no WBC(or DBC).
+ for (color=0; color<3; color++)
+ {
+ if(maxBin-MaxBins[color]>iParameters.aWBC) MaxBins[color]=maxBin-iParameters.aWBC;
+ if((MinBins[color]-minBin) > iParameters.aDBC) MinBins[color]=minBin+iParameters.aDBC;
+ }
+
+ //Step through color components
+ for (color=0; color<3; color++)
+ {
+ // If histogram has only one nonzero bin maxBin can be less than minBin.
+ // In that case change maxBin value to minBin.
+ if(MaxBins[color]<MinBins[color]) MaxBins[color]=MinBins[color];
+
+ // Limit stretching to narrovest histogram that can be stretched
+ if (MaxBins[color]-MinBins[color] < iReducedStretchLimit[color])
+ {
+ // Compute limiting shifts to measured values.
+ // Compute shifts for dark and bright end in relation
+ // to coresponding available space in dynamic range.
+ totalShift = iReducedStretchLimit[color]-(MaxBins[color]-MinBins[color]);
+ maxShift = totalShift*(255-MaxBins[color])/(255-(MaxBins[color]-MinBins[color]));
+ minShift = totalShift*MinBins[color]/(255-(MaxBins[color]-MinBins[color]));
+
+ // Check that dynamic range is not exceeded
+ // (Should happen only with faulty parameter values)
+ if(minShift > MinBins[color])
+ MinBins[color]=0;
+ else
+ // Shift measured values, so that stretching is limited
+ MinBins[color] -= minShift;
+ // Shift measured values, so that stretching is limited
+ MaxBins[color] += maxShift;
+
+ // Check that dynamic range is not exceeded
+ // (Should happen only with faulty parameter values)
+ if (MaxBins[color]>255)
+ MaxBins[color]=255;
+ }
+
+ // Set 0 mapping part of the LUT
+ for (x=0; x<=MinBins[color]; ++x)
+ iMap[color][x] = 0;
+
+ // Set 255 mapping part of the LUT
+ for (x=MaxBins[color]; x<=255; ++x)
+ iMap[color][x] = 255;
+
+ // Compute linear stretching part of the LUT
+ for (x=MinBins[color]+1; x<MaxBins[color]; x++)
+ iMap[color][x] = (TUint8)(255*(x-MinBins[color])/(MaxBins[color]-MinBins[color]));
+ }
+}
+
+
+
+/*
+-----------------------------------------------------------------------------
+
+ CDCIetd
+
+ SetParams
+
+ Set processing parameters
+
+ Return Values: none
+
+-----------------------------------------------------------------------------
+*/
+void CDCIetd::SetParams(DCIetdParameters* params)
+{
+ iParameters = *params;
+}
+
+
+
+
+/*
+-----------------------------------------------------------------------------
+
+ CDCIetd
+
+ GetParams
+
+ Get current processing parameters
+
+ Return Values: none
+
+-----------------------------------------------------------------------------
+*/
+void CDCIetd::GetParams(DCIetdParameters* params)
+{
+ *params = iParameters;
+}
+//----IMAAMI----