Adding padding in bmp image.

Hello, everyone I am working on pset4 in the CS50 online coarse. The goal is to resize a bmp image. I have it working except adding the padding back to new resized image. The image I am using uses 3 bites of padding. If the factor I resize the image by works out to have 3 bites of padding it works perfect and if the image has no padding it works perfectly I need a fresh pair of eyes. I am not sure how to add the images so here is the address to download the images and the skelton of the source code they gave to modify. Thanks. 'wget http://cdn.cs50.net/2014/fall/psets/4/pset4/pset4.zip' The image that requires the padding is labled as small.bmp.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/**
 * bmp.h
 *
 * Computer Science 50
 * Problem Set 5
 *
 * BMP-related data types based on Microsoft's own.
 */

#include <stdint.h>

/**
 * Common Data Types 
 *
 * The data types in this section are essentially aliases for C/C++ 
 * primitive data types.
 *
 * Adapted from http://msdn.microsoft.com/en-us/library/cc230309.aspx.
 * See http://en.wikipedia.org/wiki/Stdint.h for more on stdint.h.
 */
typedef uint8_t  BYTE;
typedef uint32_t DWORD;
typedef int32_t  LONG;
typedef uint16_t WORD;

/**
 * BITMAPFILEHEADER
 *
 * The BITMAPFILEHEADER structure contains information about the type, size,
 * and layout of a file that contains a DIB [device-independent bitmap].
 *
 * Adapted from http://msdn.microsoft.com/en-us/library/dd183374(VS.85).aspx.
 */
typedef struct 
{ 
    WORD   bfType; 
    DWORD  bfSize; 
    WORD   bfReserved1; 
    WORD   bfReserved2; 
    DWORD  bfOffBits; 
} __attribute__((__packed__)) 
BITMAPFILEHEADER; 

/**
 * BITMAPINFOHEADER
 *
 * The BITMAPINFOHEADER structure contains information about the 
 * dimensions and color format of a DIB [device-independent bitmap].
 *
 * Adapted from http://msdn.microsoft.com/en-us/library/dd183376(VS.85).aspx.
 */
typedef struct
{
    DWORD  biSize; 
    LONG   biWidth; 
    LONG   biHeight; 
    WORD   biPlanes; 
    WORD   biBitCount; 
    DWORD  biCompression; 
    DWORD  biSizeImage; 
    LONG   biXPelsPerMeter; 
    LONG   biYPelsPerMeter; 
    DWORD  biClrUsed; 
    DWORD  biClrImportant; 
} __attribute__((__packed__))
BITMAPINFOHEADER; 

/**
 * RGBTRIPLE
 *
 * This structure describes a color consisting of relative intensities of
 * red, green, and blue.
 *
 * Adapted from http://msdn.microsoft.com/en-us/library/aa922590.aspx.
 */
typedef struct
{
    BYTE  rgbtBlue;
    BYTE  rgbtGreen;
    BYTE  rgbtRed;
} __attribute__((__packed__))
RGBTRIPLE;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include <stdio.h>
#include <stdlib.h>

#include "bmp.h"

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

    //factor to resize by
    const int FACTOR = atoi(argv[1]);

	if (FACTOR < 1 || FACTOR > 100)
	{
		printf("Factor must be between 1 annd 100\n");
		return 2;
	}
	
    // remember filenames
    char* infile = argv[2];
    char* outfile = argv[3];

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

	//old width 
	int oldWidth = bi.biWidth;
	int oldHeight = bi.biHeight;

	//resize image header <--- This is correct
	bi.biWidth *= FACTOR;
	bi.biHeight *= FACTOR;

	//buffer to store old scanline in
	RGBTRIPLE scanline[oldWidth];
	
	// determine padding for scanlines
    int padding = ((4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4);
	
	// size of new scanline
	int sizeOfScanline = (bi.biWidth * sizeof(RGBTRIPLE));

	bi.biSizeImage = sizeOfScanline * (abs(bi.biHeight));
	bf.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 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 5;
    }

	// 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
    for (int i = 0, height = abs(oldHeight); i < height; i++)
    {
        // iterate over pixels in scanline
		for (int j = 0; j < oldWidth; j++)
        {
            // read RGB triple from infile
            fread(&scanline[j], sizeof(RGBTRIPLE), 1, inptr);
		}

		fseek(inptr, padding, SEEK_CUR);

		//write FACTOR number of scanlines
		for (int s = 0; s < FACTOR; s++) 
		{
			//write a scanline
			for (int l = 0; l < bi.biWidth; l++)
			{ 
				//write a pixel
				for (int m = 0; m < FACTOR; m++)
				{
					// write RGB triple to outfile
					fwrite(&scanline[l], sizeof(RGBTRIPLE), 1, outptr);
				}
			}
			//padding
			for (int n = 0; n < padding; n++)
			{
				fputc(0x00, outptr);
			}
			//reset file position indicator  WHY ??
			fseek(outptr, -(sizeOfScanline * (FACTOR -1)), SEEK_CUR);
		}
   }

	// close infile
    fclose(inptr);

    // close outfile
    fclose(outptr);

    return 0;
}
You are using the same 'padding' variable for both input and output files. You will need different values for each, since the padding may change with the new width.
I figured it out the fseek line should have been for the padding of the orginal image not the resized image I will post the code in case it will help someone in the future.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#include <stdio.h>
#include <stdlib.h>

#include "bmp.h"

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

    //factor to resize by
    const int FACTOR = atoi(argv[1]);

	if (FACTOR < 1 || FACTOR > 100)
	{
		printf("Factor must be between 1 annd 100\n");
		return 2;
	}
	
    // remember filenames
    char* infile = argv[2];
    char* outfile = argv[3];

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

	//old width 
	int oldWidth = bi.biWidth;
	int oldHeight = bi.biHeight;
    int old_padding = ((4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4);

	//resize image header <--- This is correct
	bi.biWidth *= FACTOR;
	bi.biHeight *= FACTOR;

	//buffer to store old scanline in
	RGBTRIPLE scanline[oldWidth];
	
	// determine padding for scanlines
    int padding = ((4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4);
	
	// size of new scanline
	int sizeOfScanline = (bi.biWidth * sizeof(RGBTRIPLE));

	bi.biSizeImage = sizeOfScanline * (abs(bi.biHeight));
	bf.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + 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 5;
    }

	// 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
    for (int i = 0, height = abs(oldHeight); i < height; i++)
    {
        // iterate over pixels in scanline
		for (int j = 0; j < oldWidth; j++)
        {
            // read RGB triple from infile
            fread(&scanline[j], sizeof(RGBTRIPLE), 1, inptr);
		}

		fseek(inptr, old_padding, SEEK_CUR);

		//write FACTOR number of scanlines
		for (int s = 0; s < FACTOR; s++) 
		{
			//write a scanline
			for (int l = 0; l < bi.biWidth; l++)
			{ 
				//write a pixel
				for (int m = 0; m < FACTOR; m++)
				{
					// write RGB triple to outfile
					fwrite(&scanline[l], sizeof(RGBTRIPLE), 1, outptr);
				}
			}
			//padding
			for (int n = 0; n < padding; n++)
			{
				fputc(0x00, outptr);
			}
			//reset file position indicator  WHY ??
			fseek(outptr, -(sizeOfScanline * (FACTOR -1)), SEEK_CUR);
		}
   }

	// close infile
    fclose(inptr);

    // close outfile
    fclose(outptr);

    return 0;
}
Topic archived. No new replies allowed.