tags:

views:

121

answers:

5

I have been through these related questions:

But I did not get an answer probably because I do not understand 64bit or 16bit values.

I had posted a question on Picasa and face detection, to use the face detection that Picasa does to get individual pics from a photo containing many pictures. Automatic Face detection using API

In an answer @Joel Martinez linked to an answer on picasa help which said:

The number encased in rect64() is a 64-bit hexadecimal number.

  • Break that up into four 16-bit numbers.
  • Divide each by the maximum unsigned 16-bit number (65535) and you'll have four numbers between 0 and 1.

the full text

@oedious wrote:- This is going to be somewhat technical, so hang on. * The number encased in rect64() is a 64-bit hexadecimal number. * Break that up into four 16-bit numbers. * Divide each by the maximum unsigned 16-bit number (65535) and you'll have four numbers between 0 and 1. * The four numbers remaining give you relative coordinates for the face rectangle: (left, top, right, bottom). * If you want to end up with absolute coordinates, multiple the left and right by the image width and the top and bottom by the image height.

A sample picasa.ini file:

[1.jpg]
backuphash=65527
faces=rect64(5520c092dfb2f8d),615eec1bb18bdec5;rect64(dcc2ccf1fd63e93e),bc209d92a3388dc3;rect64(52524b7c785e6cf6),242908faa5044cb3
crop=rect64(0)

How do I get the 4 numbers from the 64 bit hex?

I am sorry people, currently I do not understand the answers. I guess I will have to learn some C++ (I am a PHP & Java Web Developer with weakness in Math) before I can jump in and write a something which will cut up an image into multiple images with the help of some co-ordinates. I am looking into CodeLab and creating plugins for Paint.net too

+1  A: 

It depends on your programming language - in C# i.e. you can use the BitConverter class, which allows you to extract a number based on the byte position within a byte array.

UInt64 largeHexNumber = 420404334;
byte[] hexData = BitConverter.GetBytes(largeHexNumber);
UInt16 firstValue = BitConverter.ToUInt16(hexData, 0);
UInt16 secondValue = BitConverter.ToUInt16(hexData, 2);
UInt16 thirdValue = BitConverter.ToUInt16(hexData, 4);
UInt16 forthValue = BitConverter.ToUInt16(hexData, 6);
BrokenGlass
Just make sure you keep in mind of the endianness of the underlying architecture.
Jeff M
True - point taken!
BrokenGlass
+1  A: 

It depends on the language. For the C-family of languages, it can be done like this (in C#):

UInt64 number      = 0x4444333322221111;

//to get the ones, use a mask
//                   0x4444333322221111
const UInt64 mask1 =             0xFFFF; 
UInt16 part1 = (UInt16)(number & mask1);

//to get the twos, use a mask then shift
//                   0x4444333322221111
const UInt64 mask2 =         0xFFFF0000; 
UInt16 part2 = (UInt16)((number & mask2) >> 16);

//etc.
//                   0x4444333322221111
const UInt64 mask3 =     0xFFFF00000000; 
UInt16 part3 = (UInt16)((number & mask3) >> 32);

//                   0x4444333322221111
const UInt64 mask4 = 0xFFFF000000000000; 
UInt16 part4 = (UInt16)((number & mask4) >> 48);
Jeff M
+1  A: 

What I think you are being asked to do is take the 64 bits of data you have and treat it like 4 16-bit integers. From there you are taking the 16-bit values and converting them to percentages. Those percentages, when multiplied to the image height/width, give you 4 coordinates.

How you do this depends on the language you're programming in.

Brad
+1  A: 

Here is the algorithm:

The remainder of the division by 0x10000 (65536) will give you the first number.

Take the result then divide by 0x10000 (65536) again, the remainder will give you the second number.

Take the result the divide by 0x10000 (65536) again, the remainder will give you the third number.

The result is the fourth number.

pablosaraiva
Thank you. That is sane to me.
abel
Appreciate if someone could explain that 0x10000. Thanks!
Nirmal
A 16 bits hexadecimal number is between 0x0000 and 0xFFFF. If you have the following number 0xAAAABBBBCCCCDDDD and divide it by 0x10000, the result will be 0xAAAABBBBCCCC and the remainder will be 0xDDDD.
pablosaraiva
+5  A: 

If you want basics, say you have this hexadecimal number:

4444333322221111

We split it into your 4 parts on paper, so all that's left is to extract them. This involves using a ffff mask to block out everything else besides our number (f masks nothing, 0 masks everything) and sliding it over each part. So we have:

part 1: 4444333322221111 & ffff             = 1111
part 2: 4444333322221111 & ffff0000         = 22220000
part 3: 4444333322221111 & ffff00000000     = 333300000000
part 4: 4444333322221111 & ffff000000000000 = 4444000000000000

All that's left is to remove the 0's at the end. All in all, in C, you'd write this as:

int GetPart(int64 pack, int n) // where you define int64 as whatever your platform uses
{                              // __int64 in msvc
  return (pack & (0xffff << (16*n)) >> (16*n);
}

So basically, you calculate the mask as 0xffff (2 bytes) moved to the right 16*n bits (0 for the first, 16 for the 2nd, 32 for the 3rd and 48 for the 4th), apply it over the number to mask out everything but the part we're interested in, then shift the result back 16*n bits to clear out those 0's at the end.

Some additional reading: Bitwise operators in C.

Hope that helps!

Blindy