0

Thanks for the help it is resizing the picture correctly now I think but my coparison with staff version gives me lots of fails. :

:) resize.c and bmp.h exist
:) resize.c compiles
:( doesn't resize 1x1-pixel BMP when n is 1
   \ expected an exit code of 0, not output of "\n3\n\n3\n\n3\n90"
:( resizes 1x1-pixel BMP to 2x2 correctly when n is 2
   \ expected an exit code of 0, not output of "\n3\n\n2\n\n3\n174"
:( resizes 1x1-pixel BMP to 3x3 correctly when n is 3
   \ expected an exit code of 0, not output of "\n3\n\n1\n\n3\n306"
:( resizes 1x1-pixel BMP to 4x4 correctly when n is 4
   \ expected an exit code of 0, not output of "\n3\n\n0\n\n3\n486"
:( resizes 1x1-pixel BMP to 5x5 correctly when n is 5
   \ expected an exit code of 0, not output of "\n3\n\n3\n\n3\n774"
:( resizes 2x2-pixel BMP to 4x4 correctly when n is 2
   \ expected an exit code of 0, not output of "\n2\n\n0\n\n6\n486"

No idea why :(

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "bmp.h"

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


    // remember filenames
    char* resizeBy = argv[1];
    int counter = 0;
    char* infile = argv[2];
    char* outfile = argv[3];
   // char array[3];
    int d;

    for(int i = 0; resizeBy[i] > 0; i++){

        counter++;
    }
    d = atoi(argv[1]);

    if(d < 0 || d > 100)
    {
        printf("Try 1 - 100\n");
        return 6;
    }

    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");
    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;

    //int 



    fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);
    int oriWidth = bi.biWidth;
    int oriHeight = bi.biHeight;
    bi.biWidth *= d;
    bi.biHeight *= d;
    int padding =  (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

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

    int oPadding = (4 - (oriWidth * sizeof(RGBTRIPLE)) % 4) % 4;
    bf.bfSize = 54 + bi.biSizeImage;


    // 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;
    }

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

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

    // determine padding for scanlines

   printf("\n%d\n", oPadding);
      printf("\n%d\n", padding);
   printf("\n%d\n", oriWidth);
    printf("%d",bf.bfSize);
   // printf("%d", bi.biHeight);


    // iterate over infile's scanlines

    for (int i = 0, oHeight = abs(oriHeight); i < oHeight; i++)
    {


         for(int k = 0; k < d ; k++)
         {
           //get back to the beginning of the file pointer
           fseek(inptr, sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + i *(oriWidth * sizeof(RGBTRIPLE) + oPadding ), SEEK_SET);

            // iterate over pixels in scanline 
            for (int j = 0; j < oriWidth ; j++)
            {
                // temporary storage
                RGBTRIPLE triple;
                // read RGB triple from infile
                fread(&triple, sizeof(RGBTRIPLE), 1, inptr);

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

            }

             for(int t = 0; t < padding ; t++){
                fputc(0x00, outptr); 
            }

        }
         fseek(inptr,padding,SEEK_CUR);




    }

    // close infile
    fclose(inptr);

    // close outfile
    fclose(outptr);


    // that's all folks
    return 0;
}

1 Answer 1

0

There are several problems, most of which come into play when scaling larger than 1. First, when resetting the pointer at the beginning of the loop to process each line, it only accounts for the input file padding once. It should be accounting for padding once per line.

fseek(inptr, sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 
        (i *  (oriWidth * sizeof(RGBTRIPLE)) + oPadding ), SEEK_SET);

Next, the outer for loop is controlled by biHeight. Unfortunately, you are using the biHeight of the output file to control reading the input file. Works fine when d=1, but not for anything else. Did you notice that when d>1, that the output file has too many lines?

Finally, while the padding could be anything, check50 is looking for zeros as padding, not ff. This will cause a fail.

I'll let you figure out how to implement the repairs. At least I beat ChrisG to the punch on this one. ;-D

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

5
  • Thank you a lot for this pointers :) I will be working on improving my code later this evening when I have some more time on hand. I Am going to mark that question as answered sir as now is the time for me to do some more work on this project. If I am really struggling on something in the future I know whare I can go and ask for help now:) Do not know too many programmers (any). Thank you again and I hope I can just about crack it now:) Commented Aug 25, 2016 at 16:00
  • I have updated my code but not much has changed. I am still getting similar results. I mean my smiley resize is same as staffs even when i checked with xxd on both, but whenever padding comes into play it never works and outputs are diffrent. I am keep fighting myself why is that fseek in a wrong position as that is where the reset shall take place in each iteration, right? Sorry if I seem to be a bit of a cupcake but I am really struggling with this pset at the moment (this particular task). Is there anything else to be said to help me understand what is wrong? Commented Aug 25, 2016 at 17:37
  • It is resizing now but I am getting problems while checking it against cs50 check. Problems are enlisted in my question now. Commented Aug 25, 2016 at 18:36
  • Maybe it's because you forgot to remove all of those diagnostic printf statements?
    – Cliff B
    Commented Aug 25, 2016 at 19:05
  • I was thinking of that straight after I had left home in a rush to pick up my wife and than when I came back I had read your suggestion too haha :) Thank you for the answer once again and I am glad it is finally all working and successfully passing the cs50 check as well with all green lights on:) Next step recover :D I am marking this as solved:) Commented Aug 25, 2016 at 20:40

You must log in to answer this question.

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