convert image to bitstream (binary digits)

xero43's Avatar, Join Date: Oct 2009
Light Poster
Hi all,
I'm an engineering student from Italy and i'd be very glad if you help me in solving a very big problem.
First of all, i'm not expert at all in programming so, please don't insult me if i write something stupid
I'm doing my research thesis regarding optimal trasmission of image from a deep-space link; in order to do this i have to compress a raw image 8 bitperpixel (that is a matrix composed by numbers,no header, whose values go from 0 to 255) in an other format, in particular in JPEG2000, that is a .jpc file. This format has is own header, but we're not interested in this right now.
After the compression i have to protect the image witha parity check coder, in particular a LDPC coder. This coder already exist, and the problem is that, in input, it ONLY accepts a text file composed by a stream of '0' an '1', that is a bitstream.
The only way to make my testbed works is to take the jpc image, composed by a complex header and by data image, convert it into a bitstream, so in a binary stream composed only by '0' and '1' and save it in a text file.
is this problem solvable?? i'm desperate!
please somebody help me!
thank you all.

p.s. i posted this thread in the c++ topics because it's the only language that i know, but if anyone has other ideas, it would be very welcome.

Francesco
0
xpi0t0s's Avatar, Join Date: Aug 2004
Mentor
Yes, it's quite easy to do in C++, just read the file one character at a time, each will be 8 bits, and then you loop over each bit testing if it's 1 or not, and output '1' or '0' accordingly. Here's a simple function to convert a text string to binary:
Code:
void conv1010()
{
	char *str="abc";
	for (int i=0; str[i]; i++)
	{
		char c=str[i];
		for (unsigned char bitmask=0x80; bitmask; bitmask>>=1)
		{
			putchar((c & bitmask) ? '1' : '0');
		}
		putchar(' ');
	}
	putchar('\n');
}
To convert this for your needs, read characters from the .jpc file instead of str (fgetc()), and output (fputc()) the 1s and 0s to the file to be encoded with LDPC. The spaces and newline are just there to make the screen output clearer; you wouldn't output these. You'll need fopen and fclose as well.
0
xero43's Avatar, Join Date: Oct 2009
Light Poster
thank you very much,
sorry but i was abroad and i couldn't answer.
can you write the example with the fgetc() and fputc() functions please?
assume that i have to read e.g. a file called "image.jpc", so how should i change the program? thanks a lot,
francesco.

noreover, do i have to verify if the "image.jpc" is coded with the big or little endian mode?
because if i wrong, i think that the content of the file can be misled
0
xpi0t0s's Avatar, Join Date: Aug 2004
Mentor
No, you can do that; it's easy enough. If you get stuck post what you've got and we'll give you a hint how to continue. Start by RTFM to understand how the functions work.

I don't know if endianness will make any difference, but you'll need to check if the LDPC coder takes that into account.
0
xero43's Avatar, Join Date: Oct 2009
Light Poster
hi,
i made some progress but i need your help again; i post the code that i wrote but before to do that, i wanted to
verify that the results were good, so i opened some file jpc, but also raw (that is the original image without any header) with an hex editor, where i could see the values of the byte written in hexadecimal format.
Code:
#include <stdio.h>

void ShowByte( char b , FILE * im)
{    
    
    for(int i = 7; i >= 0; --i)
    {
        if ( b & (1 << i) )
        {
              fputc('1', im);
        }
        else
        {
              fputc('0', im);
        }
    
    }
  
}

int main ()
{
  FILE * pFile;
  FILE * image;
  char c;
  pFile=fopen ("image.raw","r");
  image=fopen ("bitstream.txt","w");
  if (pFile==NULL) perror ("Error opening file");
  else
  {

    do {
      c = fgetc (pFile); 
      ShowByte(c, image);
    
    } while (c != EOF);
	    
	fclose (pFile);
     
  }
  return 0;
}
first thing strange (for me): if i declare the variable c as an unsigned char and if in the function ShowByte i declare b as unsigned char, the program never stops (infinite loop?)

secondly: i compare a very big file of 1 MB called image.raw and it seems that the program works, but the file txt generated (4 MB) contains less bytes than the original; the program i wrote cut a very huge amount data at some point that i cannot find.
for example, i create a file with 20 random values with an hex editor, and my program print (correctly) only the first 7 bytes of this file.

finally, if i use in input the file that i have to test, the image.jpc file, my program prints only the first byte!!

please can somebody help me??

Last edited by shabbir; 12Oct2009 at 17:33.. Reason: Code blocks
0
xpi0t0s's Avatar, Join Date: Aug 2004
Mentor
EOF is an integer and is equal to -1. So if c is unsigned char, when you read at EOF it will be set to 0xff, which when upcast to an integer for the comparison with EOF will be converted to 0x000000ff and so the comparison will never evaluate FALSE, hence the infinite loop. However, when it is a (signed) char, upcasting 0xff will be sign-extended and result in 0xffffffff, which will equal EOF.

At a guess, the program bails out when it encounters an 0xff character, which is not the same thing as EOF. So it's better to use the feof() function that tests whether or not you are really at the end of the file.

Also as the file is binary you should open it in mode "rb" otherwise it defaults to text-mode, which means you might get some funky (and unwanted) conversions with values 10 and 13.
0
xero43's Avatar, Join Date: Oct 2009
Light Poster
ok i solved with this code:
Code:
#include <stdio.h>

void ShowByte( char b , FILE * im)
{    
    
    for(int i = 7; i >= 0; --i)
    {
        if ( b & (1 << i) )
        {
              fputc('1', im);
        }
        else
        {
              fputc('0', im);
        }
    
    }

}

int main ()
{
  FILE * pFile;
  FILE * image;
  int c;
  pFile=fopen ("image.jpc","r");
  image=fopen ("bitstream.txt","w");
  if (pFile==NULL) perror ("Error opening file");
  else
  {
    
      c = fgetc(pFile); 
      while (c != EOF)
    {
              ShowByte((char)c, image);
         c = fgetc(pFile); 
    
    } 
        }
    fclose (pFile);
        fclose (image);
  
  return 0;
}

now it works perfectly!
but i have the dual problem now, and so, starting from text, recover the jpc file.
i tried with this code but i get a segmentation fault:
#include <stdio.h>

// text points to 8 bytes string containing 0 and 1 symbols

unsigned char ByteFromText(char* text, FILE * im)
{
    unsigned char result = 0;
    for (int i = 0; i < 8; i++)
    {
        if (text[i] == '1') 
        {
             result &= ( 1 << (7-i) );
         fputc(result, im);
        }
    }
    return result;
}



int main ()
{
  FILE * pFile;
  FILE * image;
  int c;
  pFile=fopen ("bitstream.txt","r");
  image=fopen ("image.jpc","w");
  if (pFile==NULL) perror ("Error opening file");
  else
  {
    
      c = fgetc(pFile); 
      while (c != EOF)
    {
              ByteFromText((char*)c, image);
         c = fgetc(pFile); 
    
    } 
        }
    fclose (pFile);
        fclose (image);

  
  return 0;
}
any suggestions? thanks,
Fra

Last edited by shabbir; 12Oct2009 at 19:45.. Reason: Code blocks
0
xpi0t0s's Avatar, Join Date: Aug 2004
Mentor
Please use code blocks when you post code.

What happens if you don't use a cast?
How many characters does fgetc return from the file?
0
xero43's Avatar, Join Date: Oct 2009
Light Poster
ok, if i don't use a cast, i modify the main in this way:
Code:
int main ()
{
  FILE * pFile;
  FILE * image;
  int c;
  pFile=fopen ("bitstream.txt","r");
  image=fopen ("image.jpc","w");
  if (pFile==NULL) perror ("Error opening file");
  else
  {
    
      c = fgetc(pFile); 

      while (c != EOF)
    {
              ByteFromText(c, image);
         c = fgetc(pFile); 
    
    } 
        }
    fclose (pFile);
        fclose (image);

  
  return 0;
}
and the program doesn't compile. g++ outputs this message:

error: invalid conversion from ‘int’ to ‘char*’
error: initializing argument 1 of ‘char ByteFromText(char*, FILE*)’.

concerning the result of fgetc, i don't know how to answer
how can i measure the number of characters output? the only thing i can see is that a file named image.jpc empty is generated
0
xpi0t0s's Avatar, Join Date: Aug 2004
Mentor
OK. fgetc() returns a single char from the file. It does not return a string, and you cannot cast a char to a char*. Casts are tricky business, and you shouldn't use them unless you know EXACTLY what you're doing. If the compiler complains then there's a good chance that a cast won't fix the problem, or will create a new problem or make the problem worse (in this case, it changes a compiler error to a program crash).

ByteFromText seems OK, but what you need to do is read 8 characters from the file before calling it. Put those characters into a temporary buffer that is at least 9 bytes long, add a NULL terminator (a zero byte), and call ByteFromText with the buffer.