Thread: Bitunwise

  1. #1
    Registered User Azmeos's Avatar
    Join Date
    Jun 2003
    Posts
    65

    Bitunwise

    I'm trying read a bitonal image and then test each bit to see if it is 0 or 255 (black or white). I am able to do grayscale and RGB images, but bitonal images seem to be posing a difficulty to me. I know I can only access the byte, so then I must advance through each bit to check what the value is. That's where I get lost. Any help as to how to check this?
    \0

  2. #2
    pronounced 'fib' FillYourBrain's Avatar
    Join Date
    Aug 2002
    Posts
    2,297
    I think you're trying to test a single bit in a byte, correct? if so you do it as follows:

    if( thebyte & flag )
    //do stuff

    where flag could be one of the following:

    #define BIT1 0x01
    #define BIT2 0x02
    #define BIT3 0x04
    #define BIT4 0x08
    #define BIT5 0x10
    #define BIT6 0x20
    #define BIT7 0x40
    #define BIT8 0x80
    "You are stupid! You are stupid! Oh, and don't forget, you are STUPID!" - Dexter

  3. #3
    Registered User
    Join Date
    Nov 2001
    Posts
    1,348
    There are several solutions. One solution is to loop through each bit and analyze it via AND operator. Another solution is to shift each bit and compare it to a value.

    Kuphryn

  4. #4
    Registered User Azmeos's Avatar
    Join Date
    Jun 2003
    Posts
    65
    I think I tried that, but wouldn't it be backwards because of the most sig. bit being at the beginning?
    \0

  5. #5
    pronounced 'fib' FillYourBrain's Avatar
    Join Date
    Aug 2002
    Posts
    2,297
    backwards? my #define names were arbitrary. you can reverse them if you like.

    but yes, for your purposes the 0x80 bit comes first
    "You are stupid! You are stupid! Oh, and don't forget, you are STUPID!" - Dexter

  6. #6
    pronounced 'fib' FillYourBrain's Avatar
    Join Date
    Aug 2002
    Posts
    2,297
    here:

    Code:
         const unsigned char bit[] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
    
         for(int i=0; i < numbytes; i++)
            {
            char c = bytes[i];
            for(int j=0; j < 8; j++)
               {
               if(c & bit[j])
                  {
                  // do something cause the bit is true
                  }
               }
            }
    Last edited by FillYourBrain; 07-07-2003 at 09:56 AM.
    "You are stupid! You are stupid! Oh, and don't forget, you are STUPID!" - Dexter

  7. #7
    Registered User Azmeos's Avatar
    Join Date
    Jun 2003
    Posts
    65
    Hmm... here is my code, maybe you can tell me what I'm doing wrong. (cleaned/moved for easier viewing) I have more in case this is not sufficient.

    Note: pCurr is the image buffer (data holder)

    Code:
    unsigned char mask[] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
    
    		for (int i = 0; i < (imageWidth * imageLength) ; i++) {
    				
    			for (int j = 0; j < 8; j++) {
    				if (samplesPerPixel == 1) {
    					if ((mask[j] & pCurr[i]) == 0)
    						value = 19;
    					else
    						value = ' ';
    					
    					if ((i % imageWidth) == 1) ret = '\n';
    						else ret = 0;
    					cout << value << ret;
    				}
    				else {
    
    					for (int j = 0; j < samplesPerPixel; j++) {
    						value = (int) pCurr[i * samplesPerPixel + j];
    						cout << value << " ";
    					}
    				}
    			}
    		}
    Last edited by Azmeos; 07-07-2003 at 10:08 AM.
    \0

  8. #8
    pronounced 'fib' FillYourBrain's Avatar
    Join Date
    Aug 2002
    Posts
    2,297
    often, bitmaps are stored with "padding" at the end of each scanline. You may be padded to the nearest byte, sometimes the padding is to the nearest long. what kind of results are you seeing? if it's a slanted version of the original I would suggest that not accounting for the padding is the reason.
    "You are stupid! You are stupid! Oh, and don't forget, you are STUPID!" - Dexter

  9. #9
    Registered User Azmeos's Avatar
    Join Date
    Jun 2003
    Posts
    65
    It's actually a TIFF file that I'm reading, but it might seem slanty... I'm outputting it with exclaimation marks and spaces just to see if it comes close, and I can't tell if it's slanty ... just seems to be wrong, mostly because the top part should be all white and it has quite a few !s and spaces intermixed. So I don't think it's with the padding. If you want to see my reading of the image... here it is:

    Code:
    	  for (stripCount = 0; stripCount < stripMax; stripCount++){
    		if((result = TIFFReadEncodedStrip (tif, stripCount,
    				  buf + imageOffset,
    				  stripSize)) == -1){
    		  fprintf(stderr, "Read error on input strip number %d\n", stripCount);
    		  exit(42);
    		}
    
    		imageOffset += result;
    	  }
    However, I am pretty sure this is correct. I have checked with a few online sources and they seems to concurr.
    \0

  10. #10
    pronounced 'fib' FillYourBrain's Avatar
    Join Date
    Aug 2002
    Posts
    2,297
    ok, my knowledge of tiff is limited. tiff does use a form of run-length encoding though. in the y direction as well if I'm not mistaken. you'll have to look at RLE and probably the tiff specs to get that one figured out. often there is some sort of code that represents the start of a "run" that you have to look for. I'm sure you'll find that the size you expect the image to take up is bigger than the actual file size.
    "You are stupid! You are stupid! Oh, and don't forget, you are STUPID!" - Dexter

  11. #11
    Registered User Azmeos's Avatar
    Join Date
    Jun 2003
    Posts
    65
    The TIFF may read in the Y direction, but there is no Y direction when reading from memory. Both the RGB and Grayscale work with my reading and outputting. Bitonal works with reading, but I think it is the outputting that is causing the trouble.
    \0

  12. #12
    pronounced 'fib' FillYourBrain's Avatar
    Join Date
    Aug 2002
    Posts
    2,297
    what I'm saying is RLE is compression. you have to decompress. It basically tells you that you are repeating a color for n-number of times. This way it can store a whole line of color in just a couple bytes. When I said Y direction I was referring to RLE in that direction. I don't know for sure that is what they're doing. Regardless, if you are getting non-white colors in the first line as you said then I submit that you are reading RLE data as if it is unencoded. That's about all I can tell you.
    "You are stupid! You are stupid! Oh, and don't forget, you are STUPID!" - Dexter

  13. #13
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    WOTSIT.ORG has info on the TIFF format if you need it.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  14. #14
    Registered User Azmeos's Avatar
    Join Date
    Jun 2003
    Posts
    65
    I tried writing a small test program with your code, and I'm getting EVERYTHING as true. Here is the code:
    Code:
    int bitonal() {
    	uint32 imageWidth, imageLength;
    	int stripMax, stripCount;
    	unsigned long imageOffset, result, bufferSize;
    	tsize_t stripSize;
    
    	char* fileName = "28.tif";
        TIFF* tif = TIFFOpen(fileName, "r");
    
        if (tif) {
    
    		TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &imageWidth);
    		TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &imageLength);
    		
    		m_memoryWidth = (imageWidth + (1/2)) / 8;
    		m_memoryLength = imageLength;
    
    		// Read in the possibly multiple strips
    		stripSize = TIFFStripSize(tif);
    		stripMax = TIFFNumberOfStrips(tif);
    		imageOffset = 0;
      
    		bufferSize = m_memoryWidth * m_memoryLength;
    		m_bufferSize = bufferSize;
    		
    		unsigned char* buf = new unsigned char[bufferSize];
    
    		const unsigned char bit[] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
    
    		for (stripCount = 0; stripCount < stripMax; stripCount++){
    			if((result = TIFFReadEncodedStrip (tif, stripCount,
    				buf + imageOffset,
    				stripSize)) == -1){
    				fprintf(stderr, "Read error on input strip number %d\n", stripCount);
    				exit(42);
    			}
    
    			imageOffset += result;
    		}
    
    		 for(int i=0; i < (imageWidth * imageLength); i++)
    			{
    			char c = buf[i];
    			for(int j=0; j < 8; j++)
    			   {
    			   if(c & bit[j])
    				  {
    				  cout << "!";
    				  }
    			   else {
    				   cout << "";
    			   }
    			}
    		 }
    	}
    	return 0;
    }
    And I have uploaded the image I am working with.
    Last edited by Azmeos; 07-07-2003 at 12:33 PM.
    \0

  15. #15
    pronounced 'fib' FillYourBrain's Avatar
    Join Date
    Aug 2002
    Posts
    2,297
    the only thing you're outputting is an exclamation. the false case is outputting an empty string.
    "You are stupid! You are stupid! Oh, and don't forget, you are STUPID!" - Dexter

Popular pages Recent additions subscribe to a feed