Solved

bit operation

Posted on 2003-12-10
13
512 Views
Last Modified: 2010-04-15
I would like to read a file which consists of binary.
eg. The following are sequentially stored in a binary file.
1011 0001 1110 0100
1110 1111 0001 0000
0000 0110 1011 1000
0111 1000 1111 1100
0110 0000 1101 0000
1111 1001 1000 0100
0001 0001 0110 1000
0000 1110 1011 1000
1011 0001 0001 1100
0110 0110 1011 0100
1100 1010 1000 1000
0011 0010 0110 0000
.........
........
I read each byte (line by line horizontally)from the binary file. Then I have to store the bit line by line vertically to form each byte. In other words, every 2 bytes read I get the first bit. When I obtain 2 bytes, I store the second bit of the bytes read. After the 16x16 bits are manipulated, I repeat the same thing for the following 16x16 bits.
(in brief, the bits are originally scanned line by line horizontally, I need to scan line by line vertically and store the bytes in another file or array. That means I can get a bit every 16 bit within 16x16 bits, how to store so many things?)
To represent something, there are 13 bits horizontally and 14 bits vertically, last 2 columes in the file are zero-padded to form complete byte. To convert, 2 zero-bits should be inserted vertically before obtain second column.

Can anyone give help on this? Is there bit operation that can be easily used? Thx.
0
Comment
Question by:najyp
  • 5
  • 3
  • 3
13 Comments
 
LVL 45

Expert Comment

by:Kdo
ID: 9913814
Hi najyp,

This is pretty easy to do, and I'll be glad to show you how it's done.

Is this a homework assignment?

Kent
0
 
LVL 4

Expert Comment

by:dhyanesh
ID: 9914088
Hi najyp,

You will require a two dimensional array. Each byte has to be read. Then you will have to read the byte bit by bit and then store in an array. The vertical counter of the array should be incremented. I cannot post the code yet as you have to clarify whether it is homework or not.

Dhyanesh
0
 
LVL 45

Expert Comment

by:Kdo
ID: 9914115
Hi dhyanesh,

The poster's silence makes this sound like homework.


And the instructions are contradictory.  At first it sounds like he just want to flip a bit array on its diagonal.  After that the instructions get kind of muddled.  :)

Kent
0
 
LVL 4

Expert Comment

by:dhyanesh
ID: 9914371
Kdo,

I agree with you. That is precisely why I did not proceed further

Dhyanesh
0
 

Author Comment

by:najyp
ID: 9934510
It is not a homework as it is not for lecturer. It is just one part of my project. As I stuck in this part so I do other parts these days.
Let me clarify my question.
The project is related to font.
For example,
For the character 'A', I have the given 13(W)x14{H} pixels to represent it. (1 bit represent 1 pixel.)
So it maybe like this:
0000001100000
0000011110000
0000110001100
0001100000110
0011111111111
:
:
In a file, it contains many characters: ABCDEF.........and each character is represented by above to show the font. The characters are stored in a binary file one by one. For each character, the bytes stored are obtained from scanning horizontally line by line. But 3 zeros are added to each line so there are 2 bytes representing each line. So there are 28 bytes for each character.
So that is the file I read. Now, instead of scanning horizontally each line for each character, I  have to produce a file which contains these characters but the coding is scanning vertically for each character. As vertically there are 14 bits for each character, I have to pad 2 zeros to obtain 2 bytes for each vertical lline. And the last 3 columns should be cut as they are zeros-padded.
So what I have to do is to read the file given, do the conversion, and then print it out to another file.
Hope somebody understand my question.
0
Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

 
LVL 4

Accepted Solution

by:
dhyanesh earned 125 total points
ID: 9937198
Hi

I think I got what you wish to do.

First you have to declare an array of 28 bytes for input. It would be something like:

unsigned char input[28];

Then for output you require 26 bytes which is 2 x 13.

unsigned char output[26];

Then you would require a temporary 2 dimensional array to store the bits as rows and columns as you have given in your example.

int fontarray[13][14];  

You will then have to use 'fread' to read 28 bytes from a file into the array 'input'

fp=fopen("file.txt","rb");

fread(input , sizeof(unsigned char) , 28 , fp);

Thus all the 28 bytes will be stored one after the other in the array input.

Now you will have to take each byte and store in horizontally in the array. So you will have to split each byte into bits and store either a 0 or a 1 in the fontarray. For this you will have to use bit operations.

example of how to do with TWO bytes: (i.e. ONE line in your case)

unsigned char mask = 0x80                        //mask is set to 10000000 to get first bit
int bit;
for(j=0;j<8;j++)
{

    if ( input[i] & mask )                    //here the input byte is logically ANDed with the mask to get the bit
       
         bit = 1;
    else
         bit = 0;

    mask >>= 1;                 //right shift mask by 1 for next bit
 
    fonrarray[i][j] = bit;           //store in the font array
}

mask = 0x80;

for(j=0;j<5;j++)                //Now only for 5 times since last 3 bits are to be dropped
{

    if ( input[i + 1] & mask )                    //here the input byte is logically ANDed with the mask to get the bit
       
         bit = 1;
    else
         bit = 0;

    mask >>= 1;                 //right shift mask by 1 for next bit
 
    fonrarray[i][j + 8] = bit;           //store in the font array . Also j+8 because you have to store after 8 locations
}

Now you have to repeat this for all the lines i.e. for 14 lines of data.

You now have the data in a 2 D array and have to put it in the array 'output' to write to a file.

Again you will require bitiwise operations. Bit by bit will have to be set for each byte. It is quite similar to above.

Example for TWO bytes i.e. ONE column.

unsigned char mask = 0x80                        //mask is set to 10000000 to get first bit
output [i]  = 0;                                              //Here remember output[i] should be set to 0
for(j=0;j<8;j++)
{

    if (fontarray [j] [i] )                   //Note the array indices are reversed to transpose the matrix
       
         output[i] = output[i] | mask;            //Logical OR is used to set a bit in position pointed by mask

    mask >>= 1;                 //right shift mask by 1 for next bit
 
}

mask = 0x80;

for(j=0;j<6;j++)                //Now  for 6 times since last 2 bits are to be dropped
{
                                                        // j +8 used because next 8 bits are to be considered
    if (fontarray [j + 8] [i] )                   //Note the array indices are reversed to transpose the matrix
       
         output[i + 1] = output[i + 1] | mask;            //Logical OR is used to set a bit in position pointed by mask
                                                                             //Also i + 1 used since we have to store in next location
    mask >>= 1;                 //right shift mask by 1 for next bit
}

Thus now you have the output array ready and now can write this to the output file using fwrite

Like:

fpout=fopen("out.txt","wb");

fwrite(output , sizeof(unsigned char) , 28 , fpout);

This will be process for ONE character. You will have to continuosly repeat the process using a loop until the end of file.

Dhyanesh
0
 
LVL 45

Expert Comment

by:Kdo
ID: 9937536
Hi najyp,

I understand the question differently than does Dhyanesh.  I'm envisioning that you have a 16 word array of 16-bit integers and that you want to flip the bit contents of the 16x16-bit array on the diagonal.  The array is to be generated from the data in your input file.

FILE *InputFile;

main ()
{
  int BitTable[16];

  InputFile = fopen (FileName, "r");
  if (InvertBytes (InputFile, BitTable))
  // Do something with the table
  fclose (InputFile);
}

/*  returns 0 if illegal input  */
int InvertBytes (FILE *file, int BitTable[])
{  
  int    LineNumber;
  int    BitNumber;
  int    BitMask;
  char   *Cp;
  char   InputBuffer[50];  // Must be at least 21 characters to hold the bit representations, eol character and zero terminator.

  memset (BitTable, 0, sizeof (int) * 16);
  BitMask = 0x8000;
  for (LineNumber = 0; LineNumber < 16; ++LineNumber)
  {
    fgets (InputBuffer, 50, InputFile);
    if (feof (InputFile))  /* not enough lines in the file  */
      return 0;
    BitNumber = 0;
    Cp = InputBuffer;
    while (*Cp)
    {
      if ((*Cp) == '0' || (*Cp) == '1')
      {
        if (BitNumber > 15)
        {
          fprintf (stderr, "extra binary digits on line: %s", InputBuffer);
          return 0;
        }
        if (*Cp == '1')
          BitTable[BitNumber++] |= BitMask;
      }
      else if (*Cp != ' ' *Cp != '\t' && *Cp != '\r' && *Cp != '\r')
      {
        fprintf (stderr, "illegal character '%c' on line: %s", *Cp, InputBuffer);
        return 0;
      }
      Cp++;
    }
    BitMask >>= 1;
  }
  return 1;
}


This code will build the BitTable by rotating the horizontal description of each bit into its vertical location.


Kent
0
 

Author Comment

by:najyp
ID: 9943188
Thanks experts!
I think Dhyanesh's answer is quite match with my question.

Dhyanesh, is that " int fontarray[13][14] "should be "fontarray [14][13]"?

I would like to ask further that apart from bit conversion, if I would like to rearrange the order of the characters from the read file, and output to another file, how that can be done? As each character is represented by 28 bytes, how to rearrange/move every 28 bytes? For example, I would like to rearrange the characters in their unicode order.(the sequence of the characters is given and I know their unicode)

Thx a lot.
0
 
LVL 4

Expert Comment

by:dhyanesh
ID: 9949316
najyp,

Yes you are right. An error on my part. It should be "fontarray[14][13]".

Also for reading groups of 28 bytes you will have to use the same logic I explained above. However since you wish to rearrange I think it would be better if you store them all an array.

Again your array would be something like:

unsigned char input[SIZE][28];

Here SIZE is the number of characters in the file. If you do not know this number then you will have to use a linked list to store the characters. Or you can count no. of bytes in the file and find number of characters. However here you would require dynamic memory allocation.

Then you repeat this statement for SIZE number of times to read them in 'input'.

fread(input[i] , sizeof(unsigned char) , 28 , fp);

Now you can rearrange the characters and output them using fwrite.

Dhyanesh
0
 

Author Comment

by:najyp
ID: 9950829
my problem is how to rearrage the characters? How to do the comparison if I want to arrange the character in some order such as unicode order? How to sort the chunks of 28 bytes? Is there any function to be called?
0
 
LVL 4

Expert Comment

by:dhyanesh
ID: 9963403
najyp,

You have posted above that the sequence of characters is known. Could you please post the sequence?

Even though I do not think that there is any direct function to be called. It all depends on the sequence given in the file and the order to which you wish to convert into.

If there is a relation between the two orders then it will be easier.

Dhyanesh
0

Featured Post

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
The goal of this video is to provide viewers with basic examples to understand recursion in the C programming language.
The goal of this video is to provide viewers with basic examples to understand how to create, access, and change arrays in the C programming language.

746 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

8 Experts available now in Live!

Get 1:1 Help Now