Reading and writing bitmaps in c - c

I'm trying to create an application that inverts the colors of a bitmap file but am having some trouble with actually gathering the data and from the bitmap. I'm using structures to keep the data for the bitmap and it's header. Right now I have:
struct
{
uint16_t type;
uint32_t size;
uint32_t offset;
uint32_t header_size;
int32_t width;
int32_t height;
uint16_t planes;
uint16_t bits;
uint32_t compression;
uint32_t imagesize;
int32_t xresolution;
int32_t yresolution;
uint32_t ncolours;
uint32_t importantcolours;
} header_bmp
struct {
header_bmp header;
int data_size;
int width;
int height;
int bytes_per_pixel;
char *data;
} image_bmp;
Now for actually reading and writing the bitmap I have the following:
image_bmp* startImage(FILE* fp)
{
header_bmp* bmp_h = (struct header_bmp*)malloc(sizeof(struct header_bmp));
ReadHeader(fp, bmp_h, 54);
}
void ReadHeader(FILE* fp, char* header, int dataSize)
{
fread(header, dataSize, 1, fp);
}
From here how do I extract the header information into my header structure?
Also if anyone has any good resources over reading and writing bitmaps, please let me know. I have been searching for hours and can't find much useful information over the topic.

You actually should already have all the data in the correct places. The only issue possibly gone wrong could be endianness. e.g. is the number 256 represented in "short" as
0x01 0x00 or 0x00 0x01.
EDIT: there is something wrong related to the syntax of struct...
struct name_of_definition { int a; int b; short c; short d; };
struct name_of_def_2 { struct name_of_definition instance; int a; int b; }
*ptr_to_instance; // or one can directly allocate the instance it self by
// by omitting the * mark.
struct { int b; int c; } instance_of_anonymous_struct;
ptr_to_instance = malloc(sizeof(struct name_of_def_2));
also:
ReadHeader(fp, (char*)&ptr_to_instance->header, sizeof(struct definition));
// ^ don't forget to cast to the type accepted by ReadHeader
In this way you can directly read data into the middle of the struct, but the possible issue of endianness still lurks around.

Related

Efficient storage of parameters in C [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I have an application where I need to store values, those values can be either a double, an integer, a string (fixed size char array), uint8_t, chars, ...
Each of these values also has additional parameters, it can be Read-Only, Read-Write or they can have a max or min value (obviously for numeric types only).
So basically a simple struct would look like this:
typedef struct {
uint32_t current_val;
uint32_t min;
uint32_t max;
uint8_t type;
uint32_t initial_value;
uint8_t access_mode = READ_WRITE;
} valueType;
Now obviously this struct could only hold a uint32_t parameter value. I'd like to have many of those with different types and then store them in a common array.
Do you see any chance of doing this except for storing the reference to the instance and then finding out what the parameter type actually is?
I've seen a solution where for each of those parameters a memory section was allocated and then parameter was stored there. So basically the largest parameter was a 32byte string which caused even an uint32_t to occupy 32 bytes.
What would be the correct way to address this issue? Is there some common way to do this? Maybe just throw in some term so I know what to google for.
Efficient storage of parameters in C
Let us assume a fixed size per parameter.
So basically the largest parameter was a 32byte string
So we need at least 32 bytes. Use a union to overlay the various types of data.
typedef union {
char s[32];
TBD;
} valueType;
A string always ends with a null character so code can use the last char string[32-1] zero-ness as a flag for string vs. non-string.
For other types, keep track via a .type_identifier member.
typedef union {
char string[32];
struct {
union {
struct { uint32_t val; uint32_t min; uint32_t max; uint32_t initial; } t_uint32;
struct { float val; float min; float max; float initial; } t_float;
struct { char val; char min; char max; char initial; } t_char;
} u;
uint8_t type_identifier;
uint8_t access_mode;
} not_string;
} valueType;
This is fine when the size of .not_string is less than the size of .string.
Yet OP wants to code double, which commonly takes 8 bytes each and also wants 4 doublemembers.
So might as well:
typedef struct {
int type_identifier; // or uint8_t
int access_mode; // or uint8_t
union {
char string[32];
struct { uint32_t val; uint32_t min; uint32_t max; uint32_t initial; } t_uint32;
struct { double val; double min; double max; double initial; } t_double;
struct { float val; float min; float max; float initial; } t_float;
struct { char val; char min; char max; char initial; } t_char;
} u;
} valueType;
This may be as small as 2 + 32 bytes or a tad larger depending on padding requirements.
Unions are the way to go! Have an enum saying what type is stored there (I've used an int_8 to make the example small) and then do this:
struct {
int_8 type;
union {
int_8 eight_wide_thing;
char char_buffer[42];
double more_bad_variable_names;
}
int_32 foo_count;
} example;
You can do this:
struct example bar;
bar.eight_wide_thing = 42;
printf("%d", bar.eight_wide_thing);
bar.char_buffer[3] = '\0';
bar.char_buffer[0] = 'H';
bar.char_buffer[1] = 'i';
bar.char_buffer[2] = '!';
printf("%s", bar.char_buffer);
But not this:
bar.eight_wide_thing = 42;
bar.more_bad_variable_names /= 6;

I can't read .bmp file in C on Linux, but I can do it in raspbian (same code)

Sorry for my bad English.
Im trying to read a .bmp file in a C code using gcc on Linux (Fedora 27) but it doesn't work, the specific problem is when I use "fread()". I run the same code on raspbian (4.9.2-10) and magically works, read and write a .bmp file correctly. I really don't know what happening, I need help, please :'(
I use this image:
https://mega.nz/#!c5hVEYTb!u4Mc3JxvrHxxpaMLpH8A-KS3_bb72_Nj9bHv1x-2keU
This is the code:
#include <stdio.h>
#include <stdlib.h>
#pragma pack(push, 1)
typedef struct Pix
{
unsigned char R;
unsigned char G;
unsigned char B;
unsigned char L;
int BW;
}Pix;
#pragma pack(pop)
#pragma pack(push, 1)
typedef struct BitMap
{
short Signature;
long Reserved1;
long Reserved2;
long DataOffSet;
long Size;
long Width;
long Height;
short Planes;
short BitsPerPixel;
long Compression;
long SizeImage;
long XPixelsPreMeter;
long YPixelsPreMeter;
long ColorsUsed;
long ColorsImportant;
struct Pix *pixels;
}BitMap;
#pragma pack(pop)
int main(int argc, char **argv)
{
unsigned long int i=0;
unsigned long int S=0;
struct BitMap source_info;
struct Pix source_pix;
FILE *fp;
FILE *Dfp;
fp=fopen("in.bmp","rb");
if (fp==NULL)
{
fputs("File error:", stderr);
exit(1);
}
Dfp=fopen("out.bmp","wb");
//I think maybe in this line is the problem:
fread(&source_info, sizeof(source_info),1,fp);
S=source_info.Width*source_info.Height;
source_info.pixels = (struct Pix *) malloc(sizeof(struct Pix)*S);
for(i=1;i<=S;i++)
{
//read pixel from the source file
fread(&source_pix,sizeof(struct Pix),1,fp);
source_info.pixels[i-1] = source_pix;
}
fwrite(&source_info, sizeof(BitMap),1,Dfp);
// write pixels to destination file
for(i=1;i<=S;i++)
{
fwrite(&source_info.pixels[i-1],sizeof(struct Pix),1,Dfp);
}
fclose(fp);
fclose(Dfp);
return 0;
}
You are not using fixed size types between architectures. For example on a 32-bit platform long is 32 bit, but on 64-bit long is 64 bit, which is why on a 64-bit platform it can not read the headers correctly. The solution is to use the defines in stdint.
#include <stdint.h>
#pragma pack(push, 1)
typedef struct Pix
{
uint8_t R, G, B;
int32_t BW;
}
Pix;
typedef struct BitMap
{
int16_t Signature;
int32_t Reserved1;
int32_t Reserved2;
int32_t DataOffSet;
int32_t Size;
int32_t Width;
int32_t Height;
int16_t Planes;
int16_t BitsPerPixel;
int32_t Compression;
int32_t SizeImage;
int32_t XPixelsPreMeter;
int32_t YPixelsPreMeter;
int32_t ColorsUsed;
int32_t ColorsImportant;
struct Pix *pixels;
}
BitMap;
#pragma pack(pop)

cast of a structure into another one to get specific data

I have this structure representing a generic message
typedef struct {
uint16_t length;
uint8_t type1;
uint8_t type2;
uint8_t *data;
} generic_msg_t;
After reading type1 and type 2 I can know to which specific message it corresponds, for example this one:
typedef struct {
uint16_t length;
uint8_t type1;
uint8_t type2;
uint16_t a;
uint8_t b;
uint8_t c;
double d;
double e;
double f;
double g;
double h;
uint8_t i;
} specific_msg_t;
Supposing msg contains verified data, I would like to understand why if I do this I can not access to d, e, f, g, h data (but well a, b, c)
specific_msg_t * specific_msg = (specific_msg_t *) msg;
uint16_t a = specific_msg->a; //OK
double d = specific_msg->d; //NOK`
I have to do instead:
unsigned char * buffer = (unsigned char *) msg;
double d = buffer[15] + (buffer[14] << 8) + (buffer[13] << 16) + (buffer[12] << 24) + (buffer[11] << 32) + (buffer[10] << 40) + (buffer[9] << 48) + (buffer[8] << 56);`
specific_msg_t has potentially different alignment requirements than generic_msg_t so on some architectures, that code could result in a crash - the compiler has no particular requirement to align a generic_msg_t object on a boundary suitable for accessing a double.
It would help to know exactly what error you're getting though.
As long as the sender and receiver use the same headers (uint16_t is the same for both of them) and both of them use the same architecture (e.g. x86 or whatever) there shouldn't be too many problems.
I would also define a union with all the specific message types that you need, in order to avoid those nasty calculations and most of the casts.
Something similar to this:
typedef struct {
uint16_t length;
uint8_t type1;
uint8_t type2;
// whatever you need here...
double a;
float b;
// etc.
} specific_msg_t1;
typedef struct {
uint16_t length;
uint8_t type1;
uint8_t type2;
uint16_t a;
uint8_t b;
uint8_t c;
double d;
double e;
double f;
double g;
double h;
uint8_t i;
} specific_msg_t2;
typedef struct
{
uint16_t length;
uint8_t type1;
uint8_t type2;
} selector_msg_t;
typedef union
{
selector_msg_t selector;
specific_msg_t1 msgtype1;
specific_msg_t2 msgtype2;
} message_type_t;
With this setup you could be sending messages of type "message_type_t". Use the member "selector" to decide which specific type of message you received and then use the appropriate specific type to read the different data members.
If the size difference is considerable between the specific types, then it is a bad idea, but if you're not limited by bandwidth then it's at least readable and not that error prone.

How to break struct members into bytes of a single word

Say I have a C structure like:
typedef struct {
UINT8 nRow;
UINT8 nCol;
UINT16 nData; } tempStruct;
Is there a way to put all of those 3 members of the struct into a single 32-bit word, yet still be able to access them individually?
Something with the help of unions?
typedef struct {
UINT8 nRow;
UINT8 nCol;
UINT16 nData;
}
tempStruct;
typedef union {
tempStruct myStruct;
UINT32 myWord;
} stuff;
Or even better (with no "intermediate" struct):
#include <stdlib.h>
#include <stdio.h>
typedef union {
struct {
int nRow:8;
int nCol:8;
int nData:16;
};
int myWord;
} stuff;
int main(int args, char** argv){
stuff a;
a.myWord=0;
a.nCol=2;
printf("%d\n", a.myWord);
return 0;
}
What about just referring to it as a UINT32? It's not like C is type-safe.
tempStruct t;
t.nRow = 0x01;
t.nCol = 0x02;
t.nData = 0x04;
//put a reference to the struct as a pointer to a UINT32
UINT32* word = (UINT32 *) &t;
printf("%x", *word);
You can then get the value of the struct as a 32-bit word by dereferencing the pointer. The specifics of your system may matter, though...if I run this on my machine, the value of word is 0x00040201---that is, the fields are in reverse order. I don't think that's necessarily going to be the case if you're trying to serialize this to another system, so it's not portable.
If you want to actually store it as a 32-bit integer and then refer to the fields individually, why not
UINT32 word = 0x01020004;
and then somewhere else...
UINT8* row(UINT32 word) {
return (UINT8 *) &word + 3;
}
UINT8* col(UINT32 word) {
return ((UINT8 *) &word) + 2;
}
UINT16* data(UINT32 word) {
return ((UINT16 *) &word);
}
Macros will facilitate portable endianness.
Yes, you can use bit fields in C to do that. Something like:
typedef struct {
unsigned nRow : 8;
unsigned nCol : 8;
unsigned nData : 16;
} tempStruct;
If you want to control the memory layout also, you might want to take a look at #pragma pack. A non-portable option available on some compilers for this.
typedef struct {
int nRow:8;
int nCol:8;
int nData:16; } tempStruct;
nRow will take only 8 bit and nCol will take 8 bit and nDate will take 16bit.
This will work for you.
I just wrote sample program to see the size of it
#include<stdio.h>
typedef struct {
int nRow:8;
int nCol:8;
int nData:16; } tempStruct;
typedef struct {
int nRow;
int nCol;
int nData; } tempStructZ;
int main(void) {
printf("%d\n", sizeof(tempStruct));
printf("%d\n", sizeof(tempStructZ));
return 0;
}
Output:
4
16

Casting struct into int

Is there a clean way of casting a struct into an uint64_t or any other int, given that struct in <= to the sizeof int?
The only thing I can think of is only an 'ok' solution - to use unions. However I have never been fond of them.
Let me add a code snippet to clarify:
typedef struct {
uint8_t field: 5;
uint8_t field2: 4;
/* and so on... */
}some_struct_t;
some_struct_t some_struct;
//init struct here
uint32_t register;
Now how do i cast some_struct to capture its bits order in uint32_t register.
Hope that makes it a bit clearer.
I've just hit the same problem, and I solved it with a union like this:
typedef union {
struct {
uint8_t field: 5;
uint8_t field2: 4;
/* and so on... */
} fields;
uint32_t bits;
} some_struct_t;
/* cast from uint32_t x */
some_struct_t mystruct = { .bits = x };
/* cast to uint32_t */
uint32_t x = mystruct.bits;
HTH,
Alex
A non-portable solution:
struct smallst {
int a;
char b;
};
void make_uint64_t(struct smallst *ps, uint64_t *pi) {
memcpy(pi, ps, sizeof(struct smallst));
}
You may face problems if you, for example, pack the struct on a little-endian machine and unpack it on a big-endian machine.
you can use pointers and it will be easy
for example:
struct s {
int a:8;
int b:4;
int c:4;
int d:8;
int e:8; }* st;
st->b = 0x8;
st->c = 1;
int *struct_as_int = st;
hope it helps
You can cast object's pointer to desired type and then resolve it. I assume it can be a little bit slower than using unions or something else. But this does not require additional actions and can be used in place.
Short answer:
*(uint16_t *)&my_struct
Example:
#include <stdio.h>
#include <stdint.h>
typedef struct {
uint8_t field1;
uint8_t field2;
} MyStruct;
int main() {
MyStruct my_struct = {0xFA, 0x7D};
uint16_t num_my_struct = *(uint16_t *)&my_struct;
printf("%X \n", num_my_struct); // 7DFA
return 0;
}

Resources