Can not save screen shot bitmap to file using xlib - c

I am trying to copy the screen to a bitmap file, I found this write XImage to .bmp file in C thread. I tried the code provided myself, but I can not make the code work. It can save a img file, but won't be able to open it. Anything wrong I am doing here?
#include <iostream>
#include <X11/Xlib.h>
#include <cstring>
#include<stdio.h>
typedef unsigned short WORD; // 2bytes
typedef unsigned long DWORD; //4bytes
typedef long LONG;
using namespace std;
void saveXImageToBitmap(XImage *pImage);
int main()
{
Display *display;
int screen;
Window root;
display = XOpenDisplay(0);
screen = DefaultScreen(display);
root = RootWindow(display, screen);
XImage *img = XGetImage(display,root,0,0,400,400,XAllPlanes(),ZPixmap);
if (img != NULL)
{
saveXImageToBitmap(img);
//save image here
}
return 0;
}
#pragma pack(push, 1)
typedef struct BITMAPFILEHEADER {
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
};
#pragma pack(pop)
#pragma pack (push,1)
typedef struct BITMAPINFOHEADER{
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
};
#pragma pack(pop)
void saveXImageToBitmap(XImage *pImage)
{
BITMAPFILEHEADER bmpFileHeader;
BITMAPINFOHEADER bmpInfoHeader;
FILE *fp;
static int cnt = 0;
int dummy;
char filePath[255];
memset(&bmpFileHeader, 0, sizeof(BITMAPFILEHEADER));
memset(&bmpInfoHeader, 0, sizeof(BITMAPINFOHEADER));
bmpFileHeader.bfType = 0x4D42;
bmpFileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + pImage->width*pImage->height*4;
bmpFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
bmpFileHeader.bfReserved1 = 0;
bmpFileHeader.bfReserved2 = 0;
bmpInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInfoHeader.biWidth = pImage->width;
bmpInfoHeader.biHeight = pImage->height;
bmpInfoHeader.biPlanes = 1;
bmpInfoHeader.biBitCount = 32;
dummy = (pImage->width * 3) % 4;
if((4-dummy)==4)
dummy=0;
else
dummy=4-dummy;
bmpInfoHeader.biSizeImage = ((pImage->width*3)+dummy)*pImage->height;
bmpInfoHeader.biCompression = 0;
bmpInfoHeader.biXPelsPerMeter = 0;
bmpInfoHeader.biYPelsPerMeter = 0;
bmpInfoHeader.biClrUsed = 0;
bmpInfoHeader.biClrImportant = 0;
sprintf(filePath, "bitmap%d.bmp", cnt++);
fp = fopen(filePath,"wb");
if(fp == NULL)
return;
fwrite(&bmpFileHeader, sizeof(bmpFileHeader), 1, fp);
fwrite(&bmpInfoHeader, sizeof(bmpInfoHeader), 1, fp);
fwrite(pImage->data, 4*pImage->width*pImage->height, 1, fp);
fclose(fp);
}

I figured it out, the struct BITMAPFILEHEADER size should be 14 based on bitmap file format, the types I was using was wrong. please check the revised code for answer
#include <iostream>
#include <X11/Xlib.h>
#include <cstring>
#include<stdio.h>
using namespace std;
void saveXImageToBitmap(XImage *pImage);
int main()
{
Display *display;
int screen;
Window root;
display = XOpenDisplay(0);
screen = DefaultScreen(display);
root = RootWindow(display, screen);
XWindowAttributes gwa;
XGetWindowAttributes(display, root, &gwa);
int width = gwa.width;
int height = gwa.height;
XImage *img = XGetImage(display,root,0,0,width,height,XAllPlanes(),ZPixmap);
if (img != NULL)
{
saveXImageToBitmap(img);
//save image here
}
return 0;
}
#pragma pack (1)
typedef struct BITMAPFILEHEADER
{
short bfType;
int bfSize;
short bfReserved1;
short bfReserved2;
int bfOffBits;
};
typedef struct BITMAPINFOHEADER
{
int biSize;
int biWidth;
int biHeight;
short biPlanes;
short biBitCount;
int biCompression;
int biSizeImage;
int biXPelsPerMeter;
int biYPelsPerMeter;
int biClrUsed;
int biClrImportant;
};
void saveXImageToBitmap(XImage *pImage)
{
BITMAPFILEHEADER bmpFileHeader;
BITMAPINFOHEADER bmpInfoHeader;
FILE *fp;
static int cnt = 0;
int dummy;
char filePath[255];
memset(&bmpFileHeader, 0, sizeof(BITMAPFILEHEADER));
memset(&bmpInfoHeader, 0, sizeof(BITMAPINFOHEADER));
bmpFileHeader.bfType = 0x4D42;
bmpFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
bmpFileHeader.bfReserved1 = 0;
bmpFileHeader.bfReserved2 = 0;
int biBitCount =32;
int dwBmpSize = ((pImage->width * biBitCount + 31) / 32) * 4 * pImage->height;
printf("size of short:%d\r\n",(int)sizeof(short));
printf("size of int:%d\r\n",(int)sizeof(int));
printf("size of long:%d\r\n",(int)sizeof(long));
printf("dwBmpSize:%d\r\n",(int)dwBmpSize);
printf("BITMAPFILEHEADER:%d\r\n",(int)sizeof(BITMAPFILEHEADER));
printf("BITMAPINFOHEADER:%d\r\n",(int)sizeof(BITMAPINFOHEADER));
bmpFileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwBmpSize;
bmpInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInfoHeader.biWidth = pImage->width;
bmpInfoHeader.biHeight = pImage->height;
bmpInfoHeader.biPlanes = 1;
bmpInfoHeader.biBitCount = biBitCount;
bmpInfoHeader.biSizeImage = 0;
bmpInfoHeader.biCompression = 0;
bmpInfoHeader.biXPelsPerMeter = 0;
bmpInfoHeader.biYPelsPerMeter = 0;
bmpInfoHeader.biClrUsed = 0;
bmpInfoHeader.biClrImportant = 0;
sprintf(filePath, "bitmap%d.bmp", cnt++);
fp = fopen(filePath,"wb");
if(fp == NULL)
return;
fwrite(&bmpFileHeader, sizeof(bmpFileHeader), 1, fp);
fwrite(&bmpInfoHeader, sizeof(bmpInfoHeader), 1, fp);
fwrite(pImage->data, dwBmpSize, 1, fp);
fclose(fp);
}

Related

Improve gain in audio using android studio

I am just a new guy in android studio.This is my code for improving gain of a audio(mp3,wav)file.I don't know how to implement in android studio.I already stored a mp3 file in raw directory,I am using text box or seek bar for getting gain value from user and after it will play the improved gain audio.Can anyone know how to do this?
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
typedef struct header_file
{
char chunk_id[4];
int chunk_size;
char format[4];
char subchunk1_id[4];
int subchunk1_size;
short int audio_format;
short int num_channels;
int sample_rate;
int byte_rate;
short int block_align;
short int bits_per_sample;
char subchunk2_id[4];
int subchunk2_size;
} header;
typedef struct header_file* header_p;
typedef float float32_t;
typedef int uint32_t;
FILE *fr, *fw;
float fs;
#define FRAME 256
int main(int argc, char *argv[] )
{
char a[100];
strcpy(a,argv[1]);
int gain=atoi(a);
fr = fopen("sweeptest.wav", "rb");
fw = fopen( "out1.wav", "wb");
header_p meta = (header_p) malloc(sizeof(header));
fread(meta, 1, sizeof(header), fr);
fwrite(meta, 1, sizeof(header), fw);
fs = meta->sample_rate;
float src[FRAME] = { 0 };
float out1[FRAME] = { 0 };
float out[FRAME] = { 0 };
short Inbuf[256] = { 0 };
short outbuf[256] = { 0 };
int i=0;
float j = gain/20;
float gain_value = pow(10,j);
while (!feof(fr)) {
fread(Inbuf, sizeof(short int), FRAME, fr);
for ( i = 0; i < FRAME; i++)
{
src[i] = (float)(Inbuf[i] / 32767.f);
out1[i] = (src[i] * gain_value);
outbuf[i] =(short)( (out1[i]* 32767.f));
}
fwrite(outbuf, sizeof(short int), FRAME, fw);
}
printf("Program finished");
return 0;
}

OpenSSL rsa routines:RSA_padding_check_PKCS1_type_2:pkcs decoding error

I'm trying to encrypt/decrypt an AES key/iv using RSA encryption algorithm using openssl in C.
The decryption is working before storing the encrypted data into the file . But the decryption threw an error while decrypting the same encrypted data stored on the file.
Here is my code:
#include <stdio.h>
#include <stdbool.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/rsa.h>
#include <openssl/evp.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <string.h>
int padding = RSA_PKCS1_PADDING;
#define RSA_KEY_Size 384;
#define AES_256_KEY_SIZE 32;
// testing encryption/decryption
int func(const char* pubkeyfile, unsigned char *key, unsigned char *iv)
{
unsigned char *encryptedkey = (unsigned char*)malloc(RSA_KEY_Size);
unsigned char *encryptediv = (unsigned char*)malloc(RSA_KEY_Size);
unsigned char *decryptedkey = (unsigned char*)malloc(AES_256_KEY_SIZE);
unsigned char *decryptediv = (unsigned char*)malloc(AES_256_KEY_SIZE);
int result1 = rsaEncrypt(key, pubkeyfile, encryptedkey);
int result2 = rsaEncrypt(iv, pubkeyfile, encryptediv);
serialize(encryptedkey, encryptediv);
///////tested here, this part working fine
int r1 = rsaDecrypt(encryptedkey, privkeyfile, decryptedkey);
int r2 = rsaDecrypt(encryptediv, privkeyfile, decryptediv);
///////////////////////////////
unsigned char *getkey = (unsigned char*)malloc(RSA_KEY_Size);;
unsigned char *getiv = (unsigned char*)malloc(RSA_KEY_Size);;
deserialize(getkey, getiv);
unsigned char *ikey = (unsigned char*)malloc(AES_256_KEY_SIZE);
unsigned char *iiv = (unsigned char*)malloc(AES_256_KEY_SIZE);
//////////tested here, failed to decrypt after taking encrypted data from a file/////////////////
int r22 = rsaDecrypt(getiv, privkeyfile, iiv);
int r21 = rsaDecrypt(getkey, privkeyfile, ikey);
//////////////////////////////////////////////////
return 0;
}
typedef struct item {
uint8_t keyivlen;
char keyiv[RSA_KEY_Size];
struct item *next;
} list;
int serialize(unsigned char* key, unsigned char* iv)
{
list *ptr;
char *buffer;
int listLength;
list first, second;
ptr = &first;
FILE *filePtr;
memcpy(first.keyiv, key, strlen(key));
first.keyivlen = strlen(first.keyiv);
first.next = &second;
memcpy(second.keyiv, iv, strlen(iv));
second.keyivlen = strlen(second.keyiv);
second.next = 0;
listLength = listSize(ptr);
buffer = (char *)malloc(listLength);
serializeList(ptr, buffer);
filePtr = fopen("example.data", "wb+");
fwrite(buffer, listLength, 1, filePtr);
fclose(filePtr);
free(buffer);
return 0;
}
int deserialize(unsigned char* key, unsigned char* iv)
{
FILE *filePtr;
int listLength = 0;
int done = 0;
uint8_t arrayLen;
unsigned char *buffer;
int i = 0;
listLength = fileSize("example.data");
filePtr = fopen("example.data", "rb");
while (done < listLength) {
fread(&arrayLen, 1, 1, filePtr);
buffer = (unsigned char *)malloc(arrayLen + 1);
fread(buffer, arrayLen, 1, filePtr);
buffer[arrayLen] = '\0';
if (i == 0)
{
memcpy(key, buffer, arrayLen + 1);
}
else
{
memcpy(iv, buffer, arrayLen + 1);
}
//addToList(arrayLen, buffer);
done += arrayLen + 1;
i++;
free(buffer);
}
//printList(start);
return 0;
}
Here is the error:
error:0407109F:rsa routines:RSA_padding_check_PKCS1_type_2:pkcs decoding error
error:04065072:rsa routines:rsa_ossl_private_decrypt:padding check failed
And it fails in:
int r22 = rsaDecrypt(getiv, privkeyfile, iiv);
int r21 = rsaDecrypt(getkey, privkeyfile, ikey);
What could be the reason for this error?
arrayLen is only uint8_t which fits at most 255 , so your deserialised data is too short. You need RSA_KEY_Size bytes.

save bmp file using c on linux

I tried to open bmp file and save it using c code. My code worked well on window compiler(visual studio) but it didn't work on linux using gcc. Even though the format of final output is bmp, it shows like empty file(white). I'm a beginner for using linux and c programming so I'm not sure what's wrong with this happening!
I compiled it using gcc: gcc bmp.c -o bmp.
the code below is what I used.
#define _CRT_SECURE_NO_WARNINGS
#include<stdlib.h>
#include<string.h>
#include<stdio.h>
#define WIDTHBYTES(bits) (((bits)+31)/32*4)
#pragma pack(push, 1)
typedef unsigned short WORD;
typedef unsigned long DWORD;
typedef long LONG;
typedef struct tagBITMAPFILEHEADER {
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER;
typedef struct tagBITMAPINFOHEADER {
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER;
typedef struct tagRGBQUAD {
unsigned char rgbBlue;
unsigned char rgbGreen;
unsigned char rgbRed;
unsigned char rgbReserved;
} RGBQUAD;
typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[1];
} BITMAPINFO;
int main(int argc, char* argv[]){
FILE *infile;
FILE *outfile;
BITMAPFILEHEADER hf;
BITMAPINFOHEADER hInfo;
RGBQUAD hRGBpal[256];
unsigned char *lpImg;
int i, j, pos, rwsize;
int nBitCount = 1;
infile = fopen("image.bmp", "rb");
if (infile == NULL)
{
printf("no image");
return 1;
}
fread(&hf, sizeof(BITMAPFILEHEADER), 1, infile);
if (hf.bfType != 0x4d42)
{
printf("ERROR\n");
fclose(infile);
exit(1);
}
fread(&hInfo, sizeof(BITMAPINFOHEADER), 1, infile);
if (hInfo.biBitCount == 8 || hInfo.biBitCount == 16 ||
hInfo.biBitCount == 24 || hInfo.biBitCount == 32)
{
nBitCount = hInfo.biBitCount / 8;
if (hInfo.biBitCount == 8)
{
pos = hf.bfOffBits - hf.bfSize - hInfo.biSize;
if (pos > 0)
{
fread((unsigned char *)hRGBpal, sizeof(unsigned char), pos, infile);
}
}
lpImg = (unsigned char*)malloc(hInfo.biSizeImage);
fseek(infile, hf.bfOffBits, SEEK_SET);
fread(lpImg, sizeof(unsigned char), hInfo.biSizeImage, infile);
fclose(infile);
}
rwsize = WIDTHBYTES(hInfo.biBitCount*hInfo.biWidth);
for (i = 0; i < hInfo.biHeight; i++)
{
for (j = 0; j < hInfo.biWidth; j++)
{
lpImg[i*rwsize + j];
}
}
outfile = fopen("out.bmp", "wb")
if (hInfo.biBitCount == 8)
{
hf.bfOffBits = sizeof(BITMAPFILEHEADER)
+ sizeof(BITMAPINFOHEADER) + sizeof(hRGBpal);
}
fwrite(&hf, sizeof(char), sizeof(BITMAPFILEHEADER), outfile);
fwrite(&hInfo, sizeof(char), sizeof(BITMAPINFOHEADER), outfile);
if (hInfo.biBitCount == 8)
{
fwrite(hRGBpal, sizeof(RGBQUAD), 256, outfile);
}
fwrite(lpImg, sizeof(unsigned char), hInfo.biSizeImage, outfile);
fclose(outfile);
if (lpImg)
free(lpImg);
printf("DONE!");}
This probably goes wrong here:
typedef unsigned short WORD;
typedef unsigned long DWORD;
typedef long LONG;
If you're on 64bit Linux, long has 64 bits. On 64bit Windows, it has only 32bits. For portable code, use fixed-size integers:
typedef uint16_t WORD;
typedef uint32_t DWORD;
typedef int32_t LONG;
On a further note, there's no need to introduce these ugly (my opinion here) winapi typedefs at all. A (sloppy) version of the bitmap file header I'm using (still relying on the "packed struct" feature and merging both structs into one) looks like this:
#pragma pack(push)
#pragma pack(1)
struct bmphdr
{
uint16_t bfType;
uint32_t bfSize;
uint32_t bfReserved;
uint32_t bfOffBits;
uint32_t biSize;
uint32_t biWidth;
int32_t biHeight;
uint16_t biPlanes;
uint16_t biBitCount;
uint32_t biCompression;
uint32_t biSizeImage;
int32_t biXPelsPerMeter;
int32_t biYPelsPerMeter;
uint32_t biClrUsed;
uint32_t biClrImportant;
};
#pragma pack(pop)

Creating bmp file in C

I am trying to create .bmp file (filled with one colour for testing purposes).
Here is code that I'm using:
#include <stdio.h>
#define BI_RGB 0
typedef unsigned int UINT;
typedef unsigned long DWORD;
typedef long int LONG;
typedef unsigned short WORD;
typedef unsigned char BYTE;
typedef struct tagBITMAPFILEHEADER {
UINT bfType;
DWORD bfSize;
UINT bfReserved1;
UINT bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER;
typedef struct tagBITMAPINFOHEADER {
DWORD biSize;
LONG biWidth;
LONG biHeight;
WORD biPlanes;
WORD biBitCount;
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER;
typedef struct COLORREF_RGB
{
BYTE cRed;
BYTE cGreen;
BYTE cBlue;
}COLORREF_RGB;
int main(int argc, char const *argv[])
{
BITMAPINFOHEADER bih;
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biWidth = 600;
bih.biHeight = 600;
bih.biSizeImage = bih.biWidth * bih.biHeight * 3;
bih.biPlanes = 1;
bih.biBitCount = 24;
bih.biCompression = BI_RGB;
bih.biXPelsPerMeter = 2835;
bih.biYPelsPerMeter = 2835;
bih.biClrUsed = 0;
bih.biClrImportant = 0;
COLORREF_RGB rgb;
rgb.cRed = 0;
rgb.cGreen = 0;
rgb.cBlue = 0;
BITMAPFILEHEADER bfh;
bfh.bfType = 0x424D;
bfh.bfReserved1 = 0;
bfh.bfReserved2 = 0;
bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + bih.biSize;
bfh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
bih.biWidth * bih.biHeight * 4;
FILE *f;
f = fopen("test.bmp","wb");
fwrite(&bfh, sizeof(BITMAPFILEHEADER), 1, f);
fwrite(&bih, sizeof(BITMAPINFOHEADER), 1, f);
int i,j;
for(i = 0; i < bih.biHeight; i++)
{
for(j = 0; j < bih.biWidth; j++)
{
fwrite(&rgb,sizeof(COLORREF_RGB),1,f);
}
}
fclose(f);
return 0;
}
and jet every time I compile and run it I get error saying that its not valid BMP image. I double checked all values in multiple references and still can't find error here.
Did I misunderstood something and what am I doing wrong here?
Also not sure if important but I am using Ubuntu 14.04 to compile this.
EDIT
Found one more issue :
bfh.bfType = 0x424D;
should be
bfh.bfType = 0x4D42;
But still can't see image.
First of all, you set:
bfSize Specifies the size of the file, in bytes.
to invalid value, your code resulted into 1440112 while size of file is actually 1080112
bfh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
bih.biWidth * bih.biHeight * sizeof(COLORREF_RGB);
Because sizeof(COLORREF_RGB) is actually 4 not 3.
Another mistake is that size of your structs and types:
expected size actual size*
typedef unsigned int UINT; // 2 4
typedef unsigned long DWORD; // 4 8
typedef long int LONG; // 4 8
typedef unsigned short WORD; // 2 2
typedef unsigned char BYTE; // 1 1
* I'm using gcc on x86_64 architecture
Your offsets just don't match with offsets on wikipedia, reference you are using was probably written for 16 bit compiler on 16 bit OS (as pointed out by cup in a comment) so it assumes int to be 2B type.
Using values from stdint.h worked for me (guide on stdint.h for Visual Studio here):
#include <stdint.h>
typedef uint16_t UINT;
typedef uint32_t DWORD;
typedef int32_t LONG;
typedef uint16_t WORD;
typedef uint8_t BYTE;
And last but not least you have to turn off memory alignment as suggested by Weather Vane.
I believe your field sizes to be incorrect, try this
#pragma pack(push, 1)
typedef struct tagBITMAPFILEHEADER {
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER;
#pragma pack(pop)
You are trying to map a C structure to some externally-defined binary format There are a number of problems with this:
Size
typedef unsigned int UINT;
typedef unsigned long DWORD;
typedef long int LONG;
typedef unsigned short WORD;
typedef unsigned char BYTE;
The C language only specify the minimum sizes of these types. Their actual sizes can and do vary between different compilers and operating systems. The sizes and offset of the members in your structures may not be what you expect. The only size that you can rely on (on almost any system that you are likely to encounter these days) is char being 8 bits.
Padding
typedef struct tagBITMAPFILEHEADER {
UINT bfType;
DWORD bfSize;
UINT bfReserved1;
UINT bfReserved2;
DWORD bfOffBits;
} BITMAPFILEHEADER;
It is common for DWORD to be twice as large as a UINT, and in fact your program depends on it. This usually means that the compiler will introduce padding between bfType and bfSize to give the latter appropriate alignment for its type. The .bmp format has no such padding.
Order
BITMAPFILEHEADER bfh;
bfh.bfType = 0x424D;
...
fwrite(&bfh, sizeof(BITMAPFILEHEADER), 1, f);
Another problem is that the C language does not specify the endianess of the types. The .bfType member may be stored as [42][4D] (Big-Endian) or [4D][42] (Little-Endian) in memory. The .bmp format specifically requires the values to be stored in Little-Endian order.
Solution
You might be able to solve some of these problems by using compiler-specific extensions (such as #pragma's or compiler switches), but probably not all of them.
The only way to properly write an externally-defined binary format, is to use an array of unsigned char and write the values a byte at a time. Personally, I would write a set of helper functions for specific types:
void w32BE (unsigned char *p, unsigned long ul)
{
p[0] = (ul >> 24) & 0xff;
p[1] = (ul >> 16) & 0xff;
p[2] = (ul >> 8) & 0xff;
p[3] = (ul ) & 0xff;
}
void w32LE (unsigned char *p, unsigned long ul)
{
p[0] = (ul ) & 0xff;
p[1] = (ul >> 8) & 0xff;
p[2] = (ul >> 16) & 0xff;
p[3] = (ul >> 24) & 0xff;
}
/* And so on */
and some functions for writing the entire .bmp file or sections of it:
int function write_header (FILE *f, BITMAPFILEHEADER bfh)
{
unsigned char buf[14];
w16LE (buf , bfh.bfType);
w32LE (buf+ 2, bfh.bfSize);
w16LE (buf+ 6, bfh.bfReserved1);
w16LE (buf+ 8, bfh.bfReserved2);
w32LE (buf+10, bfh.bfOffBits);
return fwrite (buf, sizeof buf, 1, f);
}

working with bitmap in c

This is my first time working with bitmaps, and I've gotten pretty much most of what i need figured out already. I just need to figure out how to
1) print the first 16 pixels
Please help :) I am trying get a good grasp of working with the bmp format.
#include <stdio.h>
typedef struct __attribute__((__packed__)) {
unsigned char fileMarker1;
unsigned char fileMarker2;
unsigned int bfSize;
uint16_t unused1;
uint16_t unused2;
unsigned int imageDataOffset;
} FILEHEADER;
typedef struct __attribute__((__packed__)) {
unsigned int biSize;
int width;
int height;
uint16_t planes;
uint16_t bitPix;
unsigned int biCompression;
unsigned int biSizeImage;
int biXPelsPerMeter;
int biYPelsPerMeter;
unsigned int biClrUsed;
unsigned int biClrImportant;
} INFOHEADER;
typedef struct __attribute__((__packed__)) {
unsigned char b;
unsigned char g;
unsigned char r;
} IMAGE;
int main(void) {
FILEHEADER fh;
INFOHEADER ih;
FILE *img = fopen("sample.bmp", "rb");
fread(&fh, sizeof(unsigned char), sizeof(FILEHEADER), img);
fread(&ih, sizeof(unsigned char), sizeof(INFOHEADER), img);
printf("width: <%d>\nheight: <%d>\n", ih.width, ih.height);
printf("planes: <%d>\n", ih.planes) ;
printf("Bits per pixel: <%d>", ih.bitPix );
return 0;
}

Resources