0

For the 2019 version of Resize (more comfortable), my code is able to pass all but the final three tests:

:( resizes 6x6-pixel BMP to 3x3 correctly when f is 0.5 expected exit code 0, not 1 :( resizes 12x12-pixel BMP to 6x6 correctly when f is 0.5 expected exit code 0, not 1 :( resizes 18x18-pixel BMP to 9x9 correctly when f is 0.5 expected exit code 0, not 1

When I try to resize the large.bmp file with a factor of 0.5, it works fine visually, however the final three tests still fail. Anyone solved it successfully?

Here my code:

...

for (int i = 0, length = strlen(argv[1]); i < length; i++) {
    printf("%i\n", argv[1][i]);
    if ((int) argv[1][0] == 46 && i == 0) i++;
    if ((int) argv[1][i] < 48 || (int) argv[1][i] > 57) {
        printf("please input a valid float\n");
        return 1;
    }
}

// Get Float
if (atof(argv[1]) < 0 || atof(argv[1]) > 100) {
    printf("please input a valid float\n");
    return 1;
};

float scale_factor = atof(argv[1]);
printf("%f\n", scale_factor);

// remember filenames
char *infile = argv[2];
char *outfile = argv[3];

// open input file
FILE *inptr = fopen(infile, "r");
if (inptr == NULL)
{
    fprintf(stderr, "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;
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;
}

//############### NEW CODE ############

// ### Old HEADER VALUES ###

int height = bi.biHeight;
int width = bi.biWidth;

int copy_width;
int copy_height;
// Create new variables
copy_width = bi.biWidth * scale_factor;
copy_height = bi.biHeight * scale_factor;

// determine padding for scanlines
int padding = (4 - (width * sizeof(RGBTRIPLE)) % 4) % 4;
int copy_padding = ( 4 - (copy_width * sizeof(RGBTRIPLE)) % 4) % 4;

// Header Changes
bi.biSizeImage = ((sizeof(RGBTRIPLE) * copy_width) + copy_padding) * abs(copy_height);
bf.bfSize = bi.biSizeImage + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

// UPdate bf and bi
bi.biWidth = copy_width;
bi.biHeight = copy_height;
// ###

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

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

// ### Determine width & height factor ###
double width_factor = (double) width / (double) copy_width;
double height_factor = (double) height / (double) copy_height;

// ##########################
int old_scanline = -1;

// temporary storage
RGBTRIPLE triple[width * sizeof(RGBTRIPLE)];

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

    int  x = i * height_factor;


    // Existing scanlines, only when shrinking, i.e. negative width and height factors
    if (old_scanline != x) {

        // Reset position of stream to beginning
        fseek(inptr, sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + (((sizeof(RGBTRIPLE) * width) + padding) * x), SEEK_SET);

        old_scanline = x;

        // read RGB triple from infile
        fread(triple, sizeof(RGBTRIPLE), width, inptr);
    }
    // End of existing scanlines


    // New Scanlines
    for (int j = 0; j < copy_width; j++)
    {

        int y = j * width_factor;
        // write RGB triple to outfile

        fwrite(&triple[y], sizeof(RGBTRIPLE), 1, outptr);
    }


    // then add it back (to demonstrate how)
    for (int l = 0; l < copy_padding; l++)
    {
        fputc(0x00, outptr);
    }

}


// close infile
fclose(inptr);

// close outfile
fclose(outptr);

// success
return 0;

}

Any help is highly appreciated! Thx!

7
  • i'd suggest you don't try to "visually" debug this. You can look at the underlying bytes of the file by right-clicking on the file and choosing "view hexadecimal" as described in the whodunit problem. This will help you track down what bytes you have written to see if they are what you expect.
    – curiouskiwi
    Feb 1 '19 at 23:43
  • Thanks, will give it a try
    – xhilx
    Feb 4 '19 at 9:50
  • Looks like the return code of 1 might be from your test for valid floating point number. I'd reject a factor of 0 as well, not just negative (<= instead of <)
    – Blauelf
    Feb 5 '19 at 19:20
  • @Blauelf thanks, tried that, did not change the outcome, but thanks to you I found out the actual problem!
    – xhilx
    Feb 13 '19 at 10:06
  • Have you tried removing that faulty floating point number test and rejecting anything <=0? Or at least allow a single . at any place in the number.
    – Blauelf
    Feb 13 '19 at 10:10
0

Found the Bug!

Here I was aiming to filter to enable inputs that started with a dot (".") to work as well, however, this prevented inputs like "0.5" from working because in such cases the dot is on the 1st index and not the '0st'

for (int i = 0, length = strlen(argv[1]); i < length; i++) {
    printf("%i\n", argv[1][i]);
    if ((int) argv[1][0] == 46 && i == 0) i++;
    if ((int) argv[1][i] < 48 || (int) argv[1][i] > 57) {
        printf("please input a valid float\n");
        return 1;
    }
}

Solution:

for (int i = 0, length = strlen(argv[1]); i < length; i++) {
    if ((int) argv[1][i] == 46) {
        i++;
    }
    if ((int) argv[1][i] < 48 || (int) argv[1][i] > 57) {
        printf("please input a valid float\n");
        return 2;
    }
}
1
  • Now test that on 1., which is in many cases a valid abbreviation for 1.0 :P (the decimal point for making clear it's intended to be floating point, even though its value is integer)
    – Blauelf
    Feb 13 '19 at 10:15

You must log in to answer this question.

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