1

So this should be a little complex of questions.

1. I want to ask if my small.bmp file looks normal:

I looked at it with the command "xxd -c 12 -g 3 -s 54 small.bmp" and the output was the same as in the pset4 description but shouldn't there be a third additional green pixel column and a third green pixel row forming a green box around the white pixel? Even the box on the top right says something is wrong with the width and height.

Here is te peek:

enter image description here

So the width in peek is 3 pixels and the height is... near infinity?? Every other relevant value is right (Or are they?) only those two confuse me because of the unlogic display of small.bmp and its width and height value in peek-mode.

2. How do I read the rgb values of each pixel from the ready outfile?

So for my second question I have my resize program ready to go. I have compiled and run itand when the input file is small.bmp I get a bmp file that looks like this:

enter image description here

The factor here is irrelevant because i get the same output everytime. I think thats because small.bmp is damaged/corrupted but I'm not very sure and thats why those two question are asked together here.

To scan the black pixles in the output and of cours for the sake of practice I have written code in the resize program just before fclose(inptr); and fclose(outptr); :

#include <stdio.h>
#include <stdlib.h>
#include <cs50.h>
#include <unistd.h>

#include "bmp.h"

int main(int argc, char* argv[])
{
    // ensure proper usage
    if (argc != 4)
    {
        printf("Usage: ./res n infile outfile\n");
        return 1;
    }

// remember filenames
int n = atoi(argv[1]);
char* infile = argv[2];
char* outfile = argv[3];

// open input file 
FILE* inptr = fopen(infile, "r");
if (inptr == NULL)
{
    printf("Could not open %s.\n", infile);
    return 2;
}

// open output file
FILE* outptr = fopen(outfile, "w"); //CHANGED "w" TO "w+"
if (outptr == NULL)
{
    fclose(inptr);
    fprintf(stderr, "Could not create %s.\n", outfile);
    return 3;
}



// read infile's BITMAPFILEHEADER
BITMAPFILEHEADER bf;
fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);

// read infile's BITMAPINFOHEADER
BITMAPINFOHEADER bi;
fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);

// ensure infile is (likely) a 24-bit uncompressed BMP 4.0
if (bf.bfType != 0x4d42 || bf.bfOffBits != 54 || bi.biSize != 40 || 
    bi.biBitCount != 24 || bi.biCompression != 0)
{
    fclose(outptr);
    fclose(inptr);
    fprintf(stderr, "Unsupported file format.\n");
    return 4;
}

//ORIGINAL VALS
int orWidth = bi.biWidth;
int orHeight = bi.biHeight;
int orPadding =  (4 - (orWidth * sizeof(RGBTRIPLE)) % 4) % 4;


//NEW VALS
bi.biWidth = bi.biWidth * n;    
bi.biHeight = bi.biHeight * n;
int padding = (4 - ((bi.biWidth * sizeof(RGBTRIPLE)) % 4)) % 4;
printf("Padding new: %i\n\n", padding);
bi.biSizeImage = (bi.biWidth * abs(bi.biHeight) * 3) + (abs(bi.biHeight * 3) * padding);
bf.bfSize = 54 + bi.biSizeImage;

// write outfile's BITMAPFILEHEADER
fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);

// write outfile's BITMAPINFOHEADER
fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr);

// iterate over infile's scanlines
for (int i = 0, biHeight = abs(orHeight); i < biHeight; i++){

    //prints out current original row n times
    for(int ay = 0; ay < n; ay++){

        // iterate over pixels in scanline
        for (int j = 0; j < orWidth; j++){

            // temporary storage
            RGBTRIPLE triple;

            // read RGB triple from infile
            fread(&triple, sizeof(RGBTRIPLE), 1, inptr);

                printf("---\nR: %i\nG: %i\nB: %i\n", triple.rgbtRed, triple.rgbtGreen, triple.rgbtBlue);        



            //prints the current pixel n times

            for(int ax = 0; ax < n; ax++){

                // write RGB triple to outfile
                fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);    
            }

        }


        for (int k = 0; k < padding; k++){

            fputc(0x00, outptr);
        }
        //inputfile cursor resets to the beginning of the line (original width -> original place of the cursor at the beginning)
        fseek(inptr, (-1 * orWidth * sizeof(RGBTRIPLE)), SEEK_CUR);
    }
    fseek(inptr, sizeof(RGBTRIPLE) * (orWidth + orPadding), SEEK_CUR);
}















//HERE IS MY IMPLEMENTED CODE

fseek(outptr, sizeof(54), SEEK_SET);

for(int r = 0; r < bi.biHeight; r++){

    for(int c = 0; c < bi.biWidth; c++){

        RGBTRIPLE triplet;

        fread(&triplet, sizeof(RGBTRIPLE), 1, outptr);

        printf("|R:%iG:%iB:%i|", triplet.rgbtRed, triplet.rgbtGreen, triplet.rgbtBlue);
    }

    printf("\n");
}


// close infile
fclose(inptr);

// close outfile
fclose(outptr);

// that's all folks
return 0;
}

In the line where outptr is being opened with FILE* outptr = fopen(outfile, "w"); I changed the "w" to "w+", but the program doesnt prints the values or anything. Where am I wrong? I can't figure it out.

I hope that both of my questions are plausible and that this combined "Question" will not be deleted because it is to long or because of the fact that those are two seperate questions. (I'm a stack nooby so please bear with me)

Thank you in advance for your answers! :)

  • small.bmp looks right, it isn't corrupted. Also, fffffffd != infinity, it's hex for 4294,967,293. – ronga Aug 25 '16 at 3:40
0

I like to cut to the chase. Your code, posted above, has two issues. One problem is a miscalculated field in the headers:

bi.biSizeImage = (bi.biWidth * abs(bi.biHeight) * 3) + (abs(bi.biHeight * 3) * padding);

The biHeight field is the number of lines in the image. There's no need to convert from pixels to bytes. I'll let you figure out how this impacts the calculation, but you still have to get the header right before working on the image.

Next, another miscalculation:

fseek(inptr, sizeof(RGBTRIPLE) * (orWidth + orPadding), SEEK_CUR);

The orWidth variable is measured in pixels. Padding is measured in bytes. Do you think you can multiply both by the size of a pixel?

As for reading the pixel data, xxd is your friend.

If this answers your question, please click on the check mark to accept. Let's keep up on forum maintenance. ;-)

| improve this answer | |

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .