Read File (possibly image) as binary?

I want to read an image file as binary, then save it again in its binary form, however i am having some problems as i cant seem to get it to read the file as binary.

I have tried this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
	const int charsize = 1000;
	char file [charsize];
	int c = 0 ;
	FILE* fp = NULL;


	fp = fopen("Image.jpg", "r+b");

	fseek(fp, 0L, SEEK_END);
	unsigned long size = ftell(fp);

	if (fp != NULL)
	{
		while ((c < size) && (c < charsize))
		{
			file[c] = fgetc (fp);
			c++;
		}
		file[c] = '/0';
		fclose(fp);
	}


And the output is the funny y, which is -1, and is defiantly not binary :).

Any help will be greatly appreciated.

I am using visual studio 08 as my compiler.
Last edited on
1. You hit the EOF because you never reset the file pointer back to the beginning.
2. You're checking that fp!=NULL after fseek()ing and ftell()ing.
3. Use fread() to read from binary files.
4. Use fstreams if you're using C++.
Ok thanks, but it still is not reading as binary.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
	char file[1000];
	FILE* fp = NULL;

	fp = fopen("Image.jpg", "r+b");

	if (fp != NULL)
	{
		fseek(fp, 0L, SEEK_END);
		unsigned long size = ftell(fp);

		fseek(fp, 0L, SEEK_SET);
		
		fread (file, 1, size, fp);
		fclose(fp);
	}

	fp = fopen ("Image.txt","w");
	if (fp!=NULL)
	{
		fputs (file,fp);
		fclose (fp);
	}


-		file	0x002afa38 "€"	char [1000]
		[0]	-128 '€'	char
		[1]	2 ''	char
		[2]	0	char
		[3]	0	char
		[4]	-32 'à'	char
		[5]	1 ''	char
		[6]	0	char
		[7]	0	char
		[8]	0	char
		[9]	0	char
		[10]	0	char
		[11]	0	char
		[12]	0	char
		[13]	0	char
		[14]	0	char
		[15]	0	char
		[16]	120 'x'	char
		[17]	-6 'ú'	char
		[18]	42 '*'	char
		[19]	0	char
		[20]	66 'B'	char
		[21]	91 '['	char
		[22]	-28 'ä'	char
		[23]	0	char
		[24]	99 'c'	char
		[25]	2 ''	char
		[26]	-54 'Ê'	char
		[27]	87 'W'	char
		[28]	56 '8'	char
		[29]	75 'K'	char
		[30]	116 't'	char
		[31]	1 ''	char
		[32]	0	char
		[33]	0	char

etc
Last edited on
Note that your fopen() flags will open the file even if it didn't already exist. In that case, it will create an empty file. Also, that even though you're reading the file as binary, you're writing it as text. You should limit yourself to fread() and fwrite() when working with binary files.

EDIT: That looks perfectly fine, to me, although it doesn't seem to be a JPEG file.
Oh, one more thing. Line 13 will overflow 'file' if size is >1000.
Last edited on
Oh, one more thing. Line 13 will overflow 'file' if size is >1000.

yeah, i realized that, however the aim was to get it working first (very small jpg image).

although it doesn't seem to be a JPEG file.

Interesting, i saved it using Adobe Photoshop, ill see if theres a different result with Paint.

That looks perfectly fine, to me.

Well, in the output file it says (this weird block which in here is displayed as) ʀ, and so im guessing its null-terminated, or some sort of error.

First 33 chars as a JPG created in Paint:

removed, but very similar to previous one.


Same output: ʀ

[Edit] lol, im using put to write, going to change it to write, mybad.


Its now working, thanks :).

For those searching on google to find the answer, i had to change the saving code to:

1
2
3
4
5
6
fp = fopen ("Image2.jpg","w+b");
	if (fp!=NULL)
	{
		fwrite (file, 1, size, fp);
		fclose (fp);
	}

And now when i open it in opera (or any app that can read images), it shows the image exactly the same.
Last edited on
If I may make an observation, you should use dynamic memory allocation to handle the data buffer. Also, your variable names need a little help (you named your buffer "file"). The following is a little lengthy, but correct. If you are clever, you can make it much shorter. ;-)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
int copy_file( const char* srcfilename, const char* dstfilename )
  {
  long  len;
  char* buf = NULL;
  FILE* fp  = NULL;

  // Open the source file
  fp = fopen( srcfilename, "rb" );
  if (!fp) return 0;

  // Get its length (in bytes)
  if (fseek( fp, 0, SEEK_END ) != 0)  // This should typically succeed
    {                                 // (beware the 2Gb limitation, though)
    fclose( fp );
    return 0;
    }

  len = ftell( fp );
  rewind( fp );

  // Get a buffer big enough to hold it entirely
  buf = (char*)malloc( len );
  if (!buf)
    {
    fclose( fp );
    return 0;
    }

  // Read the entire file into the buffer
  if (!fread( buf, len, 1, fp ))
    {
    free( buf );
    fclose( fp );
    return 0;
    }

  fclose( fp );

  // Open the destination file
  fp = fopen( dstfilename, "wb" );
  if (!fp)
    {
    free( buf );
    return 0;
    }

  // Write the entire buffer to file
  if (!fwrite( buf, len, 1, fp ))
    {
    free( buf );
    fclose( fp );
    return 0;
    }

  // All done -- return success
  fclose( fp );
  free( buf );
  return 1;
  }

Hope this helps.
Thankyou very much, is it possible to save a version which consists only of binary?
isnt the file length better unsigned btw?

'(beware the 2Gb limitation, though)'
Is there any way around that, out of curiosity?

I have tried changing this:

if (!fwrite( (long*)long(buf), len, 1, fp ))
I know chars are already ints, but i want to make the application just save the numbers, so i can manipulate it better. That method just saves it in its normal form with trailing randomness.

Is there any way to save all of the buf data as an int, not english text.


[edit]

Ok, i got it kinda working, but it shows different results each time... lol.

The idea was to convert it from Char to Int
So i tried:
 
long * value = (long*)long(buf);

But it displayed normal text too. Then i tried (which is as far as i have gotton).

1
2
3
4
5
6
7
8
9
	// Write the entire buffer to file
	char * d = (char*)malloc( (unsigned long)buf );
	itoa(long(buf),d,2);
	if (!fwrite( d, len, 1, fp ))
	{
		free( buf );
		fclose( fp );
		return 0;
	}


i realize 2 is binary, and 8 is normal characters, however, it always gives me a different value and i have no idea why. im a bit of a noob with pointers and i did my best to get them to work.
Last edited on
Um, you are making some weird changes. For example, buf is a pointer. So why are you passing it as argument to malloc()?
Is there any way around [the 2 GiB limit], out of curiosity?
Other than using a 64-bit system, a file system library (e.g. Boost::filesystem. Or maybe it was a different one. I know it was possible with Boost), or direct system calls, no.

I agree with Duoas; the code does make any sense. What are you trying to do?
I added comments, but im trying to make it save as either binary, or as a number, not text.

1
2
3
4
5
6
7
8
char * d = (char*)malloc( (unsigned long)buf ); //Make a char which has the size of buf
	itoa(long(buf),d,2); //we then put the binary form of buf into d
	if (!fwrite( d, len, 1, fp )) //we write d
	{
		free( buf );
		fclose( fp );
		return 0;
	}


I do end up with the right result, if i put 2 it writes binary, if i put 8 it writes it as an int, however, the number is always different...
Last edited on
"Binary" has very specific meanings. Don't use it so lightly.
What you're trying to do is write the textual representation of the binary or decimal representation of the character codes. That can be done this way:
1
2
3
4
5
6
7
8
void f(void *buffer,size_t length,std::ofstream &file){
	for (size_t a=0;a<length;a++){
		char c=*(char *)buffer;
		char s[10];
		itoa(c,s,2);
		file.write(s,strlen(s));
	}
}

You were getting different values each time because you were passing the casted pointer to itoa(), not the value pointed to by the pointer.
1
2
3
4
5
6
7
8
void f(void *buffer,size_t length,std::ofstream &file){
	for (size_t a=0;a<length;a++){
		char c=*(char *)buffer;
		char s[10];
		itoa(c,s,2);
		file.write(s,strlen(s));
	}
}

Urm, i dont see how this would work with my code.

file.write is not a valid command? is this for a different library?

Last edited on
Sorry about that. I don't know if you're using C++ or C.
Change the type of file to FILE * and line 6 to fwrite(s,1,strlen(s),file);
Thankyou very much, im using C++.
This is working perfectly, thankyou
sorry for asking...
may i know the final coding?
Topic archived. No new replies allowed.