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