Why do you want to encrypt only the image data and not the entire file?
Why do you want to encrypt only the image data and not the entire file?
Code://try //{ if (a) do { f( b); } while(1); else do { f(!b); } while(1); //}
So currently my main looks like this
and I have very simple things written under encrypt and decrypt, but when I try running the program, there's an issue with the realloc under readImageCode:int main(int argc, char* argv[]){ FILE* in; Bitmap* map = malloc(sizeof(Bitmap)); if(argc <=3){ printf("Usage: %s [-e] [-d] inputFileName outputFileName\n", argv[0]); return 0; } if((in = fopen(argv[2], "rb")) == NULL){ printf("Input file: %s cannot be opened\n", argv[2]); exit(EXIT_FAILURE); } if(strcmp(argv[1],"-e")== 0){ readImage(argv[2], map); encrypt(map); writeImage(argv[3], map); } else if(strcmp(argv[1],"-d")==0){ readImage(argv[2], map); decrypt(map); writeImage(argv[3], map); } else{ printf("You have not entered valid choices\n"); return 0; } return EXIT_SUCCESS; }
I have done some printf's and it is getting to the realloc correctly, when size is 10,000. I think I am using the realloc function incorrectly then.Code:void readImage(char* infile, Bitmap *bitmap){ int i; FILE* input = fopen(infile, "rb"); char* array = malloc(sizeof(n)); for(i=0; i<n; i++){ fread(&array[i], 1, 1, input); bitmap->size +=1; if((bitmap->size)==n){ array = realloc(array, (2*n)); } } bitmap->header = &array[0]; bitmap->data = &array[54]; fclose(input); }
Also, my writeImage currently looks like this
I'm not sure if that's the correct way I should be passing the data and header back out to a new bitmap file.Code:void writeImage(char* outfile, Bitmap *bitmap){ int i; FILE* output = fopen(outfile, "wb"); for(i=0; i<54; i++){ fwrite(&(bitmap->header[i]), 1, 1, output); } for(i=0; i<((bitmap->size)-54); i++){ fwrite(&(bitmap->data[i]), 1, 1, output); } fclose(output); }
I can think of a couple of reasons:
1 - by preserving the key header information, the result is still a valid BMP file, and thus can be viewed with a normal BMP viewing tool.
2 - if the encryption is "good", the result will just be random dots. However, poor encryption will reveal itself as a vaguely recognisable image.
> I think I am using the realloc function incorrectly then.
Well what is 'n'?
> char* array = malloc(sizeof(n));
int n = 5000;
sizeof(n) is still 4 - probably not what you want.
> array = realloc(array, (2*n));
You also need to increase n as well.
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.
At the top of the program, after the includes, there is
#define n 10000
I have put in some edits, but now there is a compile error regarding the reassigned n value,
n = n*2
error: invalid lvalue in assignment
Is this because n is defined so I can't change it?
Code:void readImage(char* infile, Bitmap *bitmap){ int i; FILE* input = fopen(infile, "rb"); char* array = malloc(n); for(i=0; i<n; i++){ fread(&array[i], 1, 1, input); bitmap->size +=1; if((bitmap->size)==n){ array = realloc(array,(n*2)); n *=2; } } bitmap->header = &array[0]; bitmap->data = &array[54]; fclose(input); }
Last edited by kallistine; 07-26-2009 at 01:35 PM. Reason: new note
Well yes, it needs to be a variable if you intend to modify it's value.
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.
Thanks! The realloc is working correctly now, but it seems to increase indefinitely, is this because there's something wrong with how my fread is working? Is this due to the fact that I lack some sort of break statement when fread has finished reading the file? To prevent the for loop from going on forever? Is there something simliar to fscanf when it reaches EOF? Here is my latest readImage function.
the test image I am using has a size of 270,056 bytes.Code:void readImage(char* infile, Bitmap *bitmap){ int i, nsize = n; FILE* input = fopen(infile, "rb"); char* array = malloc(nsize); for(i=0; i<nsize; i++){ fread(&array[i], 1, 1, input); bitmap->size +=1; if((bitmap->size)==nsize){ nsize *=2; printf("resizing from %d to %d\n", (bitmap->size), nsize); array = realloc(array,nsize); } } bitmap->header = &array[0]; bitmap->data = &array[54]; fclose(input); }
Last edited by kallistine; 07-26-2009 at 01:57 PM. Reason: another point
>> The realloc is working correctly now, but it seems to increase indefinitely, is this because there's something wrong with how my fread is working?
You are using 'nsize' as a loop control variable:
And then once bitmap::size reaches it, you double 'nsize' and so the process continues ad infinitum:Code:for(i=0; i<nsize; i++)
But there's also the issue that 'n' (which initializes 'nsize') doesn't even belong there in the first place. What's the point of guessing the file size? This is the easiest way to do it:Code:if((bitmap->size)==nsize){ nsize *=2; printf("resizing from %d to %d\n", (bitmap->size), nsize); array = realloc(array,nsize); }
Code:fopen file fseek to the end ftell to get the file-size malloc file-size bytes rewind the file pointer fread the entire bitmap *validate* all of the fields in the bitmap header encrypt/decrypt rewind the file pointer fwrite tranformed data to file fclose file free bytes
Code:#include <cmath> #include <complex> bool euler_flip(bool value) { return std::pow ( std::complex<float>(std::exp(1.0)), std::complex<float>(0, 1) * std::complex<float>(std::atan(1.0) *(1 << (value + 2))) ).real() < 0; }
It doesn't look like that is so. Anyway, fread() returns the number of bytes read; at the end, it will read 0, so you can use the return value of fread().
What you might want to do is stat the file or something first to get the exact size of the bmp so you can just malloc the right size buffer. Since the file size is in the header, you can try something like this, which is how you can read most of the header data:
I just tried this and it gives the correct file size for .bmp images. So I would have to say to Sebastiani that this is the easiest way to do it .Code:int main() { FILE *bmp = fopen("some.bmp","rb"); char buffer[54]; int *size; fread(buffer,27,2,bmp); size = (int*)&buffer[2]; /* the offset to the "size" field in the header */ printf("size: %d",*size); /* now try height and width */ size = (int*)&buffer[18]; printf("\nwidth: %d",*size); size = (int*)&buffer[22]; printf("\nheight: %d",*size);
So: you can read in the 54 byte header, determine the size, and then malloc the buffer for *data based on that. The height and width came out correct as well -- not so hard. I just looked at:
http://www.fastgraph.com/help/bmp_header_format.html
Last edited by MK27; 07-26-2009 at 02:32 PM.
C programming resources:
GNU C Function and Macro Index -- glibc reference manual
The C Book -- nice online learner guide
Current ISO draft standard
CCAN -- new CPAN like open source library repository
3 (different) GNU debugger tutorials: #1 -- #2 -- #3
cpwiki -- our wiki on sourceforge
Thanks for all the suggestions but despite my constant resizing being inefficient, it's part of the directions, so I will follow that.
I have inserted
into the for loop to test somethings out, and my outfile bmp file displayed correctly so now I can get working on my a better encryption method and also figure out a better way to break. I can't use '0' to break because some of the RGB values are 0. Any suggestions? Thanks a lot.Code:if((bitmap->size >300000) && (array[i] == 0)){ printf("breaking \n"); break; }
Actually, I think I will get more out of this assignment if I learn how to extract things from the header, I will try to implement what MK27 did. Thanks a lot!
>> I have inserted
Well if you're going to do it incrementally, doesn't it make sense to at least do it the *right* way, and not just some way that randomly happens to work for you right now?
Code:#include <cmath> #include <complex> bool euler_flip(bool value) { return std::pow ( std::complex<float>(std::exp(1.0)), std::complex<float>(0, 1) * std::complex<float>(std::atan(1.0) *(1 << (value + 2))) ).real() < 0; }
>> FILE *bmp = fopen("some.bmp","rb");
It might be a good idea to check the return value there.
>> fread(buffer,27,2,bmp);
Ditto.
>> I just tried this and it gives the correct file size for .bmp images. So I would have to say to Sebastiani that this is the easiest way to do it
And if it's an invalid file and the size is meaningless?
Code:#include <cmath> #include <complex> bool euler_flip(bool value) { return std::pow ( std::complex<float>(std::exp(1.0)), std::complex<float>(0, 1) * std::complex<float>(std::atan(1.0) *(1 << (value + 2))) ).real() < 0; }
C programming resources:
GNU C Function and Macro Index -- glibc reference manual
The C Book -- nice online learner guide
Current ISO draft standard
CCAN -- new CPAN like open source library repository
3 (different) GNU debugger tutorials: #1 -- #2 -- #3
cpwiki -- our wiki on sourceforge
I think you mean:puts("The ship is sunk! Head for the lifeboats!");
exit (666);
puts("Iceberg at 12 o'clock - full speed ahead!");
Code:#include <cmath> #include <complex> bool euler_flip(bool value) { return std::pow ( std::complex<float>(std::exp(1.0)), std::complex<float>(0, 1) * std::complex<float>(std::atan(1.0) *(1 << (value + 2))) ).real() < 0; }