Binary string packing/unpacking issues

L

Lucas L.

Hi,
I have a packed string of raw binary pixel data that I want to
manipulate. However, I'm facing a few problems.
Firstly, the only way I've managed to unpack the data so far is with
"pixels.unpack('b*')". It works great, but comes out in one massive
string.
Is there a way to:
a)put this into an array with 8 bits in each element, eg. ['00000000',
'01010101'...]
b)unpack small sections of a few bites
The other problem is that I don't know of an efficient way to manipulate
this data without having to unpack\pack massive strings each time.

Are there any solutions to these?

Thanks!
 
D

Dave Bass

This code:

"Pixels".each_byte { |b| printf("%08b\n", b) }

produces:

01010000
01101001
01111000
01100101
01101100
01110011

Any help?
 
L

Lucas L.

Dave said:
"Pixels".each_byte { |b| printf("%08b\n", b) }

That's good for the first problem, thanks.
Now for the more difficult one of efficiently manipulating small
portions of the packed binary data.
 
R

Robert Klemme

That's good for the first problem, thanks.
Now for the more difficult one of efficiently manipulating small
portions of the packed binary data.

With Ruby 1.8 you can easily manipulate individual bytes directly:

irb(main):006:0> s="abc"
=> "abc"
irb(main):007:0> s[2]
=> 99
irb(main):008:0> s[2].to_s 2
=> "1100011"
irb(main):009:0> s[2] |= 4
=> 103
irb(main):010:0> s
=> "abg"
irb(main):011:0> s[2].to_s 2
=> "1100111"

I don't have a 1.9 handy so I can't tell you how to do it there. But
the basic lesson should be, that you can leave your data in a String and
manipulate it directly there.

Kind regards

robert
 
L

Lucas L.

Robert said:
With Ruby 1.8 you can easily manipulate individual bytes directly:

irb(main):006:0> s="abc"
=> "abc"
irb(main):007:0> s[2]
=> 99
irb(main):008:0> s[2].to_s 2
=> "1100011"
irb(main):009:0> s[2] |= 4
=> 103
irb(main):010:0> s
=> "abg"
irb(main):011:0> s[2].to_s 2
=> "1100111"

How can I replace portions of a packed binary string this way?
I know with a normal string it is easy:
irb(main):001:0> s = "abcdef"
=> "abcdef"
irb(main):002:0> s[0..2] = "cba"
=> "cba"
irb(main):003:0> s
=> "cbadef"

But I can't figure out how to do it with binary.

Thanks
 
T

Todd Benson

How can I replace portions of a packed binary string this way?
I know with a normal string it is easy:
irb(main):001:0> s = "abcdef"
=> "abcdef"
irb(main):002:0> s[0..2] = "cba"
=> "cba"
irb(main):003:0> s
=> "cbadef"

But I can't figure out how to do it with binary.

Look closely at Robert's irb line number 9.

A string is just bytes in a row with special characteristics/methods.

Todd
 
L

Lucas L.

Todd said:
How can I replace portions of a packed binary string this way?
I know with a normal string it is easy:
irb(main):001:0> s = "abcdef"
=> "abcdef"
irb(main):002:0> s[0..2] = "cba"
=> "cba"
irb(main):003:0> s
=> "cbadef"

But I can't figure out how to do it with binary.

Look closely at Robert's irb line number 9.

A string is just bytes in a row with special characteristics/methods.

Todd

You'll have to bear with me on this, I struggle with this sort of this.
I don't really know what using | achieves.
And a string may be bytes normally, but mine is a sequence of bits (well
is it in my flawed understanding). I'm using Gtk::pixbuf.pixels, if that
helps at all.

Sorry for the stupidity.
 
R

Robert Klemme

Todd said:
How can I replace portions of a packed binary string this way?
I know with a normal string it is easy:
irb(main):001:0> s = "abcdef"
=> "abcdef"
irb(main):002:0> s[0..2] = "cba"
=> "cba"
irb(main):003:0> s
=> "cbadef"

But I can't figure out how to do it with binary.
Look closely at Robert's irb line number 9.

A string is just bytes in a row with special characteristics/methods.

You'll have to bear with me on this, I struggle with this sort of this.
I don't really know what using | achieves.

It's the bitwise OR operator.

irb(main):001:0> 1 | 2
=> 3
And a string may be bytes normally, but mine is a sequence of bits (well
is it in my flawed understanding). I'm using Gtk::pixbuf.pixels, if that
helps at all.

I do not know what Gtk::pixbuf.pixels returns. But if it is a String
you can manipulate it like was have show before. Can you post what "p
your_pixbuf.pixels" and "p your_pixbuf.pixels.class" print?

Kind regards

robert
 
L

Lucas L.

Robert said:
It's the bitwise OR operator.
I don't really know why he uses it though.

Can you post what "p
your_pixbuf.pixels" and "p your_pixbuf.pixels.class" print?

Now we're getting somewhere. I was using puts to print pixels, and all I
got was a bunch of question marks. p returns a massive String
(pixels.class shows String). The string itself is uncompressed pixel
data, a byte per channel of RGBA. The output is a massive string of
"\000\000\000\000\000\000\000\000..." with "\377" where a pixel is
drawn, which I'm assumming is 0xFF in the alpha channel (why is \377
0xFF?).

However, when I tried
pixels[pixels.length-1] = '\377'
p pixels
There was no change.
So confused:(

Thanks!
 
P

Paul Irofti

So confused:(

That's because you don't seem to grasp the fundamentals, but eitherway
you're trying to do more `advanced' stuff based on them.
Relax a little bit, put your project on hold and start reading on the
way data is stored, how a bit and a byte are defined, and some Boolean
Algebra 101 won't hurt you.

Afterwards you'll not only be more productive, but you'll be able to see
things more clearly and make design choices a lot smarter.
 
R

Robert Klemme

Robert said:
It's the bitwise OR operator.
I don't really know why he uses it though.

Can you post what "p
your_pixbuf.pixels" and "p your_pixbuf.pixels.class" print?

Now we're getting somewhere. I was using puts to print pixels, and all I
got was a bunch of question marks. p returns a massive String
(pixels.class shows String). The string itself is uncompressed pixel
data, a byte per channel of RGBA. The output is a massive string of
"\000\000\000\000\000\000\000\000..." with "\377" where a pixel is
drawn, which I'm assumming is 0xFF in the alpha channel (why is \377
0xFF?).

However, when I tried
pixels[pixels.length-1] = '\377'
p pixels
There was no change.

irb#1(main):006:0> "\377"
=> "\377"
irb#1(main):007:0> "\377".length
=> 1
irb#1(main):008:0> '\377'
=> "\\377"
irb#1(main):009:0> '\377'.length
=> 4
irb#1(main):010:0>

Notice something?

I agree with Paul, you have trouble with the basics. If you try things
out on a smaller scale in IRB you'll probably see more easily how
everything works.

Kind regards

robert
 
A

ara.t.howard

Hi,
I have a packed string of raw binary pixel data that I want to
manipulate. However, I'm facing a few problems.
Firstly, the only way I've managed to unpack the data so far is with
"pixels.unpack('b*')". It works great, but comes out in one massive
string.
Is there a way to:
a)put this into an array with 8 bits in each element, eg. ['00000000',
'01010101'...]
b)unpack small sections of a few bites
The other problem is that I don't know of an efficient way to
manipulate
this data without having to unpack\pack massive strings each time.

Are there any solutions to these?

use narray

a rather complicated example

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/155483

the basic starting point is

width = 800
height = 600

na = NArray.to_na raw_pixel_data, NArray::BYTE, width, height

then to, for example, increase every pixel value by 1

na += 1

see

http://narray.rubyforge.org/SPEC.en

for more.

gem install narray

too, of course.


regards.

a @ http://codeforpeople.com/
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,050
Latest member
AngelS122

Latest Threads

Top