Go4Expert

Go4Expert (http://www.go4expert.com/)
-   C (http://www.go4expert.com/forums/c/)
-   -   convert image to bitstream (binary digits) (http://www.go4expert.com/forums/convert-image-bitstream-binary-digits-t19704/)

xero43 8Oct2009 19:43

convert image to bitstream (binary digits)
 
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

xpi0t0s 9Oct2009 16:21

Re: convert image to bitstream (binary digits)
 
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.

xero43 12Oct2009 03:36

Re: convert image to bitstream (binary digits)
 
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

xpi0t0s 12Oct2009 04:27

Re: convert image to bitstream (binary digits)
 
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.

xero43 12Oct2009 15:39

Re: convert image to bitstream (binary digits)
 
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??

xpi0t0s 12Oct2009 17:54

Re: convert image to bitstream (binary digits)
 
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.

xero43 12Oct2009 18:11

Re: convert image to bitstream (binary digits)
 
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

xpi0t0s 12Oct2009 19:22

Re: convert image to bitstream (binary digits)
 
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?

xero43 12Oct2009 20:13

Re: convert image to bitstream (binary digits)
 
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

xpi0t0s 12Oct2009 22:39

Re: convert image to bitstream (binary digits)
 
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.


All times are GMT +5.5. The time now is 00:42.