0

I'm not quite sure why my program doesn't work correctly. It's been like this for days, so I thought someone with a fresh mind on the issue could be handy. My code is as follows:

    int width = bi.biWidth;
//resizing header vars
bf.bfSize *=n;
bi.biSizeImage *=n;
bi.biWidth*=n;
bi.biHeight *=n;

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

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

// determine padding for scanlines
int padding =  (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
int smallpad =  (4 - (width * sizeof(RGBTRIPLE)) % 4) % 4;

// iterate over infile's scanlines
for (int i = 0, biHeight = abs(bi.biHeight/n); i < biHeight; i++)
{
    //copying a single line on the source file n times;
    for(int x = 0; x<n; x++){


    // iterate over pixels in scanline
    for (int j = 0; j < width; j++)
    {
        // temporary storage
        RGBTRIPLE triple;

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

        // write RGB triple to outfile n times
        for(int y = 0; y<n; y++){
        fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
    }}

    //unless it's the last iteration, return inptr to start of the line
    if(x !=n-1){

    fseek(inptr, -width, SEEK_CUR);
    }
    //add padding on output file
    for (int k = 0; k < padding; k++)
    {
        fputc(0x00, outptr);
    }
    }
    //skip padding to work on the next line of infile
    fseek(inptr, smallpad, SEEK_CUR);
}

I hope my comments made my method quite clear. The output image, however, turns out like this:

The input file was large.bmp. If anyone could spot the issue, I'd be much thankful.

EDIT: Mistakes were pointed on my first sample of code. Ran on another problem when trying to reorganize, now I get invalid file format. Here's the code:

BITMAPFILEHEADER of;

BITMAPINFOHEADER oi;
of.bfType = bf.bfType;
of.bfReserved1 = bf.bfReserved1;
of.bfReserved2 = bf.bfReserved2;
of.bfOffBits = bf.bfOffBits;

oi.biWidth = bi.biWidth *n;
oi.biHeight = bi.biHeight*n;

// determine padding for scanlines
int padding =  (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
int outpad =  (4 - (oi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

oi.biSizeImage =  sizeof((oi.biWidth + outpad)*oi.biHeight);
of.bfSize = (oi.biSizeImage + bf.bfOffBits);
// write outfile's BITMAPFILEHEADER
fwrite(&of, sizeof(BITMAPFILEHEADER), 1, outptr);

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


// iterate over infile's scanlines
for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
{
    //copying a single line on the source file n times;
    for(int x = 0; x<n; x++){


    // iterate over pixels in scanline
    for (int j = 0; j < bi.biWidth; j++)
    {
        // temporary storage
        RGBTRIPLE triple;

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

        // write RGB triple to outfile n times
        for(int y = 0; y<n; y++){
        fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
    }}

    //unless it's the last iteration, return inptr to start of the line
    if(x !=n-1){

    fseek(inptr, -bi.biWidth, SEEK_CUR);
    }
    //add padding on output file
    for (int k = 0; k < padding; k++)
    {
        fputc(0x00, outptr);
    }
    }
    //skip padding to work on the next line of infile
    fseek(inptr, padding, SEEK_CUR);
}

Once again, thank you very much.

1 Answer 1

0

You have a couple of issues with your program. First, some of your header fields are not being calculated correctly. I'll leave it to you to debug - it should be easy enough. A review of the definition of the fields might help you.

Second, look at the following line:

fseek(inptr, -width, SEEK_CUR);

How far are you moving back? What units of measure does fseek use? What units does width measure?

Cryptic hints, but they'll get you where you need to go. ;-)

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

3
  • How silly of me to make such basic mistakes. Anyway, I tried fixing those mistakes. Made some adaptations with it, will edit them on the main post. Now I'm getting invalid format, even though I copied all data of the file header. Sorry for asking this much, but could you have a look at the updated code? Thank you very much for the help so far. Commented Mar 7, 2016 at 22:31
  • That would be because you created the two new header structures without copying all of the data from the old to the new. There are a bunch of fields that you didn't copy. (Google the bitmap specification for BITMAPFILEHEADER AND BITMAPINFOHEADER.) However, there's a simple way to copy complete structures. As long as they're the same type, you can ` STRUCTTYPE struct_b = struct_a;` and then modify any fields in the new struct that you wish. (This was an example, STRUCTTYPE is merely a hypothetical type, not a keyword.)
    – Cliff B
    Commented Mar 7, 2016 at 22:40
  • Sorry for the several of days of delay between responses, but THANK YOU SO MUCH. Took quite some time to realize I should have multiplied biWidth for size of RGBTRIPLE. I didn't quite get what you meant, kept looking for the difference between int and long int :P Thanks a lot, man, off to recover.c! Commented Mar 14, 2016 at 17:26

You must log in to answer this question.

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