Hauptseite   Klassenhierarchie   Auflistung der Dateien  

filterfloodfill.cpp

00001 /**********************************************************************************
00002 * Copyright (c) 2003, Christoph Rueegg <opendev@cdrnet.ch> and Matthias Bader     *
00003 * Partially based on ideas of Tim Weyrich <weyrich@inf.ethz.ch>                   *
00004 * and/or the Swiss Federal Institute of Technology http://www.ethz.ch             *
00005 * All rights reserved.                                                            *
00006 *                                                                                 *
00007 * Project Website: http://www.cdrnet.net/projects/painter/                        *
00008 *                                                                                 *
00009 * Redistribution and use in source and binary forms, with or without modification,*
00010 * are permitted provided that the following conditions are met:                   *
00011 *                                                                                 *
00012 * 1. Redistributions of source code must retain the above copyright notice,       *
00013 * this list of conditions and the following disclaimer.                           *
00014 *                                                                                 *
00015 * 2. Redistributions in binary form must reproduce the above copyright notice,    *
00016 * this list of conditions and the following disclaimer in the documentation       *
00017 * and/or other materials provided with the distribution.                          *
00018 *                                                                                 *
00019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"     *
00020 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE       *
00021 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE      *
00022 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE        *
00023 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR             *
00024 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF            *
00025 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS        *
00026 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN         *
00027 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)         *
00028 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF          *
00029 * THE POSSIBILITY OF SUCH DAMAGE.                                                 *
00030 **********************************************************************************/
00031 
00032 #include "filterfloodfill.h"
00033 #include "../container/fixedstack.h"
00034 #include <cmath>
00035 
00036 FloodFillFilter::FloodFillFilter() : ChannelSelectDotFilter(true)
00037 {
00038   already = 0;
00039   tolerance = 25;
00040   fillcolor = 100;
00041   x0 = y0 = 0;
00042 }
00043 
00044 FloodFillFilter::~FloodFillFilter()
00045 {
00046   delete already;
00047 }
00048 
00049 void FloodFillFilter::OnMouseEvent(const int button, const int state, int x, int y)
00050 {       
00051   if(button!=0)
00052   {
00053     ChannelSelectDotFilter::OnMouseEvent(button, state, x, y);
00054   }
00055   ChannelSelectDotFilter::Normalize(&x,&y);
00056   if(state == 0 && button == 0)
00057   {
00058     x0 = x;
00059     y0 = y;
00060   }
00061   if(state == 1 && button == 0)
00062   {
00063     x0 = x-x0;
00064     y0 = y-y0;
00065     x = x-x0;
00066     y = y-y0;
00067     tolerance = (char)(abs(x0*200.0/ChannelSelectDotFilter::GetWidth()));
00068     if(tolerance < 2)
00069       tolerance = 20;
00070     fillcolor = ChannelSelectDotFilter::GetSelectedColor();
00071     unsigned char color = ChannelSelectDotFilter::Get(x,y);
00072     unsigned char low   = tolerance>color ? 0 : color-tolerance;
00073     unsigned char high  = tolerance>(255-color) ? 255 : color+tolerance;
00074     unsigned char currentcolor = 0;
00075     already = new Channel<bool>(ChannelSelectDotFilter::GetHeight(),ChannelSelectDotFilter::GetWidth());
00076     for(int x1=0;x1<already->GetWidth();x1++)
00077       for(int y1=0;y1<already->GetHeight();y1++)
00078         already->Set(x1,y1,false);
00079     FixedStack* stack = new FixedStack(already->GetWidth()*already->GetHeight());
00080     already->Set(x,y,true);
00081     stack->Push(x,y);
00082     while(stack->Pop(&x,&y))
00083     {
00084       currentcolor = ChannelSelectDotFilter::Get(x,y);
00085       if(currentcolor >= low && currentcolor <= high) 
00086       {
00087         ChannelSelectDotFilter::Set(x,y,fillcolor);
00088         if(x>0 && !already->Get(x-1,y))
00089         {
00090           stack->Push(x-1,y);
00091           already->Set(x-1,y,true);
00092         }
00093         if(x<ChannelSelectDotFilter::GetWidth()-1 && !already->Get(x+1,y))
00094         {
00095           stack->Push(x+1,y);
00096           already->Set(x+1,y,true);
00097         }
00098         if(y>0 && !already->Get(x,y-1))
00099         {
00100           stack->Push(x,y-1);
00101           already->Set(x,y-1,true);
00102         }
00103         if(y<ChannelSelectDotFilter::GetHeight()-1 && !already->Get(x,y+1))
00104         {
00105           stack->Push(x,y+1);
00106           already->Set(x,y+1,true);
00107         }
00108         already->Set(x,y,true);
00109       }
00110     }
00111     delete stack;
00112     delete already;
00113     already = 0;
00114   }
00115 }
00116 
00117 ChannelFilter<unsigned char>* FloodFillFilter::EmptyClone()
00118 {
00119   FloodFillFilter *copy = new FloodFillFilter();
00120   copy->SetSubChannel(ChannelSelectDotFilter::GetSubChannel());
00121   return(copy);
00122 }

Erzeugt am Fri Jan 31 15:27:35 2003 für OOP Miniprojekt von doxygen1.3-rc2