0

I just finished writing the code for the resize problem of pset4. When I run my code in the debugger, everything turns out right, but when I run it simply in the terminal, the computer complains about a segmentation fault. Any idea why?

 /**
 * copy.c
 *
 * Computer Science 50
 * Problem Set 4
 *
 * adaptation of copy.c to resize an image by a factor n
 */

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

#include "bmp.h"

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

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

    // 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");
    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;
    }
    //remember original padding
    int orPadding =  (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;


    // make appropriate changes to heander info

    bi.biWidth *= n;
    bi.biHeight *= n;
    // define padding

    int padding =  (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;

    // end changes
    bi.biSizeImage = ((bi.biWidth + padding) * bi.biHeight);
    bf.bfSize = bi.biSizeImage + sizeof(BITMAPINFOHEADER) + sizeof(BITMAPFILEHEADER);


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

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

    // determine padding for scanlines


    // iterate over infile's scanlines
    for (int i = 0, biHeight = abs(bi.biHeight)/n; i < biHeight; i++)
    {
        for (int l = 0; l < n ; l ++)
        {
            // iterate over pixels in scanline
            for (int j = 0; j < bi.biWidth/n; j++)
            {
                // temporary storage
                RGBTRIPLE triple;

                // read RGB triple from infile
                fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
                for(int k = 0 ; k < n ; k++ )
                {
                    // write RGB triple to outfile
                    fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
                }
            }

            // skip over padding, if any
            fseek(inptr,orPadding, SEEK_CUR);

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

            //if not on last, go back at beginning of line
            if (l != (n-1))
            {
                fseek(inptr,-(orPadding+ bi.biWidth/n * sizeof(RGBTRIPLE)), SEEK_CUR);
            }
        }
    }

    // close infile
    fclose(inptr);

    // close outfile
    fclose(outptr);

    // that's all folks
    return 0;
}
2

The problem lies early in your code:

if (argc != 4 || !isdigit(argv[1]))

The isdigit() function is designed to check whether a single character is a digit, not a string. This code is trying to shove a string down it's throat, so it chokes and coughs up a seg fault. You might want to say that it's only getting a single digit, but that's not exactly true. A string of a single digit will also include the end of string marker.

As for the debugger behavior, it's fairly common for seg faults to not happen in the debugger, although other behaviors may happen instead.

Finally, there are a couple more issues remaining in your code, but that's for another question. Happy coding! ;-)

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 .