The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: BytePtr on April 11, 2012, 11:08:31 PM

Title: Pack one bit into byte or something like that, how?
Post by: BytePtr on April 11, 2012, 11:08:31 PM
Hi.

Let's take simple BYTE (0..255).
And let's say it contains some value like: 30 or even maximum value: 255.
Is it possible to pack one additional byte value into this? AND/OR-ing or whatever the operators are.

In my case, additional values are: 0,1,2,3 and 4. Just one of them.
I need to pack them into this BYTE.

I don't even know if it's possible. I know if i add one more to 255, it's overflow. But if i just AND/OR additional value into it, will this work?
Value probably changes during packing additional stuff into it, but it's okay, if i can retrieve both values, like they were before packing.


Thanks in advance for any help.
Title: Re: Pack one bit into byte or something like that, how?
Post by: jj2007 on April 11, 2012, 11:18:28 PM
You have 8 bits, so you can pack any combination of
1+7
2+6
3+5
4+4

Take 3+5:
00000111=1+2+4=7
00011111=1+2+4+8+16=31
So the max value of the first number is 7, while the second can reach 31.

packing:
mov eax, 6
mov edx, 27
shl edx, 3
add eax, edx

unpacking:
mov edx, eax
and eax, 7
shr edx, 3
Title: Re: Pack one bit into byte or something like that, how?
Post by: dedndave on April 11, 2012, 11:21:37 PM
two ways come to mind

you can pack 3 of em the hard way:
25*N3 + 5*N2 + N1

or 2 of em the easy way
16*N2 + N1

to get really hard, you can pack 22 of em into 7 bytes   :P
Title: Re: Pack one bit into byte or something like that, how?
Post by: BytePtr on April 11, 2012, 11:43:41 PM
Thank you very much for your replies. I will try to make it work and will see how it comes out.
If i will integrate it to my code and it starts working i will let you know.
Title: Re: Pack one bit into byte or something like that, how?
Post by: BytePtr on April 12, 2012, 11:13:44 PM
Thank you once again.
I integrated into my app and it's working just perfectly. Got what i needed.
If you want jj2007 and dedndave i will add you to my app about box.

You helped me many times here.

Thank you both once again.
Title: Re: Pack one bit into byte or something like that, how?
Post by: BytePtr on April 15, 2012, 12:19:34 PM
Ok, seems i encountered some problem.

You said:
"So the max value of the first number is 7, while the second can reach 31."


I got that limit of 31 when packed the stuff, without packing additional stuff into the X (0..255) i got correct results. To the end.
What is wrong?
So if i have variable X with maximum value over 31, i can't pack anything to it anymore?

In my another test app, the stuff worked correctly until i packed the 0,1,2,3 or 4 into it.
Then it limited to 31 and then started again from 0.


Title: Re: Pack one bit into byte or something like that, how?
Post by: dedndave on April 15, 2012, 12:29:11 PM
if you have a value whose range is 0 to 31, it requires 5 bits to store it
25 = 32 (5 bits may represent up to 32 unique values)

each byte has 8 bits

if you have several values with the same range, you can use more bytes and pack more values
for example, we can pack (8) 5-bit values into 5 bytes (40 bits)

also - if you have one value with a range of 0 to 7 and another value with a range of 0 to 31, you can pack them both into 1 byte
23 = 8 (3 bits may represent up to 8 unique values)

tell us the range of all the values you want to pack
Title: Re: Pack one bit into byte or something like that, how?
Post by: jj2007 on April 15, 2012, 04:48:48 PM

       mov eax, 111b     ; same as mov eax, 7 in decimal notation
eax=   00000111=1+2+4=7
       mov edx, 11111b   ; same as mov edx, 31
edx=   00011111=1+2+4+8+16=31
       shl edx, 3        ; move the set bits to the left
edx=   11111000
       add eax, edx
       00000111
       11111000 +
eax=   11111111 = 255

Title: Re: Pack one bit into byte or something like that, how?
Post by: BytePtr on April 15, 2012, 05:44:41 PM
Ok, i will explain again: I work with 3D coordinates in my OpenGL app. X, Y and Z
X,Y minimum value can be 0, maximum value can be 255.
Z can hold values 0..7.

If i read X,Y,Z in my OpenGL app, i get coordinates of my objects of course. But into this X coordinate i would like to pack also the simple number, let's call it ID value. The ID value can only be one of these numbers: 0,1,2,3 or 4.
So the X coordinate should also hold the ID number in it.
Later if i need X coordinate, i will unpack the value packed in it and will take the X value, and if i need the ID value.
Seems that the BYTE which can hold values up to 255, is unable to hold also my ID value.

I can also work with UNSIGNED_INT's, if need to. No problem.  I guess.
If it will make things easier and makes them work.

Maybe im wrong. I will take a look into my other test app i made, and will see if it's my code or it's just doesn't fit.
Will also look, if it limits the same way.

EDIT yes, i discovered that my second test app also limit's X coordinate to 31 only. After i have unpacked it.
But it should not limit it. It must be allowed to go up to 255.

Guys, don't be mad on me. Im just learning the bit packing and similar things.
Title: Re: Pack one bit into byte or something like that, how?
Post by: qWord on April 15, 2012, 05:53:45 PM
Quote from: BytePtr on April 15, 2012, 05:44:41 PMSeems that the BYTE which can hold values up to 255, is unable to hold also my ID value.
simply use a fourth variable that holds the ID  :wink
Title: Re: Pack one bit into byte or something like that, how?
Post by: dedndave on April 15, 2012, 05:56:21 PM
Jochen is showing you the basics   :U
works great if everything is orthoganal

several years ago, i wanted to pack some text files
upper case - 26
lower case - 26
numbers - 10

that's 62 different values
if you add space and period, you're all done
64 values would fit into 6 bits

the next step is 7 bits
i wasn't happy with the "compression ratio", but you could have 128 unique characters

so - i wanted something in between
got out the calculator and figured out that i could pack up to 85 unique characters with a little better compression

but - shifting bits wouldn't do it
you have to multiply and divide
it was a lesson in Horner's Rule (Ling Long Kai Fang   :P )
although, i didn't know Horner or Ling at the time

essentially, i made a base-85 numbering system

in base-10, we put digits together like this
DN*10N + DN-1*10N-1 ... + D3*103 + D2*102 + D1*101

my packed system looked like this
D6*856 + D5*855 + D4*854 + D3*853 + D2*852 + D1*851

i got 6 base-85 "digits" in 5 bytes   :P

Title: Re: Pack one bit into byte or something like that, how?
Post by: jj2007 on April 15, 2012, 06:01:23 PM
Ok, so you have X, Y, Z with 0...255, and ID. You can't avoid another byte for the ID, unless you can reduce the range for one of the others.
For performance reasons, you should 4 bytes = one DWORD anyway. Do you have a good reason for being stingy with data size?
Title: Re: Pack one bit into byte or something like that, how?
Post by: dedndave on April 15, 2012, 06:01:46 PM
the problem you have is that you a set of 3 values
not much packing to be done, unless you want to pack 8 sets of values together   :P

i.e. (8) 3-D coordinates (which would normally require 24 bytes) can be packed into a group of 19 bytes

with the ID - just pack the 3-bit Z value with the 3-bit ID   :P
ok - you lose a couple bits
on the bright side, you could expand the system to accomodate 5-bit ID's (0-31)

in 3 bytes, you can get the ID, X, Y, and Z

that may save you some space
but - performance is likely to be improved by using 4 bytes, anyways
that is because the 32-bit world likes to access memory 32-bits at a time   :bg
Title: Re: Pack one bit into byte or something like that, how?
Post by: FORTRANS on April 15, 2012, 06:15:33 PM
Hi,

   If the X and Y values need to hold 0 to 255, they fill a byte.
No space left over to pack more data into the byte.  If the Z
value is 1 to 7 it requires three bits.  The ID holds 1 to 4 so it
requires three bits for a single ID.  You can pack the ID and
the Z value into one byte if wanted.  You can use four bits each
and treat the byte as a 2 digit packed BCD value.

   If you have oodles of ID values you can pack them as Dave
showed by compressing three into one byte.

Regards,

Steve N.
Title: Re: Pack one bit into byte or something like that, how?
Post by: BytePtr on April 15, 2012, 06:30:11 PM
ID holds 0..4. (1--5 if you want).
So they fit into Z?


Why im picky about data type, is because the OpenGL function i work is glColor3ub.
In other words, unsigned byte. It seems to stop working correctly if supply him something else.
In my app each object has color derived from X,Y,Z. So for ex: X0,Y0,Z0 are all RGB 0,0,0, so, this object has coordinates of 0,0,0.
If X1, Y0, Z0, then color of this object is RGB 1,0,0. glColor3ub just does all that, the only function that i found which paints my objects to color derived from X,Y,Z.

But each object has that ID number, so when reading coordinates, i also need this ID. Without packing stuff together, it seems to get too complicated.


Thanks for all the replies so far. I will try with Z.
Title: Re: Pack one bit into byte or something like that, how?
Post by: qWord on April 15, 2012, 06:36:38 PM
Quote from: BytePtr on April 15, 2012, 06:30:11 PM
But each object has that ID number, so when reading coordinates, i also need this ID. Without packing stuff together, it seems to get too complicated.
but this would mean, that the color also depends on the ID, because the ID is placed in the upper bits of Z - make not much sense.
Title: Re: Pack one bit into byte or something like that, how?
Post by: dedndave on April 15, 2012, 06:43:58 PM
i am not sure that you need to explicitly store an "ID number"
doesn't the position in the array imply the ID ?
for example - you have coordinate sets with ID's numbering 0 to 4
if we place those 5 coordinates into an array, then we know the ID of each, based on it's position in the array

that could work out rather nicely
you could store bytes like so

X0 Y0 X1 Y1 X2 Y2 X3 Y3 X4 Y4 P1 P2

P1 and P2 contain the packed Z values
5 x 3 = 15 bits
12 bytes stores 5 coordinates
Title: Re: Pack one bit into byte or something like that, how?
Post by: dedndave on April 15, 2012, 07:39:29 PM
not to mention what qWord said   :red
QuoteIn my app each object has color derived from X,Y,Z. So for ex: X0,Y0,Z0 are all RGB 0,0,0, so,
this object has coordinates of 0,0,0. If X1, Y0, Z0, then color of this object is RGB 1,0,0
that makes no sense
i mean - ok - we can do that, but we don't have to store the values
we can simply generate them based on location   :P

EDIT:
ok - i can see where that makes sense
you have an object plotted with points
if there is nothing there, there will be no point
Title: Re: Pack one bit into byte or something like that, how?
Post by: BytePtr on April 15, 2012, 08:15:21 PM
Well okay, i have to reveal more about my project.


All the 3D objects i have are the CUBES. Each cube has a FACE ID: LEFT, RIGHT, TOP, BOTTOM, LID.
Each cube is drawn using colors derived from X,Y,Z, OpenGL assigns for each block a color glColor3ub(X,Y,Z);
Im using colors for picking these cubes in my OpenGL app.
This works perfectly. I can click on any cube and it shows it's location perfectly, even at X:255, Y:255, Z:7.

When i added packed FACE_ID+X_COORD: i used it like this: glColor3ub(PackedData, Y, Z);

If im gonna add something (pack) to X, the picking is messed up. X is limited to 31 and that's all. I still know what side user clicked but X coord gets limited. So will Y and probably Z, dunno.

It (X) starts from 0 again and goes up to 31 and again from 0, etc and so on.
When user clicks on any cube at any location of X,Y,Z, i need to also detect, on which side of cube user clicked: (0=LEFT, 1=RIGHT, 2=TOP, 3=BOTTOM, 4=LID).


I used jj2007 code to pack and unpack the FACE ID and X coordinate, believe it or not, it worked perfectly. I mean detecting face and coordinate, but only thing was limited X coord. Because i packed stuff into it.

Quotebut this would mean, that the color also depends on the ID, because the ID is placed in the upper bits of Z

Yeah i know, but for some reason it worked fine for X. Only problem i have atm. is that everything is limited to 31, after packing / unpacking.
Without packing, everything works, but i don't know which side user clicked.

So if the additional FACE_ID will fit into Z coord, then it should work fine. If Z is limited to 31, it's okay. Z can never go beyond 8 anyway. I will try to pack FACE_ID into Z.

EDIT I packed face_id into Z and it works perfectly now. If inside dark places in exe, it limits the Z to 31, i don't care.
X,Y are now as they are, Z can never go over 8, so im satisfied.

Thank you guys for all the help so far.


EDIT2
I know it's not OpenGL forum, but just a question, you can ignore it if you want. But..

How to allow user to choose background color and at the same time avoid conflicts between block colors and background colors?

For example i like black background color, better for eyes. But my block also can have (has) color value (0,0,0).
If user clicks on background, code "thinks" that user clicked on the cube at X0,Y0,Z0 and it get's modified, but it shouldn't.

One way i was thinking about is just limit the list of colors for background, from which user can choose one, but im not very sure about this one.
Title: Re: Pack one bit into byte or something like that, how?
Post by: jj2007 on April 15, 2012, 09:07:57 PM
Quote from: BytePtr on April 15, 2012, 08:15:21 PM
Z can never go beyond 8 anyway.

That was the missing info! So you can use e.g. 3 bits for the ID, 0...15 and 5 bits for Z, 0...63. Don't forget to mask out the ID before passing Z to OpenGL, e.g. with
mov eax, PackedZ
and eax, 63
invoke glColor3ub(X, Y, eax)
Title: Re: Pack one bit into byte or something like that, how?
Post by: BytePtr on April 16, 2012, 08:32:37 AM
Thank you. Sorry for the missing info.
I also found a pretty fine solution for color conflicts with objects and background color.
It's again thanks to the fact that Z can't go beyond 8. Actually: 0..7.

I found this solution in 3 AM in the morning. But they say, don't code anything at this time of night  :bg

If background color RGB blue component is below 8, then just change it back to 8.
This way, it's still allowed to choose a lot of colors, but at the same time, it will not conflict with my object colors.
Because B value is always equal to 8 or higher than 8.
And i don't have any objects with colors: R255, G255, B > 7
Title: Re: Pack one bit into byte or something like that, how?
Post by: dedndave on April 16, 2012, 11:37:13 AM
that's one way
another would be to change 1 bit
colors used to draw objects could always have odd values
colors used for backgrounds, insets, descriptive text, etc, could have even values
especially true for BLUE, the human eye can't detect the difference

the data can be stored with all bits - only displayed with that bit set or cleared, as required