The Shed is going Social! Join us on FaceBook and Twitter and chime in on the conversation.
|
 |
|
Dev Shed Forums
> Programming Languages
> C Programming
|
Need help resizing a bitmap file
Discuss Need help resizing a bitmap file in the C Programming forum on Dev Shed. Need help resizing a bitmap file C programming forum discussing all C derivatives, including C#, C++, Object-C, and even plain old vanilla C. These languages are low level languages, and used on projects such as device drivers, compilers, and even whole computer operating systems.
|
|
 |
|
|
|
|
|

Dev Shed Forums Sponsor:
|
|
|

January 27th, 2013, 07:58 PM
|
|
Registered User
|
|
Join Date: Jan 2013
Posts: 15
Time spent in forums: 4 h 26 m 49 sec
Reputation Power: 0
|
|
|
Need help resizing a bitmap file
Hello all!
I am having a very hard trying to figure out how to resize a bitmap file. I feel like I'm very close(as I'm getting some output). However, my output file outputs a black color. When I performed xxd on my output file, I actually noticed that the colors are being written to the file. Just for some reason I'm not seeing it. Here is the code I currently have:
FILE* inptr = fopen(infile, "r");
if (inptr == NULL)
{
printf("Could not open %s.\n", infile);
return 4;
}
// open output file
FILE* outptr = fopen(outfile, "w");
if (outptr == NULL)
{
fclose(inptr);
fprintf(stderr, "Could not create %s.\n", outfile);
return 5;
}
// read infile's BITMAPFILEHEADER
BITMAPFILEHEADER bf;
fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);
// read infile's BITMAPINFOHEADER
BITMAPINFOHEADER bi;
fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);
Oldwidth=bi.biWidth;
OldHeight=bi.biHeight;
oldSizeImage=bi.biSizeImage;
bi.biWidth=bi.biWidth*factor;
bi.biHeight=bi.biHeight*factor;
oldpadding= (4-(Oldwidth*sizeof(RGBTRIPLE)) % 4) % 4;
bi.biSizeImage=bi.biWidth*(abs(bi.biHeight))*(sizeof(RGBTRIPLE));
// 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;
}
RGBTRIPLE *buffer=NULL;
buffer = malloc(sizeof(RGBTRIPLE) * bi.biWidth);
// write outfile's BITMAPFILEHEADER
fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);
// write outfile's BITMAPINFOHEADER
fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr);
// determine padding for scanlines
int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
// iterate over infile's scanlines
for (int i = 0; i<abs(OldHeight); i++)
{
// iterate over pixels in scanline
for (int j = 0; j < Oldwidth; j++)
{
// temporary storage
RGBTRIPLE triple;
// read RGB triple from infile
fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
//iterate over each pixel factor times
for (int k = 0; k <factor; k++)
{
buffer[k]=triple;
}
// write RGB triple to outfile
// fwrite(&triple, sizeof(RGBTRIPLE), bi.biWidth, outptr);
}
// skip over padding, if any
fseek(inptr,54 + (Oldwidth*sizeof(RGBTRIPLE)*i), SEEK_SET);
for (int r = 0; r < factor; r++)
{
fwrite(buffer, sizeof(RGBTRIPLE), bi.biWidth, outptr);
}
// write padding to outfile
for (int p = 0; p < padding; p++)
fputc(0x00, outptr);
}
Any help or suggestions would greatly be appreciated. thanks.
|

January 28th, 2013, 02:13 AM
|
 |
Contributed User
|
|
|
|
First, use [code][/code] tags when posting code.
Like so
Code:
#include <stdio.h>
int main()
{
FILE *inptr = fopen(infile, "r");
if (inptr == NULL) {
printf("Could not open %s.\n", infile);
return 4;
}
// open output file
FILE *outptr = fopen(outfile, "w");
if (outptr == NULL) {
fclose(inptr);
fprintf(stderr, "Could not create %s.\n", outfile);
return 5;
}
// read infile's BITMAPFILEHEADER
BITMAPFILEHEADER bf;
fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);
// read infile's BITMAPINFOHEADER
BITMAPINFOHEADER bi;
fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);
Oldwidth = bi.biWidth;
OldHeight = bi.biHeight;
oldSizeImage = bi.biSizeImage;
bi.biWidth = bi.biWidth * factor;
bi.biHeight = bi.biHeight * factor;
oldpadding = (4 - (Oldwidth * sizeof(RGBTRIPLE)) % 4) % 4;
bi.biSizeImage = bi.biWidth * (abs(bi.biHeight)) * (sizeof(RGBTRIPLE));
// 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;
}
RGBTRIPLE *buffer = NULL;
buffer = malloc(sizeof(RGBTRIPLE) * bi.biWidth);
// write outfile's BITMAPFILEHEADER
fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);
// write outfile's BITMAPINFOHEADER
fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr);
// determine padding for scanlines
int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
// iterate over infile's scanlines
for (int i = 0; i < abs(OldHeight); i++) {
// iterate over pixels in scanline
for (int j = 0; j < Oldwidth; j++) {
// temporary storage
RGBTRIPLE triple;
// read RGB triple from infile
fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
//iterate over each pixel factor times
for (int k = 0; k < factor; k++) {
buffer[k] = triple;
}
// write RGB triple to outfile
// fwrite(&triple, sizeof(RGBTRIPLE), bi.biWidth, outptr);
}
// skip over padding, if any
fseek(inptr, 54 + (Oldwidth * sizeof(RGBTRIPLE) * i), SEEK_SET);
for (int r = 0; r < factor; r++) {
fwrite(buffer, sizeof(RGBTRIPLE), bi.biWidth, outptr);
}
// write padding to outfile
for (int p = 0; p < padding; p++)
fputc(0x00, outptr);
}
return 0;
}
Second - what tests have you done?
The obvious case with factor=1 should just make a copy of the file - does it?
What test bmp files do you have?
3x3 4x4 and 5x5 should allow you to test the most interesting aspects of padding, and be small enough that you can single-step the code without having to wait for ages for each row to complete (for example). They're also small enough to visually check in a hex editor.
Your padding calculations seem overly complicated.
The fseek to skip the padding might be better as
fseek(inptr,oldPadding,SEEK_CUR);
On windows, you need to open the files in "rb" and "wb" modes.
|

January 28th, 2013, 03:49 PM
|
|
Registered User
|
|
Join Date: Jan 2013
Posts: 15
Time spent in forums: 4 h 26 m 49 sec
Reputation Power: 0
|
|
Quote: | Originally Posted by salem First, use [code][/code] tags when posting code.
Like so
Code:
#include <stdio.h>
int main()
{
FILE *inptr = fopen(infile, "r");
if (inptr == NULL) {
printf("Could not open %s.\n", infile);
return 4;
}
// open output file
FILE *outptr = fopen(outfile, "w");
if (outptr == NULL) {
fclose(inptr);
fprintf(stderr, "Could not create %s.\n", outfile);
return 5;
}
// read infile's BITMAPFILEHEADER
BITMAPFILEHEADER bf;
fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);
// read infile's BITMAPINFOHEADER
BITMAPINFOHEADER bi;
fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);
Oldwidth = bi.biWidth;
OldHeight = bi.biHeight;
oldSizeImage = bi.biSizeImage;
bi.biWidth = bi.biWidth * factor;
bi.biHeight = bi.biHeight * factor;
oldpadding = (4 - (Oldwidth * sizeof(RGBTRIPLE)) % 4) % 4;
bi.biSizeImage = bi.biWidth * (abs(bi.biHeight)) * (sizeof(RGBTRIPLE));
// 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;
}
RGBTRIPLE *buffer = NULL;
buffer = malloc(sizeof(RGBTRIPLE) * bi.biWidth);
// write outfile's BITMAPFILEHEADER
fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);
// write outfile's BITMAPINFOHEADER
fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr);
// determine padding for scanlines
int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
// iterate over infile's scanlines
for (int i = 0; i < abs(OldHeight); i++) {
// iterate over pixels in scanline
for (int j = 0; j < Oldwidth; j++) {
// temporary storage
RGBTRIPLE triple;
// read RGB triple from infile
fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
//iterate over each pixel factor times
for (int k = 0; k < factor; k++) {
buffer[k] = triple;
}
// write RGB triple to outfile
// fwrite(&triple, sizeof(RGBTRIPLE), bi.biWidth, outptr);
}
// skip over padding, if any
fseek(inptr, 54 + (Oldwidth * sizeof(RGBTRIPLE) * i), SEEK_SET);
for (int r = 0; r < factor; r++) {
fwrite(buffer, sizeof(RGBTRIPLE), bi.biWidth, outptr);
}
// write padding to outfile
for (int p = 0; p < padding; p++)
fputc(0x00, outptr);
}
return 0;
}
Second - what tests have you done?
The obvious case with factor=1 should just make a copy of the file - does it?
What test bmp files do you have?
3x3 4x4 and 5x5 should allow you to test the most interesting aspects of padding, and be small enough that you can single-step the code without having to wait for ages for each row to complete (for example). They're also small enough to visually check in a hex editor.
Your padding calculations seem overly complicated.
The fseek to skip the padding might be better as
fseek(inptr,oldPadding,SEEK_CUR);
On windows, you need to open the files in "rb" and "wb" modes. |
Thanks Salem for getting back to me. I appreciate it. I have not done a hex dump to see the output of my code(I'll be sure to do that tonight).
I agree about my padding lol.What happpened, I started to question the padding I initially had. The padding that you output(fseek(inptr,oldPadding,SEEK_CUR) is the padding I initially had. I do have two test files, and there is an enlargement going on. But do you know or have some sort of an idea on what would be causing the black output to display on my output file?
|

January 28th, 2013, 08:23 PM
|
|
|
Quote: | But do you know or have some sort of an idea on what would be causing the black output to display on my output file |
First of all, you didn't post your complete code. So, I have to ask if you have byte aligned the BitmapFileHeader structure. Failing to byte align the structure would throw off everything in your file by two bytes causing inaccurate reads and writes.
Secondly, I don't see where you are adding your "factor" to the biWidth and biHeight variable fields of your output BitmapInfoHeader structure.
Finally, I don't see where you calculate the value for the bfSize for your output BitmapInfoHeader.
|

January 28th, 2013, 10:16 PM
|
|
Registered User
|
|
Join Date: Jan 2013
Posts: 15
Time spent in forums: 4 h 26 m 49 sec
Reputation Power: 0
|
|
Quote: | Originally Posted by BobS0327 First of all, you didn't post your complete code. So, I have to ask if you have byte aligned the BitmapFileHeader structure. Failing to byte align the structure would throw off everything in your file by two bytes causing inaccurate reads and writes.
Secondly, I don't see where you are adding your "factor" to the biWidth and biHeight variable fields of your output BitmapInfoHeader structure.
Finally, I don't see where you calculate the value for the bfSize for your output BitmapInfoHeader. |
Code:
// ensure proper usage
if (argc != 4)
{
printf("Usage: resize n infile outfile\n");
return 1;
}
// remember filenames
char* number=argv[1];
char* infile = argv[2];
char* outfile = argv[3];
factor=atoi(number);
/* if (!isdigit(factor))*/
/* {*/
/* printf("Resize factor must be an integer\n");*/
/* return 2;*/
/* }*/
if (factor>100)
{
printf("Please enter in a number greater than 0 and less than or equal to 100 ");
printf(" \n");
printf("%d",factor);
return 3;
}
// open input file
FILE* inptr = fopen(infile, "r");
if (inptr == NULL)
{
printf("Could not open %s.\n", infile);
return 4;
}
// open output file
FILE* outptr = fopen(outfile, "w");
if (outptr == NULL)
{
fclose(inptr);
fprintf(stderr, "Could not create %s.\n", outfile);
return 5;
}
// read infile's BITMAPFILEHEADER
BITMAPFILEHEADER bf;
fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);
// read infile's BITMAPINFOHEADER
BITMAPINFOHEADER bi;
fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);
Oldwidth=bi.biWidth;
OldHeight=bi.biHeight;
oldSizeImage=bi.biSizeImage;
bi.biWidth=bi.biWidth*factor;
bi.biHeight=bi.biHeight*factor;
oldpadding= (4-(Oldwidth*sizeof(RGBTRIPLE)) % 4) % 4;
bi.biSizeImage=bi.biWidth*(abs(bi.biHeight))*(sizeof(RGBTRIPLE));
// 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;
}
RGBTRIPLE *buffer=NULL;
buffer = malloc(sizeof(RGBTRIPLE) * bi.biWidth);
// write outfile's BITMAPFILEHEADER
fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);
// write outfile's BITMAPINFOHEADER
fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr);
// determine padding for scanlines
int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
// iterate over infile's scanlines
for (int i = 0; i<abs(OldHeight); i++)
{
// iterate over pixels in scanline
for (int j = 0; j < Oldwidth; j++)
{
int k=0;
// temporary storage
RGBTRIPLE triple;
// read RGB triple from infile
fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
//iterate over each pixel factor times
// for (int k = 0; k <factor; k++)
// {
buffer[k]= triple;
// temp= (BYTE)temp2;
// }
// write RGB triple to outfile
// fwrite(&triple, sizeof(RGBTRIPLE), bi.biWidth, outptr);
fwrite(buffer, sizeof(RGBTRIPLE), bi.biWidth, outptr);
}
// skip over padding, if any
// fseek(inptr, 54 + (Oldwidth*sizeof(RGBTRIPLE)*i), SEEK_SET);
fseek(inptr, padding, SEEK_CUR);
/* for (int r = 0; r < factor; r++) */
/* { */
/* */
/* fwrite(buffer, sizeof(RGBTRIPLE), bi.biWidth, outptr); */
/* }*/
// write padding to outfile
for (int p = 0; p < padding; p++)
fputc(0x00, outptr);
}
// close infile
fclose(inptr);
// close outfile
fclose(outptr);
here it is bob!
|

January 28th, 2013, 11:29 PM
|
 |
Contributed User
|
|
|
|
|
That's not complete code.
Where is main() ?
Where is the definition of your structs BITMAPFILEHEADER, BITMAPINFOHEADER and RGBTRIPLE. Are you assuming we're all visual studio users with access to windows.h?
Complete code is where we can do copy/paste into a source file, and compile it with ANY ANSI/ISO compatible compiler. Otherwise, you're just cutting down on the number of people who can help you (who have your compiler), and can be bothered to patch up your code to make it compile.
|

January 28th, 2013, 11:32 PM
|
|
|
Well, the submitted code isn't compilable and it still doesn't indicate how you're implementing the various required bitmap structures. For example, in the Windows environment, you could use the windows.h header file in order to use the BitmapInfoHeader structure etc.
But from a Microsoft compiler perspective, you would byte align the BITMAPFILEHEADER structure as follows:
Code:
#pragma pack(push)
#pragma pack(1)
typedef struct
{
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
}BITMAPFILEHEADER;
#pragma pack(pop)
If you use the sizeof macro to return the total size of this structure as it appears above, it would return 14 bytes which is the required structure size in the bitmap file format. If you did NOT use the MS pragma commands as indicated above, sizeof would return 16 bytes as the total size of the structure which will cause your read and writes on the BMP file format to be inaccurate. In other words, the structure is being padded which is what you do NOT want.
If you want to continue working on this assignment, you must post compilable code for us to review. This compilable code will consist of the following three structures:
BITMAPINFOHEADER
RGBTRIPLE
BITMAPFILEHEADER (the structure above)
As a starting point, I would suggest that you clone a BITMAPFILEHEADER struct from your input BMP and then modify it to be used in writing the output BMP file.
One such modification would be as follows:
Code:
output.biWidth = bi.biWidth * factor;
output.biHeight = bi.biHeight * factor;
Last edited by BobS0327 : January 28th, 2013 at 11:36 PM.
|

January 28th, 2013, 11:37 PM
|
|
Registered User
|
|
Join Date: Jan 2013
Posts: 15
Time spent in forums: 4 h 26 m 49 sec
Reputation Power: 0
|
|
Quote: | Originally Posted by salem That's not complete code.
Where is main() ?
Where is the definition of your structs BITMAPFILEHEADER, BITMAPINFOHEADER and RGBTRIPLE. Are you assuming we're all visual studio users with access to windows.h?
Complete code is where we can do copy/paste into a source file, and compile it with ANY ANSI/ISO compatible compiler. Otherwise, you're just cutting down on the number of people who can help you (who have your compiler), and can be bothered to patch up your code to make it compile. |
sorry man! LOL....not trying to be a butt at all...
Code:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "bmp.h"
int main(int argc, char* argv[])
{
int factor=0;
int Oldwidth=0;
int OldHeight=0;
int oldpadding=0;
int oldSizeImage =0;
// ensure proper usage
if (argc != 4)
{
printf("Usage: resize n infile outfile\n");
return 1;
}
// remember filenames
char* number=argv[1];
char* infile = argv[2];
char* outfile = argv[3];
factor=atoi(number);
/* if (!isdigit(factor))*/
/* {*/
/* printf("Resize factor must be an integer\n");*/
/* return 2;*/
/* }*/
if (factor>100)
{
printf("Please enter in a number greater than 0 and less than or equal to 100 ");
printf(" \n");
printf("%d",factor);
return 3;
}
// open input file
FILE* inptr = fopen(infile, "r");
if (inptr == NULL)
{
printf("Could not open %s.\n", infile);
return 4;
}
// open output file
FILE* outptr = fopen(outfile, "w");
if (outptr == NULL)
{
fclose(inptr);
fprintf(stderr, "Could not create %s.\n", outfile);
return 5;
}
// read infile's BITMAPFILEHEADER
BITMAPFILEHEADER bf;
fread(&bf, sizeof(BITMAPFILEHEADER), 1, inptr);
// read infile's BITMAPINFOHEADER
BITMAPINFOHEADER bi;
fread(&bi, sizeof(BITMAPINFOHEADER), 1, inptr);
Oldwidth=bi.biWidth;
OldHeight=bi.biHeight;
oldSizeImage=bi.biSizeImage;
bi.biWidth=bi.biWidth*factor;
bi.biHeight=bi.biHeight*factor;
oldpadding= (4-(Oldwidth*sizeof(RGBTRIPLE)) % 4) % 4;
bi.biSizeImage=bi.biWidth*(abs(bi.biHeight))*(sizeof(RGBTRIPLE));
// 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;
}
RGBTRIPLE *buffer=NULL;
buffer = malloc(sizeof(RGBTRIPLE) * bi.biWidth);
// write outfile's BITMAPFILEHEADER
fwrite(&bf, sizeof(BITMAPFILEHEADER), 1, outptr);
// write outfile's BITMAPINFOHEADER
fwrite(&bi, sizeof(BITMAPINFOHEADER), 1, outptr);
// determine padding for scanlines
int padding = (4 - (bi.biWidth * sizeof(RGBTRIPLE)) % 4) % 4;
// iterate over infile's scanlines
for (int i = 0, BHeight=abs(OldHeight);i<BHeight; i++)
{
// iterate over pixels in scanline
for (int j = 0; j < Oldwidth; j++)
{
// temporary storage
RGBTRIPLE triple;
// read RGB triple from infile
fread(&triple, sizeof(RGBTRIPLE), 1, inptr);
//iterate over each pixel factor times
for (int k = 0; k <factor; k++)
{
buffer[k]= triple;
}
// write RGB triple to outfile
// fwrite(&triple, sizeof(RGBTRIPLE), bi.biWidth, outptr);
fwrite(buffer, sizeof(RGBTRIPLE),1, outptr);
}
// skip over padding, if any
fseek(inptr, 54 + (Oldwidth*sizeof(RGBTRIPLE)*i), SEEK_SET);
// write padding to outfile
for (int p = 0; p <padding; p++)
fputc(0x00, outptr);
}
// close infile
fclose(inptr);
// close outfile
fclose(outptr);
return 0;
Code:
#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(PROT.10).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;
Sorry again.
|

January 29th, 2013, 03:33 AM
|
 |
Contributed User
|
|
|
|
Code:
$ ./a.out 2 foo5x5-24.bmp bar.bmp
$ odx foo5x5-24.bmp
000000 42 4d 86 00 00 00 00 00 00 00 36 00 00 00 28 00 >BM........6...(.<
000010 00 00 05 00 00 00 05 00 00 00 01 00 18 00 00 00 >................<
000020 00 00 50 00 00 00 13 0b 00 00 13 0b 00 00 00 00 >..P.............<
000030 00 00 00 00 00 00 33 33 33 36 36 36 39 39 39 3c >......333666999<<
000040 3c 3c 3f 3f 3f 00 63 63 63 66 66 66 69 69 69 6c ><<???.cccfffiiil<
000050 6c 6c 6f 6f 6f 00 93 93 93 96 96 96 99 99 99 9c >llooo...........<
000060 9c 9c 9f 9f 9f 00 c3 c3 c3 c6 c6 c6 c9 c9 c9 cc >................<
000070 cc cc cf cf cf 00 f3 f3 f3 f6 f6 f6 f9 f9 f9 fc >................<
000080 fc fc ff ff ff 00 >......<
000086
$ odx bar.bmp
000000 42 4d 86 00 00 00 00 00 00 00 36 00 00 00 28 00 >BM........6...(.<
000010 00 00 0a 00 00 00 0a 00 00 00 01 00 18 00 00 00 >................<
000020 00 00 2c 01 00 00 13 0b 00 00 13 0b 00 00 00 00 >..,.............<
000030 00 00 00 00 00 00 33 33 33 36 36 36 39 39 39 3c >......333666999<<
000040 3c 3c 3f 3f 3f 00 00 33 33 33 36 36 36 39 39 39 ><<???..333666999<
000050 3c 3c 3c 3f 3f 3f 00 00 00 63 63 63 66 66 66 69 ><<<???...cccfffi<
000060 69 69 6c 6c 6c 6f 6f 00 00 6f 00 93 93 93 96 96 >iillloo..o......<
000070 96 99 99 99 9c 9c 9c 9f 00 00 9f 9f 00 c3 c3 c3 >................<
000080 c6 c6 c6 c9 c9 c9 cc cc cc 00 00 >...........<
00008b
The only thing you managed to do was insert an extra padding byte at the end of each row. But at least 2 bytes of padding is correct for an image which should be 10x10 when complete.
> buffer[k]= triple;
You need to append pixels to the buffer, not overwrite the ones you stored.
> fwrite(buffer, sizeof(RGBTRIPLE),1, outptr);
You need to write the whole buffer, not just one pixel.
You also need to do this 'factor' times.
Don't forget the padding at the end of each row.
My test bitmap is attached.
|

January 29th, 2013, 11:02 AM
|
|
Registered User
|
|
Join Date: Jan 2013
Posts: 15
Time spent in forums: 4 h 26 m 49 sec
Reputation Power: 0
|
|
Quote: | Originally Posted by salem
Code:
$ ./a.out 2 foo5x5-24.bmp bar.bmp
$ odx foo5x5-24.bmp
000000 42 4d 86 00 00 00 00 00 00 00 36 00 00 00 28 00 >BM........6...(.<
000010 00 00 05 00 00 00 05 00 00 00 01 00 18 00 00 00 >................<
000020 00 00 50 00 00 00 13 0b 00 00 13 0b 00 00 00 00 >..P.............<
000030 00 00 00 00 00 00 33 33 33 36 36 36 39 39 39 3c >......333666999<<
000040 3c 3c 3f 3f 3f 00 63 63 63 66 66 66 69 69 69 6c ><<???.cccfffiiil<
000050 6c 6c 6f 6f 6f 00 93 93 93 96 96 96 99 99 99 9c >llooo...........<
000060 9c 9c 9f 9f 9f 00 c3 c3 c3 c6 c6 c6 c9 c9 c9 cc >................<
000070 cc cc cf cf cf 00 f3 f3 f3 f6 f6 f6 f9 f9 f9 fc >................<
000080 fc fc ff ff ff 00 >......<
000086
$ odx bar.bmp
000000 42 4d 86 00 00 00 00 00 00 00 36 00 00 00 28 00 >BM........6...(.<
000010 00 00 0a 00 00 00 0a 00 00 00 01 00 18 00 00 00 >................<
000020 00 00 2c 01 00 00 13 0b 00 00 13 0b 00 00 00 00 >..,.............<
000030 00 00 00 00 00 00 33 33 33 36 36 36 39 39 39 3c >......333666999<<
000040 3c 3c 3f 3f 3f 00 00 33 33 33 36 36 36 39 39 39 ><<???..333666999<
000050 3c 3c 3c 3f 3f 3f 00 00 00 63 63 63 66 66 66 69 ><<<???...cccfffi<
000060 69 69 6c 6c 6c 6f 6f 00 00 6f 00 93 93 93 96 96 >iillloo..o......<
000070 96 99 99 99 9c 9c 9c 9f 00 00 9f 9f 00 c3 c3 c3 >................<
000080 c6 c6 c6 c9 c9 c9 cc cc cc 00 00 >...........<
00008b
The only thing you managed to do was insert an extra padding byte at the end of each row. But at least 2 bytes of padding is correct for an image which should be 10x10 when complete.
> buffer[k]= triple;
You need to append pixels to the buffer, not overwrite the ones you stored.
> fwrite(buffer, sizeof(RGBTRIPLE),1, outptr);
You need to write the whole buffer, not just one pixel.
You also need to do this 'factor' times.
Don't forget the padding at the end of each row.
My test bitmap is attached. |
How would I append the pixels to the buffer?
buffer+=Triple;?
|

January 29th, 2013, 11:34 AM
|
 |
Contributed User
|
|
|
|
|
> How would I append the pixels to the buffer?
Here's a side exercise for you - write your own strcat() function.
|

January 29th, 2013, 11:53 AM
|
|
Registered User
|
|
Join Date: Jan 2013
Posts: 15
Time spent in forums: 4 h 26 m 49 sec
Reputation Power: 0
|
|
Quote: | Originally Posted by salem > How would I append the pixels to the buffer?
Here's a side exercise for you - write your own strcat() function. |
That makes sense...its a string, not a integer or number. Ok, thank you! Sorry about earlier man. Wasnt trying to be a butt. This was, afteral, my first time posting to this forum.
|

January 29th, 2013, 01:21 PM
|
 |
Contributed User
|
|
|
|
Quote: | Originally Posted by saldar05 That makes sense...its a string, not a integer or number. |
Not really,
It's about the concept.
The way that you would write
strcat(char *dest, const char *src);
is in some way similar to what you would write for
rgbtriplecat( RGBTRIPLE *dest, const RGBTRIPLE *src );
If you also maintain a count of the number added, this becomes rather trivial.
|

January 29th, 2013, 05:45 PM
|
|
Registered User
|
|
Join Date: Jan 2013
Posts: 15
Time spent in forums: 4 h 26 m 49 sec
Reputation Power: 0
|
|
Quote: | Originally Posted by salem Not really,
It's about the concept.
The way that you would write
strcat(char *dest, const char *src);
is in some way similar to what you would write for
rgbtriplecat( RGBTRIPLE *dest, const RGBTRIPLE *src );
If you also maintain a count of the number added, this becomes rather trivial. |
Ok, but for sure, in your humble opinion, strcat is the way to go to append the pixels to the buffer? And by overwriting them, you are essentially saying that when the the for loop within the width for loop exits, the for loop for width starts to rewrite what has already been written, correct?
|

January 29th, 2013, 09:25 PM
|
|
|
|
One way to add your image data to your BMP file is to set up several loops. The outer loop would be based on the height of the new image. The inner loop would be based on the width of the new image. This inner loop would read a RGBTRIPLE from the input file and then "factor" it into the buffer. The next loop within the height loop would write out buffer that was previously built a number of times based on the value of "factor". Finally, append padding based on the "new" padding value.
Your logic would look something lik this pseudo code:
|-Height loop (based on image height)
| |- Width loop (based on image width)
| | Read a RGBTRIPLE from input file
| |- Loop to "factor" each pixel in buffer
| Skip over "old" padding in input file using fseek SEEK_CUR
| Loop to write out buffer to row "factor" of times
|- Append "new" padding to output file using fputc
|
Developer Shed Advertisers and Affiliates
| Thread Tools |
Search this Thread |
|
|
|
| Display Modes |
Rate This Thread |
Linear Mode
|
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|
|