mmserv/thumbnailengine/ImaamiSrc/DCIetd.cpp
changeset 0 71ca22bcf22a
equal deleted inserted replaced
-1:000000000000 0:71ca22bcf22a
       
     1 /*
       
     2 * Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:   
       
    15 *	CDCIETD 
       
    16 *		Display specific color contrast enhancement, 
       
    17 *		Image Enhancement for Transflective Displays version 2,
       
    18 *		IETD 2.
       
    19 *
       
    20 */
       
    21 
       
    22 
       
    23 
       
    24 //  Include Files  
       
    25 #include <e32std.h>	// The basic definitions
       
    26 #include <fbs.h>	// For FBS bitmap
       
    27 #include "DCIetd.h"	// The DCIetd class
       
    28 
       
    29 
       
    30 //  MEMBER FUNCTIONS
       
    31 //=============================================================================
       
    32 
       
    33 
       
    34 
       
    35 
       
    36 /*
       
    37 -----------------------------------------------------------------------------
       
    38 
       
    39   CDCIetd
       
    40   
       
    41   Constructor
       
    42 	
       
    43   Default constructor, initializes member variables to initial values
       
    44 	  
       
    45   Return Values:  none
       
    46 		
       
    47 -----------------------------------------------------------------------------
       
    48 */
       
    49 CDCIetd::CDCIetd()
       
    50 {
       
    51 	// Set default values for parameters (from init file)
       
    52 	iParameters.aWhitePixels = WhitePixels;
       
    53 	iParameters.aBlackPixels = BlackPixels;
       
    54 	iParameters.aStretchLimit = StretchLimit;
       
    55 	iParameters.aSaturationGain = SaturationGain;
       
    56 	iParameters.aBitLimit = BitLimit;
       
    57 	iParameters.aWBC = WBC;
       
    58 	iParameters.aDBC = DBC;
       
    59 }
       
    60 
       
    61 
       
    62 
       
    63 
       
    64 /*
       
    65 -----------------------------------------------------------------------------
       
    66 
       
    67   CDCIetd
       
    68   
       
    69   NewLC
       
    70 	
       
    71   Factory function to instantiate the class.
       
    72   This function leaves the class pointer to the cleanup stack
       
    73   May leave with KErrNoMemory if no memory available
       
    74   
       
    75   Return Values:  CDCIetd* self:  pointer to the class instance
       
    76 
       
    77 -----------------------------------------------------------------------------
       
    78 */
       
    79 CDCIetd* CDCIetd::NewLC()
       
    80 {
       
    81     CDCIetd* self = new (ELeave) CDCIetd();
       
    82     CleanupStack::PushL(self);
       
    83     self->ConstructL();
       
    84     return self;
       
    85 }
       
    86 
       
    87 
       
    88 
       
    89 
       
    90 /*
       
    91 -----------------------------------------------------------------------------
       
    92 
       
    93   CDCIetd
       
    94   
       
    95   NewL
       
    96 	
       
    97   Factory function to instantiate the class.
       
    98   May leave with KErrNoMemory if no memory available
       
    99 	  
       
   100   Return Values:  CDCIetd* self:  pointer to the class instance
       
   101 	
       
   102 -----------------------------------------------------------------------------
       
   103 */
       
   104 CDCIetd* CDCIetd::NewL()
       
   105 {
       
   106     CDCIetd* self = CDCIetd::NewLC();
       
   107     CleanupStack::Pop();
       
   108     return self;
       
   109 }
       
   110 
       
   111 
       
   112 
       
   113 
       
   114 /*
       
   115 -----------------------------------------------------------------------------
       
   116 
       
   117   CDCIetd
       
   118   
       
   119   ConstructL
       
   120 	
       
   121   Second phase constructor. Does nothing at the moment
       
   122 	  
       
   123   Return Values:  none
       
   124 		
       
   125  -----------------------------------------------------------------------------
       
   126 */
       
   127 void CDCIetd::ConstructL()
       
   128 {
       
   129     // This function is intentionally left blank.
       
   130 }
       
   131 
       
   132 
       
   133 
       
   134 
       
   135 /*
       
   136 -----------------------------------------------------------------------------
       
   137 
       
   138   CDCIetd
       
   139   
       
   140   Destructor
       
   141 	
       
   142   Return Values:  none
       
   143 		
       
   144 -----------------------------------------------------------------------------
       
   145 */
       
   146 CDCIetd::~CDCIetd()
       
   147 {
       
   148     // This function is intentionally left blank.
       
   149 }
       
   150 
       
   151 
       
   152 
       
   153 
       
   154 /*
       
   155 -----------------------------------------------------------------------------
       
   156 
       
   157   CDCIetd
       
   158   
       
   159   Analyze
       
   160 	
       
   161   Analyze image referenced by aBPtr 
       
   162 	  
       
   163   Return Values:  none
       
   164 		
       
   165 -----------------------------------------------------------------------------
       
   166 */
       
   167 // Analyze image referenced by aBPtr
       
   168 void CDCIetd::Analyze(CFbsBitmap& aBPtr)
       
   169 {
       
   170 
       
   171 	//EColor16M image is needed
       
   172 	if (aBPtr.DisplayMode() != EColor16M) return;
       
   173 	
       
   174 	//Do analysis
       
   175 	GatherHistograms(aBPtr);
       
   176 	MakeMappings();
       
   177 }
       
   178 
       
   179 
       
   180 
       
   181 
       
   182 /*
       
   183 -----------------------------------------------------------------------------
       
   184 
       
   185   CDCIetd
       
   186   
       
   187   ProcessL
       
   188 	
       
   189   Process image referenced by aImage (modify aImage).
       
   190   May leave with KErrNoMemory if no memory available
       
   191 	  
       
   192   Return Values:  none
       
   193 		
       
   194 -----------------------------------------------------------------------------
       
   195 */
       
   196 void CDCIetd::ProcessL (CFbsBitmap& aImage)  // image reference
       
   197 {
       
   198 	TUint	r, g, b;	// Color components
       
   199 	TUint	lum;		// Brightness estimate
       
   200 	TInt	dr, dg, db;	// Differences to brightness
       
   201 	TUint8*	dataPtr;	// Pointer to data
       
   202 	
       
   203 	//EColor16M image is needed
       
   204 	if (aImage.DisplayMode() != EColor16M) return;
       
   205 	
       
   206 	//Line Buffer and pointer to the data
       
   207 	TUint imageWidth = aImage.SizeInPixels().iWidth;
       
   208 	TUint scanLineLengthInBytes = aImage.ScanLineLength(imageWidth, aImage.DisplayMode());
       
   209 
       
   210 	//Allocate buffer for scanline
       
   211 	iScanLineBuffer = HBufC8::NewMaxL(scanLineLengthInBytes);
       
   212 	//Pointer to scanline
       
   213 	TPtr8 linePtr = iScanLineBuffer->Des();
       
   214 	
       
   215 	//Step through image pixels and do stretching
       
   216 	//and saturation increase
       
   217 	//---------------------------------------------
       
   218 
       
   219 	//Read all lines
       
   220 	for (TInt lineNo=0; lineNo<aImage.SizeInPixels().iHeight; ++lineNo)
       
   221 	{
       
   222 		//Get line
       
   223 		aImage.GetScanLine(linePtr, TPoint(0, lineNo), imageWidth, aImage.DisplayMode());
       
   224 		//CHECK! CONST_CAST not used in every algorithm which way is better?
       
   225 		dataPtr = CONST_CAST(TUint8*, linePtr.Ptr());
       
   226 	
       
   227 		//Step through pixels in line
       
   228 		for (TUint x=0; x < imageWidth; ++x)
       
   229 		{
       
   230 			// Map color componets according to mapping LUTs
       
   231 			b = iMap[2][*dataPtr++];
       
   232 			g = iMap[1][*dataPtr++];
       
   233 			r = iMap[0][*dataPtr++];
       
   234 			
       
   235 			//Compute brightness estimate
       
   236 			//lum=0.299r+0.587g+0.114b; //true Y
       
   237 			//lum=(32768+19595*r+38470*g+7471*b)>>16; //Y
       
   238 			//lum = (r+g+b)/3; //Simple approximation
       
   239 			lum=(r+(g<<1)+b)>>2; //More effective simple approximation
       
   240 			
       
   241 			//Compute componentwise differences to luminance
       
   242 			dr = r-lum;
       
   243 			dg = g-lum;
       
   244 			db = b-lum;
       
   245 			
       
   246 			//Increase differences => saturation increases.
       
   247 			//Use gain parameter for adjusting the strength of the effect.
       
   248 			b += iParameters.aSaturationGain*db/32;
       
   249 			g += iParameters.aSaturationGain*dg/32;
       
   250 			r += iParameters.aSaturationGain*dr/32;
       
   251 			
       
   252 			//Save data to same image & same pixels
       
   253 			dataPtr -= 3;
       
   254 						
       
   255 			//Limit to available dynamic range [0,255].
       
   256 			*dataPtr++ = Limit255(b);
       
   257 			*dataPtr++ = Limit255(g);
       
   258 			*dataPtr++ = Limit255(r);
       
   259 		}
       
   260 		
       
   261 		//Save line
       
   262 		aImage.SetScanLine(linePtr, lineNo);
       
   263 	}
       
   264 
       
   265 	//Free memory
       
   266 	delete(iScanLineBuffer);
       
   267 	iScanLineBuffer = 0;
       
   268 }
       
   269 
       
   270 
       
   271 
       
   272 
       
   273 /*
       
   274 -----------------------------------------------------------------------------
       
   275 
       
   276   CDCIetd
       
   277   
       
   278   GatherHistograms
       
   279 	
       
   280   Gather histograms and make cumulative histogram.
       
   281 	  
       
   282   Return Values:  none
       
   283 		
       
   284 -----------------------------------------------------------------------------
       
   285 */
       
   286 void CDCIetd::GatherHistograms (const CFbsBitmap& aImage)  // Pointer to the image bitmap
       
   287 {
       
   288 	const TUint8* dataPtr; //Pointer to data
       
   289 	TInt lineNo; //Line number
       
   290 	TUint x;	 //Pixel index	
       
   291 	TUint color; //Color index
       
   292 	TUint count; // Number of colors in each component
       
   293 
       
   294 	//Compute image width & allocate scan line memory
       
   295 	TUint imageWidth = aImage.SizeInPixels().iWidth;
       
   296 	TUint histScanLineLengthInBytes = aImage.ScanLineLength(imageWidth, aImage.DisplayMode());
       
   297 	iScanLineBuffer = HBufC8::NewMaxL(histScanLineLengthInBytes);
       
   298 	
       
   299 	//Pointer to line
       
   300 	TPtr8 linePtr = iScanLineBuffer->Des();
       
   301 
       
   302 	//Clear histograms
       
   303 	Mem::FillZ(iHistogram, sizeof(iHistogram));
       
   304 
       
   305 	// Read all lines and gather histograms
       
   306 	for (lineNo=0; lineNo<aImage.SizeInPixels().iHeight; lineNo++)
       
   307 	{
       
   308 		//Get line
       
   309 		aImage.GetScanLine(linePtr, TPoint(0, lineNo), imageWidth, aImage.DisplayMode());
       
   310 		dataPtr = linePtr.Ptr();
       
   311 
       
   312 		//Step through pixels
       
   313 		for (x=imageWidth; x != 0; --x)
       
   314 		{
       
   315 			++iHistogram[2][*dataPtr++]; // Increase Blue bin value
       
   316 			++iHistogram[1][*dataPtr++]; // Increase Green bin value
       
   317 			++iHistogram[0][*dataPtr++]; // Increase Red bin value
       
   318 		}
       
   319 	}
       
   320 	
       
   321 	//Make cumulative histograms & count colors in each histogram
       
   322 	for (color=0; color<3; ++color)
       
   323 	{
       
   324 		 // Count used colors
       
   325 		count=0;
       
   326 		for (x=0; x<256; ++x)
       
   327 		{
       
   328 			if (iHistogram[color][x]>0) count++;
       
   329 		}
       
   330 		
       
   331 		// Compute increased stretch limit if a color component has less colors than iBitLimit.
       
   332 		// Otherwise use predetermined stretch limit.
       
   333 		if (count<iParameters.aBitLimit)
       
   334 			iReducedStretchLimit[color] = (TUint8)(iParameters.aStretchLimit*count/iParameters.aBitLimit+255-255*count/iParameters.aBitLimit);
       
   335 		else
       
   336 			iReducedStretchLimit[color] = iParameters.aStretchLimit;
       
   337 		
       
   338 		//Make cumulative histogram
       
   339 		for (x=1; x<256; ++x)
       
   340 			iHistogram[color][x] += iHistogram[color][x-1];
       
   341 		
       
   342 	}
       
   343 	
       
   344 	//Free memory
       
   345 	delete(iScanLineBuffer);
       
   346 	iScanLineBuffer = 0;
       
   347 }
       
   348 
       
   349 
       
   350 
       
   351 
       
   352 /*
       
   353 -----------------------------------------------------------------------------
       
   354 
       
   355   CDCIetd
       
   356   
       
   357   MakeMappings
       
   358 	
       
   359   Make mapping function look-up table (LUT).
       
   360 	  
       
   361   Return Values:  none
       
   362 		
       
   363 -----------------------------------------------------------------------------
       
   364 */
       
   365 void CDCIetd::MakeMappings()
       
   366 {
       
   367 	TUint    MinBins[3];// Smallest existing values in histogram
       
   368 	TUint    MaxBins[3];// Largest existing values in histogram
       
   369 	TUint    minBin;    // Minimum of smallest existing values
       
   370 	TUint    maxBin;    // Maximum of largest existing values
       
   371 	TUint    x;         // Index
       
   372 	
       
   373 	// Stretching limit variables
       
   374 	TUint    minShift;
       
   375 	TUint    maxShift;
       
   376 	TUint    totalShift;
       
   377 	
       
   378 	TUint    color; //Color index
       
   379 	
       
   380 	//Step through colors
       
   381 	for (color=0; color<3; ++color)
       
   382 	{
       
   383 		// Find smallest existing values in histograms, discard darkest pixels
       
   384 		// according to blackpixels parameter
       
   385 		x = 0; // Start from fist bin
       
   386 		MinBins[color] = iParameters.aBlackPixels * iHistogram[color][255]/1000; // Compute value to be found
       
   387 		while (x < 255 && (TUint)iHistogram[color][x] < MinBins[color])
       
   388 			++x; // Find from histogram
       
   389 		
       
   390 		MinBins[color] = x; // Save bin index = start of stretching part of LUT
       
   391 		
       
   392 		// Find largest existing values in histograms, discard brightest pixels
       
   393 		// according to whitepixels parameter
       
   394 		x = 255;  // Start from last bin
       
   395 		//Compute value to be found
       
   396 		MaxBins[color] = iHistogram[color][255] - iParameters.aWhitePixels * iHistogram[color][255]/1000;
       
   397 		while (x > 0 && (TUint)iHistogram[color][x] > MaxBins[color])
       
   398 			--x; // Find from histogram
       
   399 		
       
   400 		MaxBins[color] = x; // Save bin index = end of stretching part of LUT
       
   401 	}
       
   402 	
       
   403 	//Find minimum of all colors
       
   404 	minBin=255;
       
   405 	for (color=0; color<3; color++)
       
   406 	{
       
   407 		if (minBin>MinBins[color]) minBin=MinBins[color];
       
   408 	}
       
   409 	
       
   410 	//Find maximum of all colors
       
   411 	maxBin=0;
       
   412 	for (color=0; color<3; color++)
       
   413 	{
       
   414 		if (maxBin<MaxBins[color]) maxBin=MaxBins[color];
       
   415 	}
       
   416 	
       
   417 	//Adjust white and dark balance within limits given in parameters (maximum correction).
       
   418 	//0 means that largest(or smallest) of all values is used => no WBC(or DBC).
       
   419 	for (color=0; color<3; color++)
       
   420 	{
       
   421 		if(maxBin-MaxBins[color]>iParameters.aWBC) MaxBins[color]=maxBin-iParameters.aWBC;
       
   422 		if((MinBins[color]-minBin) > iParameters.aDBC) MinBins[color]=minBin+iParameters.aDBC;
       
   423 	}
       
   424 	
       
   425 	//Step through color components
       
   426 	for (color=0; color<3; color++)
       
   427 	{
       
   428 		// If histogram has only one nonzero bin maxBin can be less than minBin.
       
   429 		// In that case change maxBin value to minBin.
       
   430 		if(MaxBins[color]<MinBins[color]) MaxBins[color]=MinBins[color];
       
   431 		
       
   432 		// Limit stretching to narrovest histogram that can be stretched
       
   433 		if (MaxBins[color]-MinBins[color] < iReducedStretchLimit[color])
       
   434 		{
       
   435 			// Compute limiting shifts to measured values.
       
   436 			// Compute shifts for dark and bright end in relation
       
   437 			// to coresponding available space in dynamic range.
       
   438 			totalShift = iReducedStretchLimit[color]-(MaxBins[color]-MinBins[color]);
       
   439 			maxShift = totalShift*(255-MaxBins[color])/(255-(MaxBins[color]-MinBins[color]));
       
   440 			minShift = totalShift*MinBins[color]/(255-(MaxBins[color]-MinBins[color]));
       
   441 			
       
   442 			// Check that dynamic range is not exceeded
       
   443 			// (Should happen only with faulty parameter values)
       
   444 			if(minShift > MinBins[color])
       
   445 				MinBins[color]=0;
       
   446 			else
       
   447 			// Shift measured values, so that stretching is limited 
       
   448 			MinBins[color] -= minShift;
       
   449 			// Shift measured values, so that stretching is limited 
       
   450 			MaxBins[color] += maxShift;
       
   451 			
       
   452 			// Check that dynamic range is not exceeded
       
   453 			// (Should happen only with faulty parameter values)
       
   454 			if (MaxBins[color]>255)
       
   455 				MaxBins[color]=255;
       
   456 		}
       
   457 		
       
   458 		// Set 0 mapping part of the LUT
       
   459 		for (x=0; x<=MinBins[color]; ++x)
       
   460 			iMap[color][x] = 0;
       
   461 		
       
   462 		// Set 255 mapping part of the LUT
       
   463 		for (x=MaxBins[color]; x<=255; ++x)
       
   464 			iMap[color][x] = 255;
       
   465 		
       
   466 		// Compute linear stretching part of the LUT
       
   467 		for (x=MinBins[color]+1; x<MaxBins[color]; x++)
       
   468 			iMap[color][x] = (TUint8)(255*(x-MinBins[color])/(MaxBins[color]-MinBins[color]));
       
   469 	}
       
   470 }
       
   471 
       
   472 
       
   473 
       
   474 /*
       
   475 -----------------------------------------------------------------------------
       
   476 
       
   477   CDCIetd
       
   478   
       
   479   SetParams
       
   480 	
       
   481   Set processing parameters
       
   482 	  
       
   483   Return Values:  none
       
   484 		
       
   485 -----------------------------------------------------------------------------
       
   486 */
       
   487 void CDCIetd::SetParams(DCIetdParameters* params)
       
   488 {
       
   489 	iParameters = *params;
       
   490 }
       
   491 
       
   492 
       
   493 
       
   494 
       
   495 /*
       
   496 -----------------------------------------------------------------------------
       
   497 
       
   498   CDCIetd
       
   499   
       
   500   GetParams
       
   501 	
       
   502   Get current processing parameters
       
   503 	  
       
   504   Return Values:  none
       
   505 		
       
   506 -----------------------------------------------------------------------------
       
   507 */
       
   508 void CDCIetd::GetParams(DCIetdParameters* params)
       
   509 {
       
   510 	*params = iParameters;
       
   511 }
       
   512 //----IMAAMI----