Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

plfiltercontrast.cpp

Go to the documentation of this file.
00001 /*
00002 /--------------------------------------------------------------------
00003 |
00004 |      $Id: plfiltercontrast.cpp,v 1.1 2004/05/21 21:02:53 maxx Exp $
00005 |
00006 |      Copyright (c) 1996-1998 Ulrich von Zadow
00007 |
00008 \--------------------------------------------------------------------
00009 */
00010 
00011 #include "plstdpch.h"
00012 #include "plfiltercontrast.h"
00013 #include "plbitmap.h"
00014 #include "plpaintlibdefs.h"
00015 
00016 PLFilterContrast::PLFilterContrast(double contrast, PLBYTE offset)
00017     : PLFilter(), 
00018     m_contrast(contrast), 
00019     m_offset((double) offset-125.0)
00020 {
00021 }
00022 
00023 PLFilterContrast::~PLFilterContrast()
00024 {
00025 
00026 }
00027 
00028 void PLFilterContrast::Apply(PLBmp * pBmpSource, PLBmp * pBmpDest) const
00029 {
00030   // Consider a coordinate system with two axes: The x axis represents
00031   // an input RGB component or intensity, the y axis an output RGB
00032   // component or intensity. The ranges of input and output values go 
00033   // from 0 - 255. 
00034   // If I take a straight line that intersects (0,0) through (255,255), 
00035   // I have defined a Null filter that leaves the image unchanged. 
00036 
00037   // Next step: Let's rotate this straight line around the point (125,125).
00038   // If I increase the slope, output values above (125,125) are increased 
00039   // by the slope factor, output values below (125, 125) are decreased 
00040   // likewise. This is how I create the contrast enhancement effect.
00041 
00042   // Now we are having a problem: Increasing the slope means that our
00043   // straight line intersects the line (x, 255), creating output values 
00044   // above 255 which are not defined in our RGB model. Since in the RGB world
00045   // there is nothing whiter than white, I'll set all these values to 255. A 
00046   // similar thing happens  on the lower left of our imaginary diagram: All
00047   // values smaller than 0 have to be set 0 - according to the fact that 
00048   // there is nothing darker than absolute darkness...
00049 
00050   // Ok, now what is that offset value good for? Remember the point 
00051   // (125,125). At this position, input and output values of our filter 
00052   // remain unchanged, independent of the slope of our straight line. Now 
00053   // imagine we are shifting our line parallel to the x axis. Our filter 
00054   // works quite differently now: We create a cut-off for the higher output 
00055   // value range (shift right), or the lower ones (shift left).
00056 
00057   register int inc=0;
00058 
00059   double contrast = m_contrast;
00060  
00061   PLASSERT (pBmpSource->GetBitsPerPixel() >= 24);
00062 
00063   pBmpDest->Create (pBmpSource->GetWidth(), 
00064                     pBmpSource->GetHeight(),
00065                     pBmpSource->GetBitsPerPixel(),
00066                     pBmpSource->HasAlpha(),
00067                     pBmpSource->GetResolution());
00068 
00069   PLBYTE ** pSrcLines = pBmpSource->GetLineArray();
00070   PLBYTE ** pDstLines = pBmpDest->GetLineArray();
00071 
00072   register int destWidth = pBmpDest->GetWidth();
00073 
00074   if(pBmpSource->GetBitsPerPixel() == 24)
00075    inc = 3;
00076 
00077   if(pBmpSource->GetBitsPerPixel() == 32)
00078    inc = sizeof(PLPixel32);
00079 
00080   register double red, green, blue;
00081   register double csupp = contrast * (m_offset - 125.0) + 125.0;
00082 
00083   for (int y = 0; y < pBmpDest->GetHeight(); ++y)
00084   { // For each line
00085     register PLBYTE * pSrcPixel = pSrcLines[y];
00086     register PLBYTE * pDstPixel = pDstLines[y];
00087 
00088     for (register int x = 0; x < destWidth; ++x)
00089     {
00090        // Formel für Kontrastberechnung:
00091        // v = (contrast * (v - 125.0 + m_offset) + 125.0);
00092        red   = contrast * ((double) (pSrcPixel[PL_RGBA_RED])) + csupp;
00093        green = contrast * ((double) (pSrcPixel[PL_RGBA_GREEN])) + csupp;
00094        blue  = contrast * ((double) (pSrcPixel[PL_RGBA_BLUE])) + csupp;
00095 
00096        if(red >= 255.0)
00097         pDstPixel[PL_RGBA_RED] = (PLBYTE) 255;
00098        else if (red < 0.0)
00099         pDstPixel[PL_RGBA_RED] = (PLBYTE) 0;
00100        else
00101         pDstPixel[PL_RGBA_RED] = (PLBYTE) red;
00102 
00103        if(green >= 255.0)
00104         pDstPixel[PL_RGBA_GREEN] = (PLBYTE) 255;
00105        else if (green < 0.0)
00106         pDstPixel[PL_RGBA_GREEN] = (PLBYTE) 0;
00107        else
00108         pDstPixel[PL_RGBA_GREEN] = (PLBYTE) green;
00109 
00110        if(blue >= 255.0)
00111         pDstPixel[PL_RGBA_BLUE] = (PLBYTE) 255;
00112        else if (blue < 0.0)
00113         pDstPixel[PL_RGBA_BLUE] = (PLBYTE) 0;
00114        else
00115         pDstPixel[PL_RGBA_BLUE] = (PLBYTE) blue;
00116 
00117        pSrcPixel += inc;
00118        pDstPixel += inc;
00119     }
00120   }
00121 }
00122 
00123 /*
00124 /--------------------------------------------------------------------
00125 |
00126 |      $Log: plfiltercontrast.cpp,v $
00127 |      Revision 1.1  2004/05/21 21:02:53  maxx
00128 |      Initial Version of vuVolume, moderatly changed to make it compile on my windows and linux machine.
00129 |
00130 |      Revision 1.3  2003/01/25 02:54:41  mspindle
00131 |      *** empty log message ***
00132 |
00133 |      Revision 1.2  2003/01/07 16:14:59  sbergner
00134 |      *** empty log message ***
00135 |
00136 |      Revision 1.1  2002/11/13 01:59:47  mspindle
00137 |      *** empty log message ***
00138 |
00139 |      Revision 1.4  2001/10/16 17:12:26  uzadow
00140 |      Added support for resolution information (Luca Piergentili)
00141 |
00142 |      Revision 1.3  2001/10/06 22:03:26  uzadow
00143 |      Added PL prefix to basic data types.
00144 |
00145 |      Revision 1.2  2001/10/06 15:32:22  uzadow
00146 |      Removed types LPBYTE, DWORD, UCHAR, VOID and INT from the code.
00147 |
00148 |      Revision 1.1  2001/09/16 19:03:23  uzadow
00149 |      Added global name prefix PL, changed most filenames.
00150 |
00151 |      Revision 1.5  2001/02/04 14:31:52  uzadow
00152 |      Member initialization list cleanup (Erik Hoffmann).
00153 |
00154 |      Revision 1.4  2001/01/15 15:05:31  uzadow
00155 |      Added PLBmp::ApplyFilter() and PLBmp::CreateFilteredCopy()
00156 |
00157 |      Revision 1.3  2001/01/12 23:30:01  uzadow
00158 |      Doc update.
00159 |
00160 |      Revision 1.2  2000/12/18 22:42:53  uzadow
00161 |      Replaced RGBAPIXEL with PLPixel32.
00162 |
00163 |      Revision 1.1  2000/11/06 23:20:22  uzadow
00164 |      Added Contrast, Intensity and Lightness filters by
00165 |      Thomas Hirschmann
00166 |
00167 |
00168 \--------------------------------------------------------------------
00169 */

Generated on Wed Dec 15 21:20:30 2004 for vuVolume by  doxygen 1.3.9.1