The immediate problem lies with your header structures. You have created bi_new and modified two of it's fields, but you forgot to copy the contents of bi to bi_new, so all of the unmodified fields contain garbage data. This is why you're getting the unsupported image error. FYI, whole structures can be copied at once simply by a=b; so that you don't have ...
That is because biHeight in this case is a negative number, and the representation in binary is made by the two's complement in this case, this can be a bit confusing but you can take a look at the link if you are interested.
As example the number -3, the one you are expecting, represented as a signed 32-bit integer in binary is:
11111111 11111111 11111111 ...
If you take a look in bmp.h, which is included as a header file to copy.c, you'll see a definition for structures named RGBTRIPLE:
So a triple has 3 variables in it of type BYTE. BYTE is defined in the header of the same bmp.h:
Your BMP needs to be 24 bits BMP image. I never used Paintbrush and Seashore, but try to find more options as you export your BMP in them.
If you cannot manage to do that, you may use a tool like GIMP. Here are the steps
From the File menu choose New.
Specify the width and the height and click OK.
From the File menu choose Export As.
From the menu near the ...
Row size is a DWORD ie 32 bits/4 bytes. So a the 24 bit pixels must be padded to fit. See also this answer in Stack Overflow...
"Because 24 bits is an odd number of bytes (3) and for a variety of reasons all the image rows are required to start at an address which is a multiple of 4 bytes."
The height of the bitmap, in pixels. If biHeight is positive, the bitmap is a bottom-up DIB and its origin is the lower-left corner. If biHeight is negative, the bitmap is a top-down DIB and its origin is the upper-left corner.
The value fffffffd (hex) is 1111 1111 1111 1111 1111 1111 1111 1101 (bin). The two's complement for that ...
Given that padding cannot be read by fread
Who says the padding can't be read by fread? Of course it can and that's the main reason you need to skip it — in order to make fread read the first pixel of the next scanline rather than the padding.
Your padding calculation is fine (I believe). I think the problem lies on the "logic". Once you've completed scanning the first line, you force the file cursor to skip the infile padding:
for (int j = 0; j < bi.biWidth; j++)
// read RGB triple from infile
// write RGB triple to outfile w/ magnification
// skip over ...
There are several problems in the code, but the biggest is this:
//GO BACK TO BEGINNING OF SCANLINE
fseek(inptr, (i * bi.biWidth), SEEK_SET);
The third parameter is the starting point and the second parameter is the offset. SEEK_SET is the beginning of the file, so starting at the beginning of the file, you are saying to move to i * bi....
The problem lies early in your code:
if (argc != 4 || !isdigit(argv))
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. ...
The missing part of Dr.Queso's response is this. A pixel is made of 3 parts - one red, one green and one blue. Each of these is represented by a number that determines it's intensity. The range for each color part of a pixel runs from 0 to 255, with 0 being the absence of that color and 255 being the maximum. Of course, that's in base 10. In hexadecimal, ...
Two issues I think I see are:
1) You change the value of BiWidth to BiWidth = BiWidth * scale (and same for BiHeight) for use in changing the header values but then you use those updated values in the loop. So if have a 3X3 scaling to a 6X6 you have it iterating over each pixel 6 times and then writing each pixel out twice (the scale) so you are writing out ...
You may have the file, but it isn't in the same directory as your source code file and/or the directory where you are executing your make command. You must be in the same directory on the command line as both the resize.c file and the bmp.h file. If either file is in a different directory, the compile will fail.
Given all of your previous questions and the ...
Have you watched the "Walkthrough" videos yet? It looks like there's only one video, but there are actually several (just kind of hidden because they will play one after another, and you can select which one with a playlist to the top right corner of the video screen). Watching the video on the grayscale implementation helped a lot, and I was actually able ...
Actually, no, the code doesn't work correctly at all.
First, the header data is incorrect. Two fields are not calculated correctly.
Second, even at resize of 1, the image output is incorrect. small.bmp is the correct output, s2.bmp is the output from your code above. Note the second line in each file.
00000036: 00ff00 00ff00 00ff00 000000 .......
The problems revolve around how the pointer is moved at the end of each line in the input file and how padding is added to the output file. There are two issues.
First, the output file padding. It works for n=1 because the padding sizes are identical. The problem here is that the code is writing the input padding to the output file.
Next, when handling ...
It's not needed for a padding of 1, 2, or 3 bytes.
But imagine what happened if bi.biWidth were a multiple of 4.
bi.biWidth * sizeof(RGBTRIPLE) would be a multiple of 4.
(bi.biWidth * sizeof(RGBTRIPLE)) % 4 would be 0.
4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4 would be 4, but should be 0. You'd fix that by applying another %4.
You change bi.biWidth and bi.biHeight to new scale using
bi.biWidth = bi.biWidth * enlarge;
bi.biHeight = bi.biHeight * enlarge;
and then use code that relies on the values to represent the input file
for (int i = 0, biHeight = abs(bi.biHeight); i < biHeight; i++) //iterate for each scanline
for (int k = 0; k < bi....
There is definitely an issue with your code. You should first test with scale factor of 1, make sure the headers are right, then check the image data, using the peek and xxd tools. Once those are right (they may already be), repeat with scale of 2 and then 3. You can use the staff version (described in instructions) to generate a file to compare to.
"Everyone's looking for a zebra. I see the injured horse."
All of the file reads and writes are using the outptr output file pointer. The only reference to the input file pointer inptr is the fclose statement at the end. Wouldn't it work better if the code read data from the input file instead of the output file?
If this answers your question, please click ...
It has nothing to do with the malloc call itself. The problem lies in what you think you are checking. Look at the following:
RGBTRIPLE* row = ...
int sizeRow = sizeof(row);
row is declared as a pointer. sizeRow contains the size of the pointer row, not the actual size of the space allocated by the malloc that row points at. A good analogy is this: My ...
Can you say "typo = infinite loop" ?
// replicate pixel n times to outfile
for(int l = 0; l < n; i++)
fwrite(&triple, sizeof(RGBTRIPLE), 1, outptr);
Your for loop initialized L but then increments I (caps added for visibility), resulting in an infinite loop that just keeps writing ...
I think maybe the relationship between biSize, biSizeImage, and bfSize is not reflected properly in the code. Here's reference from MSDN:
bfSize: The size, in bytes, of the bitmap file.
~ MSDN BITMAPFILEHEADER structure
biSize: The number of bytes required by the structure.
biSizeImage: The size, in bytes, of the image.
~ MSDN ...
I see at least one issue, maybe three.
First, your final fseek() that is supposed to go back to the beginning of the line is outside the for( k ) loop when it should be inside. Move it above the preceeding }.
Second, the fseek should move backwards, not forwards, so you need a negative direction, or you need to save the position of the beginning of the ...
fread() knows nothing about the structure. All it knows is the size of the block to read and the address of the memory block where it will put the bytes it reads.
It's up to you to make sure that the block of data you're reading in is sensible and matches the structure that you will subsequently use to access the individual members of the BITMAPFILEHEADER ...
char *n = argv; explains the problem. Your goal is to get a number as input, but that's not what you are doing here. Remember that all arguments in argv are strings. You have essentially grabbed the first character in argv and put it in n. But then you treat n as an integer, something that is allowed, but in this case, is wrong.
Let's say that ...
Ah, but it is not random at all! In fact, it's almost correct!
It looks like you are unaware of a couple features that are going on. I bet that the actual hex number that you're seeing for biSizeImage is FFFFFE50. Two things are at work here.
First, you're seeing a two's complement representation of a negative number. (If you want to know, google two's ...
There are a number of issues that need to be fixed. Since the philosophy of this forum is to guide people to solutions and not just to fix code, I'll point you at two subtle but major issues that will help you with the rest.
First, your generated bitmap files are not being recognized as bitmaps. Very simply, when you write out the BITMAPFILEHEADER and the ...
The spec you're quoting does not actually say that "size of a bmp can't exceed 2^32 -1" as you are (mis)interpreting.
It says that, in order to code your implementation of resize.c, you may assume that.
What (I think) that sentence is telling you, is that when you eventually decide on how to implement your buffer and output to disk it'll be enough for you ...