Resize bmp image size is off

Hello, I am working on a problem for the online course CS50. They give us a program that copies a bmp image and we are to modify it to resize the image.My problem is my image looks perfect but is a few bytes larger than the staffs implementation.They give us a program to compare the headers for the image with the staffs and mine are perfect. Of course the larger the factor to resize by the more mine is bigger than the staffs. I just need a fresh pair of eyes, Thank you very much.


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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
/**
 * 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;

#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 and 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);

	//specs of orginal image 
	int oldWidth = bi.biWidth;
	int oldHeight = bi.biHeight;
    int old_padding = ((4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4);

	//resize image header 
	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)) + padding;

	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);
				}
			}
			//add padding back
			for (int n = 0; n < padding; n++)
			{
				fputc(0x00, outptr);
			}
			//reset file position indicator
			fseek(outptr, -((sizeOfScanline - padding) * (FACTOR -1)), SEEK_CUR);
		}
   }
	// close infile
    fclose(inptr);

    // close outfile
    fclose(outptr);
    return 0;
}
Last edited on
Topic archived. No new replies allowed.