Yes. Well I am a bit tired as well as not a native speaker and it is a bit hard for me to understand posters here as they are usually not native speakers too so I lost for a moment why is he now using unsigned char. But I got to sleep anyway. I guess I will find out that tomorrow.
The code worked when I needed get number of header offset. It was small number. So when tried to load bigger numbers greater then 255 so it did not work. I am not sure if there is not some other problem. For example planes should be 1 and not 8 so I am not sure if the error is in the conversion or elsewhere.
Are you sure that you're reading everything in the right order?
But your read*Bytes() functions are wrong, you don't need those ambersands(&) in there.
Devoted my life to programming...
Thanks for the notice. I removed the ampersands from within the functions and most of the numbers are correct not. At least bitmap size and width and height is correct. I must find why planes and palColors are not correct.
If you're still using post #10, then it's wrong.
&item is a pointer to the parameter, not what it points to.
Also, passing the 2 or 4 byte buffer n seems a waste of effort, unless you use the result elsewhere.
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
If at first you don't succeed, try writing your phone number on the exam paper.
Good notice, I fixed both functions. Now all values are fine. Thanks
Notice:
When I declare local variable
is this declared every time when function is called? Maybe better useCode:unsigned char n[4];
?Code:static unsigned char n[4];
Last edited by barracuda; 02-12-2015 at 04:11 AM.
I have found this
I expect that it converts uint32_t to little endian. Author of this code uses it to write data to binary file.Code:#define UINT16_SWAP_LE_BE_CONSTANT(val) \ ((uint16_t) \ ( \ (uint16_t) ((uint16_t) (val) >> 8) | \ (uint16_t) ((uint16_t) (val) << 8))) #define UINT32_SWAP_LE_BE_CONSTANT(val) \ ((uint32_t) \ ( \ (((uint32_t) (val) & (uint32_t) 0x000000ffU) << 24) | \ (((uint32_t) (val) & (uint32_t) 0x0000ff00U) << 8) | \ (((uint32_t) (val) & (uint32_t) 0x00ff0000U) >> 8) | \ (((uint32_t) (val) & (uint32_t) 0xff000000U) >> 24)))
> is this declared every time when function is called? Maybe better use
> static unsigned char n[4];
No.
On most machines, creating the local stack frame is a single instruction regardless of the number of local variables.
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
If at first you don't succeed, try writing your phone number on the exam paper.
Could you yet help me how to get first 2 bytes of the bitmap "BM" characters to member char magicNo[2]?
readChars(fp, &bmpfile->header.magicNo, 2);
I tried:
andCode:static int readChars(FILE * fp, char** item, size_t size) { size_t in; char n[size]; in = fread(n, size, 1, fp); memcpy(item,n,size); if (!in) return -2; return in; }
None worksCode:static int readChars(FILE * fp, char** item, size_t size) { size_t in; char n[size]; in = fread(item, size, 1, fp); if (!in) return -2; return in; }
If I delete one star, then I got this message:
note: expected 'char *' but argument is of type 'char (*)[2]'|
Hence is not clear to me how to pass the char array by reference
Last edited by barracuda; 02-12-2015 at 06:50 AM.
> readChars(fp, &bmpfile->header.magicNo, 2);
Drop the &, and all those double stars should be single stars.
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
If at first you don't succeed, try writing your phone number on the exam paper.
Like it goes, we will do your entire project. It looks to me that you are just being lazy not that you actually need help.
But since I am in a mood as well as I have a loooooooong experience with BMPs. I can give you a "tip" as Salem loves to call it.
As a magic identifier it will be poor to use non-magical values at all such as 'B' and 'M'.
This magic identifier is 2 bytes long. So you can declare it as `uint_16` or even better `WORD` which is `unsigned short` and make it a constant, because it isn't really a value you can change.
The 19778 is the magic number that initializes the BMP image.Code:const WORD id = 19778;
All you have to do now, is to write it directly to the bmp stream
Code:fwrite(&id, 1, sizeof id, fp);
But this works only on little endians. On big endians the magic number will be 16973.
A better way is to compare the ID byte by byte.
(not tested, free typed from my head)Code:typedef union int_2byte_t { uint16_t full; uint8_t part[2]; } int_2byte; … int_2byte bmp_id; if (fread(&bmp_id, sizeof(bmp_id), 1, filepointer) != 1) return -1; if (bmp_id.part[0] == 'B' && bmp_id.part[1] == 'M') { /* work with BMP */ } else { fclose(filepointer); return -2; } …
Last edited by WoodSTokk; 02-12-2015 at 09:47 AM.
Other have classes, we are class
That is an awful way. Endianness must be determined in an init function, once.
Leave that aside, any extra and pointless operation performed is not a "better way"..
If by better you mean easier, then no.
If by better you mean faster, then again no.
If by better you mean less error-prone then again... no your way isn't any better.