0

I've checked other similar questions and answers and found some problems(and then fixed up), but(seems like the problems weren't there), I still have the same problem "invalid or unsupported image format".

What I want to do is, store the each pixels of input image file "n" times in an array called "tripleScale" then draw these pixels "n" times in output image file in order to have the primary image "n" times bigger.

I've watched some videos explaining about the resizing algorithm and I don't know where to put the "ftell()" function, and if it's a must in order to have this program run properly.

-

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

// remember scale n 
int scale = atoi(argv[1]);

// tripleScale's array iteration
int count = 0;

// check if n is between 0 and 100
if (scale < 0 || scale > 100)
{
    fprintf(stderr, "The scale n must be in between 0 and 100\n");
    return 1;
}


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

// save original necessary primary data
int oriWidth = bi.biWidth;
int oriHeight = bi.biHeight;

// determine the new biHeight and biWidth with scale n
bi.biWidth = oriWidth * scale;
bi.biHeight = oriHeight * scale;

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

// determine new biSizeImage and biSize with scale n
bi.biSizeImage = (bi.biWidth * sizeof(RGBTRIPLE) + paddingScale) * abs(bi.biHeight);
bi.biSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + bi.biSizeImage;

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

RGBTRIPLE *tripleScale = malloc(sizeof(RGBTRIPLE) * bi.biWidth);

// iterate over infile's scanlines
for (int i = 0, biHeight = abs(oriHeight); i < biHeight; i++)
{
    // reset the counter(index) to start at 0 for each row
    count=0;

    // 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 array scale times (n times)
        for(int px = 0; px < scale; px++){
            tripleScale[count] = triple;
            count++;
        }

    }

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


    //repeat scale times (n times) for vertical rows
    for(int row=0; row<scale; row++){
        // write RGB triple to outfile
        fwrite(tripleScale, sizeof(RGBTRIPLE), bi.biWidth, outptr);

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

    }

}

// free the allocated memory with malloc
// free(tripleScale);

// close infile
fclose(inptr);

// close outfile
fclose(outptr);

// success
return 0;

}

1 Answer 1

1

Perhaps you should very carefully review the header fields that you are changing. Many have quite similar names, even the same name in both bi and bf headers.

You should also use the peek tool to examine headers in both the input and output file. If you can't open the output file with peek, then you should use the xxd tool to look at the raw data.

Also, make sure you are using n=1 to test the headers until you get them right. That way, the input and output files should be identical.

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

2
  • REALLY THANK YOU. Commented Apr 10, 2017 at 5:47
  • Now I feel really stupid for having mistaken bf.bfSize for bi.biSize. Thank's a lot Cliff B :D You've really saved me XD Commented Apr 10, 2017 at 5:49

You must log in to answer this question.

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