I have been trying for an hour to pack a simple number into a type 'S'
I have a small number < 10 and need to smash it into a unit16.
I think the Perl "pack()" should take a number < 64k and PACK it into
16 contiguous bits resembling a uint16_t in C. All 5000 attempts to
figure out this simple function have failed. What am I doing wrong?
In C:
unit16_t count; // Tiny, 1 digit integer
uint48_t rgb; // Full 48 binary bits from 3, uint16s, r, g and b
uint64_t rgbc; // The final data, just like RGBA
memcpy(rgbc+0, rgb, 3*sizeof(uint16_t));
memcpy(rgbc+3, count, 1*sizeof(uint16_t));
// Voila! 4 ushort numbers in a row in RGBC "PACKED" into 64 adjoining
+ bits
Conceptually this is what I want to do:
Take 6 bytes of RGB and 2 bytes of count into a PACK them into a 'Q' 6
+4
$rgbc = pack('Q', $rgb, $count);
"Pack a quad from 2 variables and store in RGBC"
I have a test number, 0x4567 = decimal 17757
I have a 48 bit RGB dragged from a binary .RAW file in a hash key
The tiny count is the data value for an RGB key.
I want to write an RGBC file with the count appended to the end of the
+
RGB value so I will have 4, unit16_t values to make a uint64_t RGBC
How does one "Pack" a small number into a 16 bit unsigned integer??
------------------------------
Attempts:
Perl:
http://perldoc.perl.org/functions/pack.html
pack TEMPLATE,LIST
The TEMPLATE is a sequence of characters that give the order and type
+of
values, as follows:
S An unsigned short value.
$count=17767; # C=0x4567=Dec17757
$c16 = pack("S", $count); # Pack COUNT to
@c = pack("S*", $count); # == 0000
printf("Count= dec %d, hex 0x%04hx, c16=0x%04hx, \@c[%d]=%s\n",
$count, $count, $c16, scalar @c, join(", ", @c));
printf("c[0]=%d=0x%08x, c[1]=%d=0x%08x\n", $c[0], $c[0],$c[1],$c[1
+]);
->
Count= dec 17767, hex 0x4567, c16=0x0000, @c[1]=gE
c[0]=0=0x00000000, c[1]=0=0x00000000
and many error/warning messages
Unpack?
Count= dec 17767, hex 0x4567, c16=0x0000, @c[2]=14129, 13879
c[0]=14129=0x00003731, c[1]=13879=0x00003637
17767 dec = 0b100010101100111
14129 dec = 0b11011100110001 <<< totally random?
13879 dec = 0b11011000110111
The number packs into a single 'S' with a value of 0x0000
But, it also packs into an array of unsigned shorts with weird
values c[0]=14129=0x3731, c[1]=13879=0x3637
None of these integers or hex values bears any resemblance to my numbe
+r
------------------------------------------
Obviously the wrong approach:
Try putting the number in as a text literal, "17757":
@c = unpack("S*", "17757"); # == 0000
printf("\@c[%d]=%s\n", scalar @c, join(", ", @c));
printf("c[0]=%d=0x%08x, c[1]=%d=0x%08x\n", $c[0], $c[0],$c[1],$c[1
+]);
@c[2]=14129, 13623
c[0]=14129=0x00003731, c[1]=13623=0x00003537
Same
--------------------------------------
Try using hex, 0x4567
@c = pack("S*", 0x4567); # == 0000
printf("\@c[%d]=%s\n", scalar @c, join(", ", @c));
printf("c[0]=%d=0x%08x, c[1]=%d=0x%08x\n", $c[0], $c[0],$c[1],$c[1
+]);
return();
@c[1]=gE One array value "gE"
c[0]=0=0x00000000 Prints as 0
--------------------------------------
Try doing some math on it so it knows its a number
@c = pack("S*", $c16=17757*1); # == 0000
printf("\@c[%d]=%s\n", scalar @c, join(", ", @c));
printf("c[0]=%d=0x%08x, c[1]=%d=0x%08x\n", $c[0], $c[0], $c[1], $c
+[1]);
return();
@c[1]=]E Weird text and zero for decimal and hex
c[0]=0=0x00000000
------------------------------------------
Confusing pack with unpack? I just used unpack to read a binary RAW fi
+le.
It worked exactly as expected.
@c = unpack("S*", "17757"); # == 0000
printf("\@c[%d]=%s\n", scalar @c, join(", ", @c));
printf("c[0]=%d=0x%08x, c[1]=%d=0x%08x\n", $c[0], $c[0], $c[1], $c
+[1]);
@c[2]=14129, 13623
c[0]=14129=0x00003731, c[1]=13623=0x00003537
----------------------------------------------
@c = pack("S*", "17757"); # == 0000
printf("\@c[%d]=%s\n", scalar @c, join(", ", @c));
printf("c[0]=%d=0x%08x, c[1]=%d=0x%08x\n", $c[0], $c[0], $c[1], $c
+[1]);
@c[1]=]E
Argument "]E" isn't numeric in printf at C:\bin\bb.pl line 347.
Use of uninitialized value in printf at C:\bin\bb.pl line 347.
Use of uninitialized value in printf at C:\bin\bb.pl line 347.
c[0]=0=0x00000000, c[1]=0=0x00000000
====================================================
====================================================
open(IN, "<$file") or die("CCS: ERROR! <Opening '$file': $!\n");
for($ii = 0; $ii < $sr_num; $ii++) {
$sr_len = sysread(IN, $buf, $bsize); # SysRead Length
$tr_len += $sr_len; # Total Read Length
$tr_num++; # Total Read Number
while($buf) {
$rgb=substr($buf, 0, 6, ''); # Nibble 6 bytes
$rgb2c{$rgb}++;
}
} # End For II loop
foreach $rgb (keys %rgb2c) {
$count = $rgb2c{$rgb};
# Attempt to take known 6 byte RGB, some psychotic
# perl number and smash them together into a QUAD
# a uint64 RGBC value just like a standard RGBA
$rgbc = pack('Q', $rgb, $count);