Search code examples
c++bmp

Aborting when trying to reading and writing bmp files c++


this is my first post in stackoverflow. I write a program that should take a bmp file in input, and black and white it and then write it into the out.bmp. when I started to write the code, i delete the bmp file format at the end of the name of input and then open it with text editor, then write the code, and the output style is like the input. when I type ./a.out <in.bmp>out.bmp in terminal, I get an Abort error (Aborted (core dumped)) and when I give the ./a.out < in > out.bmp gimp say to me it is not a bmp file. here is the code:

// In the Name of God

#include <iostream>
#include <vector>
#include <string>
#include <cstdlib>
#include <algorithm>
#include <math.h>
#include <sstream>

using namespace std;

bool TypeIsTrue (string type){
    if (type == "424d")
        return true;
    return false;
}
int GrayIt (int b , int g , int r){


    return (b + g + r) / 3 ;
}
int ConvertToDec(string hex){
    long int dec = 0;
    reverse(hex.begin(), hex.end());
    for (int i = 0 ; i <hex.size();i++){
        if (hex[i] == 'a')
            dec = dec + 10 *(pow(16,i));
        else if (hex[i] == 'b')
            dec = dec + 11 *(pow(16,i));
        else if (hex[i] == 'c')
            dec = dec + 12 *(pow(16,i));
        else if (hex[i] == 'd')
            dec = dec + 13 *(pow(16,i));
        else if (hex[i] == 'e')
            dec = dec + 14 *(pow(16,i));
        else if (hex[i] == 'f')
            dec = dec + 15 *(pow(16,i));
        else
            dec = dec + ((hex[i] - '0')*(pow(16,i)));
    }
    return dec;
}
string ConvertToHex(int dec){
    string hex;
    int reminded,Divided;
    reminded = dec % 16 ;
    Divided = dec / 16;
    if (Divided == 10){
        hex = "a";
    }
    else if (Divided == 11){
        hex = "b";
    }
    else if (Divided == 12){
        hex = "c";
    }
    else if (Divided == 13){
        hex = "d";
    }
    else if (Divided == 14){
        hex = "e";
    }
    else if (Divided == 15){
        hex = "f";
    }
    else if (Divided == 0){
        hex = "0";
    }
    else if (Divided == 1){
        hex = "1";
    }
    else if (Divided == 2){
        hex = "2";
    }
    else if (Divided == 3){
        hex = "3";
    }
    else if (Divided == 4){
        hex = "4";
    }
    else if (Divided == 5){
        hex = "5";
    }
    else if (Divided == 6){
        hex = "6";
    }
    else if (Divided == 7){
        hex = "7";
    }
    else if (Divided == 8){
        hex = "8";
    }
    else if (Divided == 9){
        hex = "9";
    }
    if (reminded == 10){
        hex = hex+"a";
    }
    else if (reminded == 11){
        hex = hex+"b";
    }
    else if (reminded == 12){
        hex = hex+"c";
    }
    else if (reminded == 13){
        hex = hex+"d";
    }
    else if (reminded == 14){
        hex = hex+"e";
    }
    else if (reminded == 15){
        hex = hex+"f";
    }
    else if (reminded == 0){
        hex = hex+"0";
    }
    else if (reminded == 1){
        hex = hex+"1";
    }
    else if (reminded == 2){
        hex = hex+"2";
    }
    else if (reminded == 3){
        hex = hex+"3";
    }
    else if (reminded == 4){
        hex = hex+"4";
    }
    else if (reminded == 5){
        hex = hex+"5";
    }
    else if (reminded == 6){
        hex = hex+"6";
    }
    else if (reminded == 7){
        hex = hex+"7";
    }
    else if (reminded == 8){
        hex = hex+"8";
    }
    else if (reminded == 9){
        hex = hex+"9";
    }
    return hex;
}
int main (){
    vector <string> a;
    vector <string> r;
    vector <string> g;
    vector <string> b;
    vector <string> out;
    string temp;
    int red,green,blue;
    while(cin >> temp){
        a.push_back (temp);
    }
    if(!TypeIsTrue(a[0])){
        cout<<"The file is not bmp\nRerun program"<<endl;
        abort();
    }   
    int phase = 1;
    for (int i = 27 ; i < a.size(); i++){ //int i = 27

        string first;
        string last;
        first = a[i].substr(0,2);
        last = a[i].substr(2,3);
        if(phase == 4)
            phase = 1;
        if(phase == 1){
            b.push_back(first);
            g.push_back(last);
            phase ++;
            // cout<<"push_backed"<<endl;   
        }
        else if(phase == 2){
            r.push_back(first);
            b.push_back(last);
            phase ++;
            // cout<<"push_backed"<<endl;
        }
        else if(phase == 3){
            g.push_back(first);
            r.push_back(last);
            phase ++;
            // cout<<"push_backed"<<endl;
        }

    }
    for (int i = 0 ; i <27 ; i++){
        out.push_back(a[i]);
    }
    for(int i = 27 ; i<b.size() ; i++){
        blue = ConvertToDec(b[i]);  
        green = ConvertToDec(g[i]);
        red = ConvertToDec(r[i]);
        out.push_back ( ConvertToHex( GrayIt (blue , green , red)));
        out.push_back ( ConvertToHex( GrayIt (blue , green , red)));
        out.push_back ( ConvertToHex( GrayIt (blue , green , red)));
    }
    int j = 1 ;
    for (int i = 0 ; i < 27 ; i++){
        cout<< out[i] << " ";
        if (j == 8){
            cout<<endl;
            j = 0;
        }
        j++;
    } 
    j=1;
    bool space = false;
    for (int i = 27 ; i < out.size(); i++){
        if( i == 27 + 10){
            cout<<endl;
            j = 1;

        }
        cout<<out[i];
        if (space)
            cout<<" ";
        j++;
        if(j == 17){
            cout<<endl;
            j = 1 ;
        }
        space=!space;
    }
    return 0;
}

Solution

  • You're getting an abort error because you asked for one.

    if(!TypeIsTrue(a[0])){
        cout<<"The file is not bmp\nRerun program"<<endl;
        abort();
    }
    

    If your program is designed to have its output redirected, it is very important to send error messages to stderr (and std::cerr or std::clog) and not stdout.

    BTW, the type test is failing because BMP files are not text, it makes no sense to read them using cin >> variable.

    In addition, there's no guarantee that a[0] even exists. You need to test a.size() first.

    if(a.size() < 1 || !TypeIsTrue(a[0])){
        cerr << "The file is not bmp\nRerun program\n";
        abort();
    }