the program below is almost complete. Define void CImage::save(const char* filename) function so that  to create a new image array with the translated and re-ordered components and save it to a new .bmp file. For this task, it will likely be easiest to create a new, blank image array that is initially set to the background color (see CImage::newImage()). Then by processing the Components in appropriate order and copying appropriate pixels into this new image, you can create the appropriate component location and ordering. Think carefully how this can be done and how it can be done “simply” even it requires some “wasted” work.

#include "component.h"
#include "cimage.h"
#include "bmplib.h"
#include <deque>
#include <iomanip>
#include <iostream>
#include <cmath>
// You shouldn't need other #include's - Ask permission before adding

using namespace std;

// TO DO: Complete this function
CImage::CImage(const char* bmp_filename)
{
    //  Note: readRGBBMP dynamically allocates a 3D array
    //    (i.e. array of pointers to pointers (1 per row/height) where each
    //    point to an array of pointers (1 per col/width) where each
    //    point to an array of 3 unsigned char (uint8_t) pixels [R,G,B values])
    
    img_ = nullptr;

    img_ = readRGBBMP(bmp_filename, h_, w_);
    // ================================================
    // TO DO: call readRGBBMP to initialize img_, h_, and w_;

    // Leave this check
    if(img_ == NULL) {
        throw std::logic_error("Could not read input file");
    }

    // Set the background RGB color using the upper-left pixel
    for(int i=0; i < 3; i++) {
        bgColor_[i] = img_[0][0][i];
    }

    // ======== This value should work - do not alter it =======
    // RGB "distance" threshold to continue a BFS from neighboring pixels
    bfsBgrdThresh_ = 60;

    // ================================================
    // TO DO: Initialize the vector of vectors of labels to -1
    vector<int> row(w_ , -1);
    labels_.resize(h_, row);

    // ================================================
    // TO DO: Initialize any other data members

}

// TO DO: Complete this function
CImage::~CImage()
{
    for (int i=0; i < h_;i++){
        if (img_[i] != nullptr){
            for (int j=0; j < w_;j++){
                delete[] img_[i][j];
            }
            delete [] img_[i];
        }
    }
    delete [] img_;
    img_ = nullptr;
}

// Complete - Do not alter
bool CImage::isCloseToBground(uint8_t p1[3], double within) {
    // Computes "RGB" (3D Cartesian distance)
    double dist = sqrt( pow(p1[0]-bgColor_[0],2) +
                        pow(p1[1]-bgColor_[1],2) +
                        pow(p1[2]-bgColor_[2],2) );
    return dist <= within;
}

// TO DO: Complete this function
size_t CImage::findComponents()
{
  size_t count = 0;

  for (int i=0; i < h_; i++){
    for (int j=0; j < w_;j++){
      if (!isCloseToBground(img_[i][j], bfsBgrdThresh_) && labels_[i][j] == -1){
          Component newcomp = bfsComponent(i, j, count);
          components_.push_back(newcomp);
          count++;
      }
    }
  }
  return count;
}

// Complete - Do not alter
void CImage::printComponents() const
{
    cout << "Height and width of image: " << h_ << "," << w_ << endl;
    cout << setw(4) << "Ord" << setw(4) << "Lbl" << setw(6) << "ULRow" << setw(6) << "ULCol" << setw(4) << "Ht." << setw(4) << "Wi." << endl;
    for(size_t i = 0; i < components_.size(); i++) {
        const Component& c = components_[i];
        cout << setw(4) << i << setw(4) << c.label << setw(6) << c.ulNew.row << setw(6) << c.ulNew.col
             << setw(4) << c.height << setw(4) << c.width << endl;
    }
}


// TODO: Complete this function
int CImage::getComponentIndex(int mylabel) const
{
  for (size_t i=0; i< components_.size();i++){
    if (components_[i].label == mylabel){
      return i;
    }
  }
  return 0;
}


// Nearly complete - TO DO:
//   Add checks to ensure the new location still keeps
//   the entire component in the legal image boundaries
void CImage::translate(int mylabel, int nr, int nc)
{
    // Get the index of specified component
    int cid = getComponentIndex(mylabel);
    if(cid < 0) {
        return;
    }
    int h = components_[cid].height;
    int w = components_[cid].width;

    // ==========================================================
    // ADD CODE TO CHECK IF THE COMPONENT WILL STILL BE IN BOUNDS
    // IF NOT:  JUST RETURN.

    if (h < 0 || h >= h_ || w < 0 || w >= w_){
      return;
    }

    // ==========================================================

    // If we reach here we assume the component will still be in bounds
    // so we update its location.
    Location nl(nr, nc);
    components_[cid].ulNew = nl;
}

// TO DO: Complete this function
void CImage::forward(int mylabel, int delta)
{
    int cid = getComponentIndex(mylabel);
    if(cid < 0 || delta <= 0) {
        return;
    }
    
    int finalindex = max(0,(cid-delta));
    while (cid > finalindex){
      swap(components_[cid], components_[cid-1]);
      cid--;
    }
}

// TO DO: Complete this function
void CImage::backward(int mylabel, int delta)
{
    int cid = getComponentIndex(mylabel);
    if(cid < 0 || delta <= 0) {
        return;
    }
    
    int finalindex = min(static_cast<int>(numComponents()) - 1, (cid + delta));
    while(cid < finalindex){
    swap(components_[cid], components_[cid+1]);
    cid++;
  }
}

// TODO: complete this function
void CImage::save(const char* filename)
{
    //



    writeRGBBMP(filename, out, h_, w_);
  
}

// Complete - Do not alter - Creates a blank image with the background color
uint8_t*** CImage::newImage(uint8_t bground[3]) const
{
    uint8_t*** img = new uint8_t**[h_];
    for(int r=0; r < h_; r++) {
        img[r] = new uint8_t*[w_];
        for(int c = 0; c < w_; c++) {
            img[r][c] = new uint8_t[3];
            img[r][c][0] = bground[0];
            img[r][c][1] = bground[1];
            img[r][c][2] = bground[2];
        }
    }
    return img;
}

// To be completed
void CImage::deallocateImage(uint8_t*** img) const
{
    for (int i=0; i < h_;i++){
        for (int j=0; j < w_; j++){
                delete[] img[i][j];
            }
            delete [] img[i];
        
    }
    delete [] img;
    img = nullptr;
}

// TODO: Complete the following function or delete this if
//       you do not wish to use it.
Component CImage::bfsComponent(int pr, int pc, int mylabel)
{
    // Arrays to help produce neighbors easily in a loop
    // by encoding the **change** to the current location.
    // Goes in order N, NW, W, SW, S, SE, E, NE
    int neighbor_row[8] = {-1, -1, 0, 1, 1, 1, 0, -1};
    int neighbor_col[8] = {0, -1, -1, -1, 0, 1, 1, 1};

    deque<Location> curr;
    curr.push_back(Location(pr,pc));

    int minrow = pr, maxrow = pr, mincol = pc, maxcol = pc;
    labels_[pr][pc] = mylabel;

    while (! curr.empty()){ 
      Location current = curr.front(); // extract item in front of q
      curr.pop_front();

      int x = current.row;
      int y = current.col;

      //update bounding box
      minrow = min(minrow, x);
      maxrow = max(maxrow, x);
      mincol = min(mincol, y);
      maxcol = max(maxcol, y);

      for (int i=0; i<8;i++){
        // loc of neighbors
        int nx = x + neighbor_row[i];
        int ny = y + neighbor_col[i];
        if (nx >= 0 && nx < h_ && ny >= 0 && ny < w_){ //check if valid
          if (!isCloseToBground(img_[nx][ny], bfsBgrdThresh_) && labels_[nx][ny] == -1){
            labels_[nx][ny] = mylabel;
            curr.push_back(Location(nx,ny));
          }
        }
      }
    }

    int height = maxrow - minrow + 1;
    int width = maxcol - mincol +1;
    Component component(Location(minrow,mincol), height, width, mylabel);
    return component;
}

// Complete - Debugging function to save a new image
void CImage::labelToRGB(const char* filename)
{
    //multiple ways to do this -- this is one way
    vector<uint8_t[3]> colors(components_.size());
    for(unsigned int i=0; i<components_.size(); i++) {
        colors[i][0] = rand() % 256;
        colors[i][1] = rand() % 256;
        colors[i][2] = rand() % 256;
    }

    for(int i=0; i<h_; i++) {
        for(int j=0; j<w_; j++) {
            int mylabel = labels_[i][j];
            if(mylabel >= 0) {
                img_[i][j][0] =  colors[mylabel][0];
                img_[i][j][1] =  colors[mylabel][1];
                img_[i][j][2] =  colors[mylabel][2];
            } else {
                img_[i][j][0] = 0;
                img_[i][j][1] = 0;
                img_[i][j][2] = 0;
            }
        }
    }
    writeRGBBMP(filename, img_, h_, w_);
}

// Complete - Do not alter
const Component& CImage::getComponent(size_t i) const
{
    if(i >= components_.size()) {
        throw std::out_of_range("Index to getComponent is out of range");
    }
    return components_[i];
}

// Complete - Do not alter
size_t CImage::numComponents() const
{
    return components_.size();
}

// Complete - Do not alter
void CImage::drawBoundingBoxesAndSave(const char* filename)
{
    for(size_t i=0; i < components_.size(); i++){
        Location ul = components_[i].ulOrig;
        int h = components_[i].height;
        int w = components_[i].width;
        for(int i = ul.row; i < ul.row + h; i++){
            for(int k = 0; k < 3; k++){
                img_[i][ul.col][k] = 255-bgColor_[k];
                img_[i][ul.col+w-1][k] = 255-bgColor_[k];

            }
            // cout << "bb " << i << " " << ul.col << " and " << i << " " << ul.col+w-1 << endl; 
        }
        for(int j = ul.col; j < ul.col + w ; j++){
            for(int k = 0; k < 3; k++){
                img_[ul.row][j][k] = 255-bgColor_[k];
                img_[ul.row+h-1][j][k] = 255-bgColor_[k];

            }
            // cout << "bb2 " << ul.row << " " << j << " and " << ul.row+h-1 << " " << j << endl; 
        }
    }
    writeRGBBMP(filename, img_, h_, w_);
}