void run(){ //Loop
   uint16_t i;
   for(i=0; i< NEO_COUNT; i++) {
     col->setColor(i, col->Wheel(((i * 256 / NEO_COUNT) + iter) & 255));
   }
   iter++;
   if(iter>256*5) iter=0;
 }
void Kingdoms::Init(void)
{
    const Colors colors(Settings::Get().GetPlayers().GetColors());

    clear();

    for(Colors::const_iterator
	it = colors.begin(); it != colors.end(); ++it)
	GetKingdom(*it).Init(*it);
}
Exemple #3
0
Mesh Mesh::fromMap(const Map &depth, const Map &intensities, bool centralizeLoadedMesh)
{
    if ((depth.w != intensities.w) || (depth.h != intensities.h))
        throw FACELIB_EXCEPTION("incompatibile input map sizes");
    std::map<std::pair<int,int>, int> coordToIndex;

    VectorOfPoints points;
    Colors colors;
    int index = 0;
    for (int y = 0; y < depth.h; y++)
    {
        for (int x = 0; x < depth.w; x++)
        {
            if (depth.isSet(x,y))
            {
                if (!intensities.isSet(x,y)) throw FACELIB_EXCEPTION("intensities point is not valid");

                points.push_back(cv::Point3d(x, depth.h-y-1, depth.get(x,y)));

                uchar intensity = intensities.get(x, y);
                colors.push_back(cv::Vec3b(intensity, intensity, intensity));

                coordToIndex[std::pair<int,int>(x,y)] = index;
                index++;
            }
        }
    }

    Mesh mesh = Mesh::fromPointcloud(points, centralizeLoadedMesh, false);
    mesh.colors = colors;

    // triangles
    for (int y = 0; y < depth.h; y++)
    {
        for (int x = 0; x < depth.w; x++)
        {
            if (depth.isSet(x,y) &&
                depth.isValidCoord(x, y+1) && depth.isSet(x, y+1) &&
                depth.isValidCoord(x+1, y+1) && depth.isSet(x+1, y+1))
            {
                mesh.triangles.push_back(cv::Vec3i(coordToIndex[std::pair<int,int>(x,y)], coordToIndex[std::pair<int,int>(x,y+1)], coordToIndex[std::pair<int,int>(x+1,y+1)]));
            }

            if (depth.isSet(x,y) &&
                depth.isValidCoord(x+1, y+1) && depth.isSet(x+1, y+1) &&
                depth.isValidCoord(x+1, y) && depth.isSet(x+1, y))
            {
                mesh.triangles.push_back(cv::Vec3i(coordToIndex[std::pair<int,int>(x,y)], coordToIndex[std::pair<int,int>(x+1,y+1)], coordToIndex[std::pair<int,int>(x+1,y)]));
            }
        }
    }

    return mesh;
}
    void Redraw(void) const
    {
	for(Colors::const_iterator
    	    it = colors.begin(); it != colors.end(); ++it)
	{
	    const Rect & pos = positions[std::distance(colors.begin(), it)];

	    AGG::GetICN(ICN::CELLWIN, 43 + Color::GetIndex(*it)).Blit(pos);
	    if(recipients & *it)
		AGG::GetICN(ICN::CELLWIN, 2).Blit(pos.x + 2, pos.y + 2);
	}
    }
    SelectRecipientsColors(const Point & pos) :
	colors(Settings::Get().GetPlayers().GetColors() & ~Settings::Get().GetPlayers().current_color), recipients(0)
    {
	positions.reserve(colors.size());

	for(Colors::const_iterator
    	    it = colors.begin(); it != colors.end(); ++it)
	{
    	    const u8 current = std::distance(colors.begin(), it);
	    const Sprite & sprite = AGG::GetICN(ICN::CELLWIN, 43);

    	    positions.push_back(Rect(pos.x + Game::GetStep4Player(current, sprite.w() + 15, colors.size()),
									    pos.y, sprite.w(), sprite.h()));
	}
    }
Exemple #6
0
void Mag::init(){
  if(!mag.begin())
  {
    // There was a problem detecting the LSM303 ... check your connections 
    Serial.println("Ooops, no LSM303 detected ... Check your wiring!");
    
    Colors * color = watch->getColors();
    while(1){
      color->setColors(127, 255,0,0);
      color->pushColors();
      delay(500);
      color->clearColors();
      color->pushColors();
      delay(500);
    }
  }
}
Exemple #7
0
int solve(int num,string filename){
	BMP input,output;
	input.ReadFromFile(filename.c_str());
	int h =input.TellHeight() ,w=input.TellWidth();
	output.SetSize(w,h);
	RangedPixelToPixelCopy(input,0,w-1,h-1,0,output,0,0);
	output.SetBitDepth(input.TellBitDepth());
	Colors colors;
	for(int i=0;i<w;++i){
		for(int j=0;j<h;++j){
			RGBApixel* color = output(i,j);
			colors.addColor(color);
		}
	}
	colors.culculate(num);
	for(int i=0;i<w;++i){
		for(int j=0;j<h;++j){
			RGBApixel* color = output(i,j);
			colors.mapColor(color);
		}
	}
	output.WriteToFile("output.bmp");
}
Exemple #8
0
void loop() {
  if (Serial.available()) {
    String serialData = Serial.readStringUntil('\n');
    Serial.print("Data from searial: "); Serial.println(serialData);
    char colorDelimeter = '|';
    char colorValueDelimeter = ':';
    String rawData = serialData;
    String colorData[COLORS_COUNT];
    int i = 0;
    while (rawData.length()) {
      int colorDelimeterIndex = rawData.indexOf(colorDelimeter);
      if (colorDelimeterIndex >= 0) {
        colorData[i] = rawData.substring(0, colorDelimeterIndex);
        rawData = rawData.substring(colorDelimeterIndex + 1);
      } else {
        colorData[i] = rawData;
        rawData = String("");
      }
      i++;
    }
    for (i = 0; i < COLORS_COUNT; i++) {
      int colorValueDelimeterIndex = colorData[i].indexOf(colorValueDelimeter);
      String ledColor = colorData[i].substring(0, colorValueDelimeterIndex);
      int ledValue = colorData[i].substring(colorValueDelimeterIndex + 1).toInt();
      // Serial.println(ledColor);
      // Serial.println(ledValue);
      if (ledColor == RED_COLOR) {
        RedColor.wantValue(ledValue);
      } else if (ledColor == GREEN_COLOR){
        GreenColor.wantValue(ledValue);
      } else if (ledColor == BLUE_COLOR) {

        BlueColor.wantValue(ledValue);
      }else{
        Serial.println("Unknown color token");
      }
      // =====
      // int ledPin;
      // if (ledColor == RED_COLOR) {
      //   ledPin = redLedPin;
      // } else if (ledColor == GREEN_COLOR){
      //   ledPin = greenLedPin;
      // } else if (ledColor == BLUE_COLOR) {
      //   ledPin = blueLedPin;
      // }else{
      //   Serial.println("Unknown color token");
      // }
      // Serial.print("Color: "); Serial.println(ledColor);
      // setLedValue(ledPin, ledValue);
    }
  }
  RedColor.tick();
  GreenColor.tick();
  BlueColor.tick();
}
Exemple #9
0
int getcolorpair(int fg, int bg)
{
  typedef std::map<std::pair<int, int>, int> Colors;
  static Colors c;

  Colors::const_iterator i;
  if ((i = c.find(std::make_pair(fg, bg))) != c.end())
    return i->second;

  if ((int) c.size() >= COLOR_PAIRS) {
    g_warning(_("Color pairs limit exceeded."));
    return 0;
  }

  if (init_pair(c.size() + 1, fg, bg) == ERR)
    return 0;
  int res = COLOR_PAIR(c.size() + 1);
  c[std::make_pair(fg, bg)] = res;
  return res;
}
Exemple #10
0
int main( void )
{
    
    Setup setup;
    setup.init();
    window = setup.get_window();
    
    board.init_board();
    
    glfwSetKeyCallback(window, keyCalback);
    // Dark blue background
    glClearColor(0.0f, 0.0f, 0.4f, 0.0f);
    
    GLuint VertexArrayID;
    glGenVertexArrays(1, &VertexArrayID);
    glBindVertexArray(VertexArrayID);
    
    
    
    // Create and compile our GLSL program from the shaders
    GLuint programID = LoadShaders( "SimpleVertexShader.vertexshader", "SimpleFragmentShader.fragmentshader" );
    
    GLuint ScaleID = glGetUniformLocation(programID, "scale");
    GLuint MoveXID = glGetUniformLocation(programID, "move_x");
    GLuint MoveYID = glGetUniformLocation(programID, "move_y");
    
    GLuint RedID = glGetUniformLocation(programID, "red");
    GLuint GreenID = glGetUniformLocation(programID, "green");
    GLuint BlueID = glGetUniformLocation(programID, "blue");
    
    draw_board();

    GLuint vertexbuffer;
    glGenBuffers(1, &vertexbuffer);
    
    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*g_vertex_buffer_data.size(), &g_vertex_buffer_data[0], GL_DYNAMIC_DRAW);
    
    /*glBindBuffer(GL_ARRAY_BUFFER, colorbuffer);
    glBufferData(GL_ARRAY_BUFFER, 2000, &g_color_buffer_data[0], GL_STATIC_DRAW);*/

    do{
        
        

        
        
        
        // Clear the screen
        glClear(GL_COLOR_BUFFER_BIT);
        
        // Use our shader
        glUseProgram(programID);
        
        // 1rst attribute buffer : vertices
        glEnableVertexAttribArray(0);
        glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
        glVertexAttribPointer(
                              0,                  // attribute 0. No particular reason for 0, but must match the layout in the shader.
                              2,                  // size
                              GL_FLOAT,           // type
                              GL_FALSE,           // normalized?
                              0,                  // stride
                              (void*)0            // array buffer offset
                              );
        
        
        // Draw the triangle !
        int k =0;
        for (int i = 0; i < 64; i+=4 ){
            Colors colors;
            Card card = board.get_current_board()[k];
            vector<float> color = colors.get_colors(card.get_color());
            
            
            glUniform1f(MoveXID,0.0);
            glUniform1f(MoveYID,0.0);
            if (card.get_status() == HIDDEN){
                glUniform1f(ScaleID,1.0);
                glUniform1f(RedID,0.0);
                glUniform1f(GreenID,0.0);
                glUniform1f(BlueID,0.0);
            } else if (card.get_status() == DISABLED){
                glUniform1f(ScaleID,1.0);
                glUniform1f(RedID,0.0);
                glUniform1f(GreenID,0.0);
                glUniform1f(BlueID,0.4);
            } else {
                glUniform1f(ScaleID,1.0);
                glUniform1f(RedID,color[0]);
                glUniform1f(GreenID, color[1]);
                glUniform1f(BlueID, color[2]);
            }
            k++;
            glDrawArrays(GL_TRIANGLE_STRIP, i, 4);
        }
        // Draw cursor
        
        int tempX = board.get_current_position() % 4;
        int tempY = board.get_current_position() / 4;
        
        glUniform1f(MoveXID, tempX * 0.5);
        glUniform1f(MoveYID, -tempY * 0.5);
        glUniform1f(RedID,1.0);
        glUniform1f(GreenID,1.0);
        glUniform1f(BlueID,0.4);
        glDrawArrays(GL_LINE_STRIP, 64, 5);
        
        for( int i =0 ; i< 16;i++){
            Card &card = board.get_current_board()[i];
            if (card.get_status() == SHOW){
                if (card.get_shape() == TRIANGLE){
                    glUniform1f(MoveXID,0.0);
                    glUniform1f(MoveYID,0.0);
                    glUniform1f(ScaleID,1.0);
                    glUniform1f(RedID,1.0);
                    glUniform1f(GreenID,1.0);
                    glUniform1f(BlueID,0.4);
                    glDrawArrays(GL_TRIANGLE_STRIP, card.get_place(), 3);
                } else if (card.get_shape() == SQUARE){
                    glUniform1f(MoveXID,0.0);
                    glUniform1f(MoveYID,0.0);
                    glUniform1f(ScaleID,1.0);
                    glUniform1f(RedID,1.0);
                    glUniform1f(GreenID,1.0);
                    glUniform1f(BlueID,0.4);
                    glDrawArrays(GL_TRIANGLE_STRIP, card.get_place(), 4);
                }
                else if (card.get_shape() == DIAMOND){
                    glUniform1f(MoveXID,0.0);
                    glUniform1f(MoveYID,0.0);
                    glUniform1f(ScaleID,1.0);
                    glUniform1f(RedID,0.0);
                    glUniform1f(GreenID,1.0);
                    glUniform1f(BlueID,0.4);
                    glDrawArrays(GL_TRIANGLE_STRIP, card.get_place(), 4);
                } else if (card.get_shape() == TRAPEZE){
                    glUniform1f(MoveXID,0.0);
                    glUniform1f(MoveYID,0.0);
                    glUniform1f(ScaleID,1.0);
                    glUniform1f(RedID,0.0);
                    glUniform1f(GreenID,1.0);
                    glUniform1f(BlueID,0.4);
                    glDrawArrays(GL_TRIANGLE_STRIP, card.get_place(), 4);
                }else if (card.get_shape() == PARALLELOGRAM){
                    glUniform1f(MoveXID,0.0);
                    glUniform1f(MoveYID,0.0);
                    glUniform1f(ScaleID,1.0);
                    glUniform1f(RedID,0.0);
                    glUniform1f(GreenID,0.5);
                    glUniform1f(BlueID,1.0);
                    glDrawArrays(GL_TRIANGLE_STRIP, card.get_place(), 4);
                }else if (card.get_shape() == TRIAN_2){
                    glUniform1f(MoveXID,0.0);
                    glUniform1f(MoveYID,0.0);
                    glUniform1f(ScaleID,1.0);
                    glUniform1f(RedID,1.0);
                    glUniform1f(GreenID,1.0);
                    glUniform1f(BlueID,0.4);
                    glDrawArrays(GL_TRIANGLE_STRIP, card.get_place(), 4);
                }else if (card.get_shape() == DIAMOND_2){
                    glUniform1f(MoveXID,0.0);
                    glUniform1f(MoveYID,0.0);
                    glUniform1f(ScaleID,1.0);
                    glUniform1f(RedID,0.0);
                    glUniform1f(GreenID,1.0);
                    glUniform1f(BlueID,0.4);
                    glDrawArrays(GL_TRIANGLE_STRIP, card.get_place(), 4);
                }else if (card.get_shape() == DIAMOND_3){
                    glUniform1f(MoveXID,0.0);
                    glUniform1f(MoveYID,0.0);
                    glUniform1f(ScaleID,1.0);
                    glUniform1f(RedID,0.0);
                    glUniform1f(GreenID,1.0);
                    glUniform1f(BlueID,0.4);
                    glDrawArrays(GL_TRIANGLE_STRIP, card.get_place(), 4);
                }
                
            }
        }
        
        glDisableVertexAttribArray(0);
        
        // Swap buffers
        glfwSwapBuffers(window);
        glfwPollEvents();
        
        
        
        
    } // Check if the ESC key was pressed or the window was closed
    while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS &&
          glfwWindowShouldClose(window) == 0 );
    
    // Cleanup VBO
    glDeleteBuffers(1, &vertexbuffer);
    glDeleteVertexArrays(1, &VertexArrayID);
    glDeleteProgram(programID);
    
    // Close OpenGL window and terminate GLFW
    glfwTerminate();
    
    return 0;
}
//---------------------------------------------------------------------------------------
void IdfyTonalityCtrol::on_settings_changed()
{
    // The settings have been changed. Reconfigure answer keyboard for the new settings

    Colors* pColors = m_appScope.get_colors();

    //set buttons
    int iB = 0;
    if (m_pConstrains->UseMajorMinorButtons())
    {
        //Only major / minor buttons
        m_pAnswerButton[iB]->set_label( to_std_string(_("Major")) );
        m_pAnswerButton[iB]->set_visible(true);
        //m_pAnswerButton[iB]->enable(true);
        set_button_color(iB, pColors->Normal());
        iB++;
        m_pAnswerButton[iB]->set_label( to_std_string(_("Minor")) );
        m_pAnswerButton[iB]->set_visible(true);
        //m_pAnswerButton[iB]->enable(true);
        set_button_color(iB, pColors->Normal());
        iB++;
    }

    else
    {
        EKeySignature nKeys[] = {
            k_key_C, k_key_Cs, k_key_c, k_key_cs, k_key_Cf,
            k_key_D, k_key_Df, k_key_d, k_key_ds, k_key_undefined,
            k_key_E, k_key_Ef, k_key_e, k_key_ef, k_key_undefined,
            k_key_F, k_key_Fs, k_key_f, k_key_fs, k_key_undefined,
            k_key_G, k_key_Gf, k_key_g, k_key_gs, k_key_undefined,
            k_key_A, k_key_Af, k_key_a, k_key_as, k_key_af,
            k_key_B, k_key_Bf, k_key_b, k_key_bf, k_key_undefined,
        };

        //use a button for each enabled key signature
        iB=0;
        for (unsigned i = 0; i < sizeof(nKeys)/sizeof(EKeySignature); i++, iB++)
        {
            EKeySignature nKey = nKeys[i];
            if (nKey != k_key_undefined)
            {
                m_pAnswerButton[iB]->set_label(
                                            to_std_string(get_key_signature_name(nKey)) );
            }
            m_nRealKey[iB] = nKey;
            m_pAnswerButton[iB]->set_visible(nKey != k_key_undefined);
//            bool fEnable = m_pConstrains->IsValidKey(nKey);
//            m_pAnswerButton[iB]->enable(fEnable);
//            set_button_color(iB, fEnable ? pColors->Normal() : Color(255,255,255));
        }
    }

    //hide all other buttons
    while (iB < k_num_buttons)
    {
        m_pAnswerButton[iB]->set_visible(false);
        m_pAnswerButton[iB]->enable(false);
        iB++;
    }

    m_pDoc->set_dirty();

//    if (m_pConstrains->is_theory_mode())
//        new_problem();
//    else
//        m_pProblemScore = NULL;
}
Exemple #12
0
Mesh Mesh::fromABS(const std::string &filename, const std::string &texture, bool centralizeLoadedMesh)
{
    cv::Mat_<cv::Vec3b> image;
    if (!texture.empty())
        image = cv::imread(texture);

    std::ifstream in(filename);
    if (!in.is_open())
        throw FACELIB_EXCEPTION("can't open file " + filename);

    std::string line;

    int mapHeight;
    in >> mapHeight;
    std::getline(in, line);

    int mapwidth;
    in >> mapwidth;    
    std::getline(in, line);

    std::getline(in, line);
    int total = mapwidth*mapHeight;
    std::vector<int> flags(total);
    std::vector<double> xPoints(total);
    std::vector<double> yPoints(total);
    std::vector<double> zPoints(total);

    for (int i = 0; i < total; i++)
        in >> (flags[i]);
    for (int i = 0; i < total; i++)
        in >> (xPoints[i]);
    for (int i = 0; i < total; i++)
        in >> (yPoints[i]);
    for (int i = 0; i < total; i++)
        in >> (zPoints[i]);

    VectorOfPoints points;
    Colors colors;
    for (int i = 0; i < total; i++)
    {
        if (flags[i])
        {
            cv::Point3d p;
            p.x = xPoints[i];
            p.y = yPoints[i];
            p.z = zPoints[i];
            points.push_back(p);

            if (!texture.empty())
            {
                int x = i % 640;
                int y = i / 640;
                colors.push_back(image(y, x));
            }
        }
    }

    Mesh mesh = Mesh::fromPointcloud(points, centralizeLoadedMesh);
    mesh.colors = colors;
    return mesh;
}
Exemple #13
0
int main( int argc, char ** argv )

{
    /* Check that we are running against at least GDAL 1.4 (probably older in fact !) */
    /* Note to developers : if we use newer API, please change the requirement */
    if (atoi(GDALVersionInfo("VERSION_NUM")) < 1400)
    {
        fprintf(stderr, "At least, GDAL >= 1.4.0 is required for this version of %s, "
                "which was compiled against GDAL %s\n", argv[0], GDAL_RELEASE_NAME);
        exit(1);
    }

/* -------------------------------------------------------------------- */
/*      Generic arg processing.                                         */
/* -------------------------------------------------------------------- */
    GDALAllRegister();
    GDALSetCacheMax( 100000000 );
    argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 );
    if( argc < 1 )
        exit( -argc );
    
/* -------------------------------------------------------------------- */
/*      Parse arguments.                                                */
/* -------------------------------------------------------------------- */
    int i;
    const char *pszOutFile = NULL;
    const char *pszInFile = NULL;
    int nMaxNonBlack = 2;
    int nNearDist = 15;
    int bNearWhite = FALSE;
    int bSetAlpha = FALSE;
    int bSetMask = FALSE;
    const char* pszDriverName = "HFA";
    int bFormatExplicitelySet = FALSE;
    char** papszCreationOptions = NULL;
    int bQuiet = FALSE;

    Colors oColors;
    
    for( i = 1; i < argc; i++ )
    {
        if( EQUAL(argv[i], "--utility_version") )
        {
            printf("%s was compiled against GDAL %s and is running against GDAL %s\n",
                   argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME"));
            return 0;
        }
        else if( EQUAL(argv[i], "-o") && i < argc-1 )
            pszOutFile = argv[++i];
        else if( EQUAL(argv[i], "-of") && i < argc-1 )
        {
            pszDriverName = argv[++i];
            bFormatExplicitelySet = TRUE;
        }
        else if( EQUAL(argv[i], "-white") ) {
            bNearWhite = TRUE;
        }

        /***** -color c1,c2,c3...cn *****/
        
        else if( EQUAL(argv[i], "-color") && i < argc-1 ) {
            Color oColor;
            
            /***** tokenize the arg on , *****/
            
            char **papszTokens;
            papszTokens = CSLTokenizeString2( argv[++i], ",", 0 );

            /***** loop over the tokens *****/
            
            int iToken;
            for( iToken = 0; papszTokens && papszTokens[iToken]; iToken++ )
            {

                /***** ensure the token is an int and add it to the color *****/
                
                if ( IsInt( papszTokens[iToken] ) )
                    oColor.push_back( atoi( papszTokens[iToken] ) );
                else {
                    CPLError(CE_Failure, CPLE_AppDefined,
                             "Colors must be valid integers." );
                    CSLDestroy( papszTokens );
                    exit(1);
                }
            }
            
            CSLDestroy( papszTokens );

            /***** check if the number of bands is consistant *****/

            if ( oColors.size() > 0 &&
                 oColors.front().size() != oColor.size() )
            {
                CPLError(CE_Failure, CPLE_AppDefined,
                         "ERROR: all -color args must have the same number of values.\n" );
                exit(1);
            }

            /***** add the color to the colors *****/
            
            oColors.push_back( oColor );
            
        }
        
        else if( EQUAL(argv[i], "-nb") && i < argc-1 )
            nMaxNonBlack = atoi(argv[++i]);
        else if( EQUAL(argv[i], "-near") && i < argc-1 )
            nNearDist = atoi(argv[++i]);
        else if( EQUAL(argv[i], "-setalpha") )
            bSetAlpha = TRUE;
        else if( EQUAL(argv[i], "-setmask") )
            bSetMask = TRUE;
        else if( EQUAL(argv[i], "-q") || EQUAL(argv[i], "-quiet") )
            bQuiet = TRUE;
        else if( EQUAL(argv[i], "-co") && i < argc-1 )
            papszCreationOptions = CSLAddString(papszCreationOptions, argv[++i]);
        else if( argv[i][0] == '-' )
            Usage();
        else if( pszInFile == NULL )
            pszInFile = argv[i];
        else
            Usage();
    }

    if( pszInFile == NULL )
        Usage();

    if( pszOutFile == NULL )
        pszOutFile = pszInFile;

/* -------------------------------------------------------------------- */
/*      Open input file.                                                */
/* -------------------------------------------------------------------- */
    GDALDatasetH hInDS, hOutDS = NULL;
    int nXSize, nYSize, nBands;

    if( pszOutFile == pszInFile )
        hInDS = hOutDS = GDALOpen( pszInFile, GA_Update );
    else
        hInDS = GDALOpen( pszInFile, GA_ReadOnly );

    if( hInDS == NULL )
        exit( 1 );

    nXSize = GDALGetRasterXSize( hInDS );
    nYSize = GDALGetRasterYSize( hInDS );
    nBands = GDALGetRasterCount( hInDS );
    int nDstBands = nBands;

    if( hOutDS != NULL && papszCreationOptions != NULL)
    {
        CPLError(CE_Warning, CPLE_AppDefined,
                  "Warning: creation options are ignored when writing to an existing file.");
    }

/* -------------------------------------------------------------------- */
/*      Do we need to create output file?                               */
/* -------------------------------------------------------------------- */
    if( hOutDS == NULL )
    {
        GDALDriverH hDriver = GDALGetDriverByName( pszDriverName );
        if (hDriver == NULL)
            exit(1);

        if (!bQuiet && !bFormatExplicitelySet)
            CheckExtensionConsistency(pszOutFile, pszDriverName);

        if (bSetAlpha)
        {
            /***** fixme there should be a way to preserve alpha band data not in the collar *****/
            if (nBands == 4)
                nBands --;
            else
                nDstBands ++;
        }

        if (bSetMask)
        {
            if (nBands == 4)
                nDstBands = nBands = 3;
        }

        hOutDS = GDALCreate( hDriver, pszOutFile, 
                             nXSize, nYSize, nDstBands, GDT_Byte, 
                             papszCreationOptions );
        if( hOutDS == NULL )
            exit( 1 );

        double adfGeoTransform[6];

        if( GDALGetGeoTransform( hInDS, adfGeoTransform ) == CE_None )
        {
            GDALSetGeoTransform( hOutDS, adfGeoTransform );
            GDALSetProjection( hOutDS, GDALGetProjectionRef( hInDS ) );
        }
    }
    else
    {
        if (bSetAlpha)
        {
            if (nBands != 4 &&
                (nBands < 2 ||
                 GDALGetRasterColorInterpretation(GDALGetRasterBand(hOutDS, nBands)) != GCI_AlphaBand))
            {
                CPLError(CE_Failure, CPLE_AppDefined,
                        "Last band is not an alpha band.");
                exit(1);
            }

            nBands --;
        }

        if (bSetMask)
        {
            if (nBands == 4)
                nDstBands = nBands = 3;
        }
    }

    /***** set a color if there are no colors set? *****/

    if ( oColors.size() == 0) {
        Color oColor;

        /***** loop over the bands to get the right number of values *****/

        int iBand;
        for (iBand = 0; iBand < nBands ; iBand++) {

            /***** black or white? *****/

            if (bNearWhite) 
                oColor.push_back(255);
            else
                oColor.push_back(0);
        }

        /***** add the color to the colors *****/

        oColors.push_back(oColor);
            
    }

    /***** does the number of bands match the number of color values? *****/

    if ( (int)oColors.front().size() != nBands ) {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "-color args must have the same number of values as the non alpha input band count.\n" );
        exit(1); 
    }

    /***** check the input and output datasets are the same size *****/
    
    if (GDALGetRasterXSize(hOutDS) != nXSize ||
        GDALGetRasterYSize(hOutDS) != nYSize)
    {
        CPLError(CE_Failure, CPLE_AppDefined,
                 "The dimensions of the output dataset don't match "
                 "the dimensions of the input dataset.");
        exit(1);
    }


    int iBand;
    for( iBand = 0; iBand < nBands; iBand++ )
    {
        GDALRasterBandH hBand = GDALGetRasterBand(hInDS, iBand+1);
        if (GDALGetRasterDataType(hBand) != GDT_Byte)
        {
            CPLError(CE_Warning, CPLE_AppDefined,
                     "Band %d is not of type GDT_Byte. It can lead to unexpected results.", iBand+1);
        }
        if (GDALGetRasterColorTable(hBand) != NULL)
        {
            CPLError(CE_Warning, CPLE_AppDefined,
                     "Band %d has a color table, which is ignored by nearblack. "
                     "It can lead to unexpected results.", iBand+1);
        }
    }

    GDALRasterBandH hMaskBand = NULL;
    
    if (bSetMask) {

        /***** if there isn't already a mask band on the output file create one *****/
        
        if ( GMF_PER_DATASET != GDALGetMaskFlags( GDALGetRasterBand(hOutDS, 1) ) )
        {

            if ( CE_None != GDALCreateDatasetMaskBand(hOutDS, GMF_PER_DATASET) ) {
                CPLError(CE_Failure, CPLE_AppDefined,
                         "Failed to create mask band on output DS");
                bSetMask = FALSE;
            }
        }

        if (bSetMask) {
            hMaskBand = GDALGetMaskBand(GDALGetRasterBand(hOutDS, 1));
        }
    }

/* -------------------------------------------------------------------- */
/*      Allocate a line buffer.                                         */
/* -------------------------------------------------------------------- */
    GByte *pabyLine;
    GByte *pabyMask=NULL;
    
    int   *panLastLineCounts;

    pabyLine = (GByte *) CPLMalloc(nXSize * nDstBands);
    
    if (bSetMask)
        pabyMask = (GByte *) CPLMalloc(nXSize);
    
    panLastLineCounts = (int *) CPLCalloc(sizeof(int),nXSize);

/* -------------------------------------------------------------------- */
/*      Processing data one line at a time.                             */
/* -------------------------------------------------------------------- */
    int iLine;

    for( iLine = 0; iLine < nYSize; iLine++ )
    {
        CPLErr eErr;

        eErr = GDALDatasetRasterIO( hInDS, GF_Read, 0, iLine, nXSize, 1, 
                                    pabyLine, nXSize, 1, GDT_Byte, 
                                    nBands, NULL, nDstBands, nXSize * nDstBands, 1 );
        if( eErr != CE_None )
            break;
        
        if (bSetAlpha)
        {
            int iCol;
            for(iCol = 0; iCol < nXSize; iCol ++)
            {
                pabyLine[iCol * nDstBands + nDstBands - 1] = 255;
            }
        }
        
        if (bSetMask)
        {
            int iCol;
            for(iCol = 0; iCol < nXSize; iCol ++)
            {
                pabyMask[iCol] = 255;
            }
        }
        
        ProcessLine( pabyLine, pabyMask, 0, nXSize-1, nBands, nDstBands,
                     nNearDist, nMaxNonBlack, bNearWhite, &oColors,
                     panLastLineCounts,
                     TRUE, // bDoHorizontalCheck
                     TRUE, // bDoVerticalCheck
                     FALSE // bBottomUp
                    );
        ProcessLine( pabyLine, pabyMask, nXSize-1, 0, nBands, nDstBands,
                     nNearDist, nMaxNonBlack, bNearWhite, &oColors,
                     panLastLineCounts,
                     TRUE,  // bDoHorizontalCheck
                     FALSE, // bDoVerticalCheck
                     FALSE  // bBottomUp
                    );
        
        eErr = GDALDatasetRasterIO( hOutDS, GF_Write, 0, iLine, nXSize, 1, 
                                    pabyLine, nXSize, 1, GDT_Byte, 
                                    nDstBands, NULL, nDstBands, nXSize * nDstBands, 1 );

        if( eErr != CE_None )
            break;
    
        /***** write out the mask band line *****/

        if (bSetMask) {

            eErr = GDALRasterIO ( hMaskBand, GF_Write, 0, iLine, nXSize, 1,
                                  pabyMask, nXSize, 1, GDT_Byte,
                                  0, 0 );
                             
            if( eErr != CE_None ) {
                CPLError(CE_Warning, CPLE_AppDefined,
                         "ERROR writeing out line to mask band.");
               break;
            }
        }
        
        if (!bQuiet)
            GDALTermProgress( 0.5 * ((iLine+1) / (double) nYSize), NULL, NULL );
    }

/* -------------------------------------------------------------------- */
/*      Now process from the bottom back up                            .*/
/* -------------------------------------------------------------------- */
    memset( panLastLineCounts, 0, sizeof(int) * nXSize);
    
    for( iLine = nYSize-1; iLine >= 0; iLine-- )
    {
        CPLErr eErr;

        eErr = GDALDatasetRasterIO( hOutDS, GF_Read, 0, iLine, nXSize, 1, 
                                    pabyLine, nXSize, 1, GDT_Byte, 
                                    nDstBands, NULL, nDstBands, nXSize * nDstBands, 1 );
        if( eErr != CE_None )
            break;

        /***** read the mask band line back in *****/

        if (bSetMask) {

            eErr = GDALRasterIO ( hMaskBand, GF_Read, 0, iLine, nXSize, 1,
                                  pabyMask, nXSize, 1, GDT_Byte,
                                  0, 0 );
                             
                                
            if( eErr != CE_None )
                break;
        }

        
        ProcessLine( pabyLine, pabyMask, 0, nXSize-1, nBands, nDstBands,
                     nNearDist, nMaxNonBlack, bNearWhite, &oColors,
                     panLastLineCounts,
                     TRUE, // bDoHorizontalCheck
                     TRUE, // bDoVerticalCheck
                     TRUE  // bBottomUp
                   );
        ProcessLine( pabyLine, pabyMask, nXSize-1, 0, nBands, nDstBands,
                     nNearDist, nMaxNonBlack, bNearWhite, &oColors,
                     panLastLineCounts,
                     TRUE,  // bDoHorizontalCheck
                     FALSE, // bDoVerticalCheck
                     TRUE   // bBottomUp
                    );
        
        eErr = GDALDatasetRasterIO( hOutDS, GF_Write, 0, iLine, nXSize, 1, 
                                    pabyLine, nXSize, 1, GDT_Byte, 
                                    nDstBands, NULL, nDstBands, nXSize * nDstBands, 1 );
        if( eErr != CE_None )
            break;

        /***** write out the mask band line *****/

        if (bSetMask) {

            eErr = GDALRasterIO ( hMaskBand, GF_Write, 0, iLine, nXSize, 1,
                                  pabyMask, nXSize, 1, GDT_Byte,
                                  0, 0 );
                             
                                
            if( eErr != CE_None )
                break;
        }

        
        if (!bQuiet)
            GDALTermProgress( 0.5 + 0.5 * (nYSize-iLine) / (double) nYSize, 
                            NULL, NULL );
    }

    CPLFree(pabyLine);
    if (bSetMask)
        CPLFree(pabyMask);
    
    CPLFree( panLastLineCounts );

    GDALClose( hOutDS );
    if( hInDS != hOutDS )
        GDALClose( hInDS );
    GDALDumpOpenDatasets( stderr );
    CSLDestroy( argv );
    CSLDestroy( papszCreationOptions );
    GDALDestroyDriverManager();
    
    return 0;
}