0
#include <stdio.h>
#include <stdlib.h>
#include <cs50.h>
#include "bmp.h"

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

    //atoi converts string  ex "6" to 6
    int n  = atoi(argv[1]);
    char *infile = argv[2];
    char *outfile = argv[3];

    //n  is a positive integer less than or equal to 100
    if( (n >  100) && (n <= 0) )
    {
        fprintf(stderr, "(n) must be a positive integer less than or equal to 100");
        return 2;
    }
    // open input file
    FILE *inptr = fopen(infile, "r");
    if (inptr == NULL)
    {
        fprintf(stderr, "Could not open %s.\n", infile);
        return 3;
    }

    // open output file
    FILE *outptr = fopen(outfile, "w");
    if (outptr == NULL)
    {
        fclose(inptr);
        fprintf(stderr, "Could not create %s.\n", outfile);
        return 4;
    }
    // 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;
    }

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

    //new headerfile BITMAPINFOHEADER

    //new  bi.biWidth and new bi.biHeight
    bi.biWidth =  bi.biWidth * n;
    bi.biHeight = bi.biHeight * n;

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

    //new bi.biSizeImage
    bi.biSizeImage = ((sizeof(RGBTRIPLE) * bi.biWidth) + new_padding) * abs(bi.biHeight);



    //new headerfiles and new BITMAPINFOHEADER

    //new bf.bfsize
     bf.bfSize = bi.biSizeImage + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

    // 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 createes height
        for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
        {
            // iterate over pixels in scanline creates width
            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        nth time triples
                fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
            }
        }


        // skip over padding, if any
        fseek(inptr, new_padding, SEEK_CUR);
        // then add it back (to demonstrate how)
        for (int k = 0; k <  new_padding; k++)
        {
            fputc(0x00, outptr);
        }


    // close infile
    fclose(inptr);

    // close outfile
    fclose(outptr);

    // success
    return 0;
}

For pset4 I don't know what is wrong. I am pretty sure my headerfiles are correct. If they wrong inform me.

I can't see anything wrong with my for loops.

Lets say I have the input of 2 Rgbtriples

input :

Rgbtriple: Rgbtriple:

  for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++)
    {
        // iterate over pixels in scanline creates width
        for (int j = 0; j < bi.biWidth; j++)
        {

        }

Assume n = 3.

bi.biHeight = 1 * 3 = 3. This will create a height of 3. So i = 0-2.

bi.biWidth = 2 * 3 = 6. This will create width of 6 or 6 Rgbtriples. So i = 0-2.

The reason I didn't add bi.biHeight * n and bi.biWidth * n is because they are already modified because of the new headers.

output:

Height: 0: Rgbtriple :Rgbtriple: Rgbtriple Rgbtriple: Rgbtriple 5:Rgbtriple: 0x00 0x00

Height:0: Rgbtriple Rgbtriple: Rgbtriple Rgbtriple: Rgbtriple 5:Rgbtriple: 0x00 0x00

Height: 0: Rgbtriple Rgbtriple: Rgbtriple Rgbtriple: Rgbtriple 5:Rgbtriple: 0x00 0x00

I am not really sure why fseek is needed. The padding should be correct in the code.

1 Answer 1

0

There are a number of issues to deal with. In no particular order, the padding for both the input file and the output file need to be calculated. There is no guarantee that they are the same. In fact, there's about a 3 in 4 chance that they aren't.

The code simply copies a triple or pixel from the input file to the output file. It doesn't do anything to replicate it for the horizontal scaling.

Finally, there's nothing in the code that deals with vertical scaling.

fseek is your friend for moving around the input file as needed.

Time to review all the shorts and other class material.

BTW, why don't you know if your headers are right? Have you used the peek or xxd tools to look at them? Have you compared the output file headers to the input file headers to each other when the scale is 1, or against the output from the staff sample when the scale is larger?

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

You must log in to answer this question.

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