Saturday, June 30, 2012

Difference Between the Hash() and Hash_File() Functions in PHP

The Hash_File() function returns the same value as if the function Hash() had been performed on the same exact piece of data.  At first, I was uncertain if Hash_File() used the filename, or even the permission settings, when defining the data to be hashed for the given algorithm.  If it did work that way, then that means the same exact files would have different HASH values when you moved or renamed them on your system.  Anyway, fortunately, it does not work that way.  Hash() and Hash_File() produce identical results for the same pieces of data.  This is also true for the relationship between the Hash_HMAC() and Hash_HMAC_File() functions: the same pieces of data, the same keys, produce identical results.  It was a wise, design principle.

Some sample code to demonstrate this principle :

<?php

            // Author: holdoffhunger@gmail.com

        // Preset Data
        // ------------------------------------------------
       
    $test_data = "php-hashing";
    $test_file = "test.txt";
    $test_file_read = file_get_contents($test_file);
   
        // Hash Data
        // ------------------------------------------------
   
    $test_data_hash = hash("md2", $test_data, FALSE);
    $test_file_hash = hash_file("md2", $test_file, FALSE);
   
        // Print Hash Results
        // ------------------------------------------------
   
    print("Data Hash ($test_data): $test_data_hash<br><br>");
    print("File Hash ($test_file_read): $test_file_hash");
   
?>

    Expected Results
    ..................................
   
Data Hash (php-hashing): 457d84e1d69e519a7b73348db21477d3

File Hash (php-hashing): 457d84e1d69e519a7b73348db21477d3

Official Function Page: http://www.php.net/manual/en/function.hash-file.php

// Note: All code appearing on the PHP Revolution blog by the blog owner is released under the Hacktivismo Enhanced-Source Software License Agreement (HESSLA), unless otherwise noted.  http://www.hacktivismo.com/about/hessla.php

Friday, June 29, 2012

Using the MHash Function to Create HMAC Hash Results in PHP

The MHash function here lists one disclaimer at the top when providing a key to the mhash function : "Not all algorithms supported in mhash can be used in HMAC mode."  So, what algorithms blow up and what do fine when it comes to doing keyed, HMAC hashing?  The destructive ones are: Adler32, CRC32, CRC32B, and GOST.  These are the first four, predefined constants listed with the MHash Application Package: http://www.php.net/manual/en/mhash.constants.php .  Providing one of these algorithms with an HMAC key (of string-length greater than one) creates the following error message: "Warning: mhash() [function.mhash]: mhash initialization failed in [(folder-location)] on line 181".  If you really want to use these algorithms in creating your HMAC hashes, the function Hash_hmac() from the HASH-Message Digest Framework package is capable of doing that perfectly.

Again, that is if the string length is greater than one.  Why string length greater than one?  Well, if the key value is blank, it is ignored as a parameter altogether.  So, if you feed the mhash function an algorithm that is not compatible with HMAC hashing and an HMAC key that's blank (""), it will work the same as if it had received no HMAC key at all.  This is different from the way the Hash_hmac() function of the HASH-MDF works.  In the case of the Hash_hmac() function, feeding a blank HMAC key will use that blank key in generating the HMAC hash.  Even with functions that can do HMAC hashing, like MD5 or SHA1, if the MHash() is given a blank HMAC key, it will ignore the key and just return the results of standard, non-HMAC hashing.  It's probably not wise to use a blank HMAC key anyway, but it's good to know that the hashing algorithm changes altogether if the provided HMAC key is blank.

Some sample code to demonstrate :

<?php

            // Author: holdoffhunger@gmail.com
   
        // Preset Data
        // ---------------------------------------------------

    $string_to_hash = "The hash_hmac() function better to use for these purposes.";
    $blank_hmac_key = "";
   
        // MHash - Hashing With and Without HMAC Parameter
        // ---------------------------------------------------

    $mhash_result_with_hmac_parameter = bin2hex(mhash(MHASH_CRC32, $string_to_hash, $blank_hmac_key));
    $mhash_result_without_hmac_parameter = bin2hex(mhash(MHASH_CRC32, $string_to_hash));
   
        // MHash - Hashing With and Without HMAC Parameter
        // ---------------------------------------------------

    $hash_result_with_hmac_parameter = hash_hmac("crc32", $string_to_hash, $blank_hmac_key);
    $hash_result_without_hmac_parameter = hash("crc32", $string_to_hash);

        // Print Results
        // ---------------------------------------------------

    print("MHASH (CRC32 Algorithm) With Blank HMAC Key: $mhash_result_with_hmac_parameter .<br>");
    print("MHASH (CRC32 Algorithm) Without HMAC Processing: $mhash_result_without_hmac_parameter .<br><br>");

    print("HASH (CRC32 Algorithm) With Blank HMAC Key: $hash_result_with_hmac_parameter .<br>");
    print("HASH (CRC32 Algorithm) Without HMAC Processing: $hash_result_without_hmac_parameter .");

?>

    Results :
    ...................................

MHASH (CRC32 Algorithm) With Blank HMAC Key: f665c094 .
MHASH (CRC32 Algorithm) Without HMAC Processing: f665c094 .

HASH (CRC32 Algorithm) With Blank HMAC Key: 3041f4f8 .
HASH (CRC32 Algorithm) Without HMAC Processing: f665c094 .

Official Function Page: http://www.php.net/manual/en/function.mhash.php

// Note: All code appearing on the PHP Revolution blog by the blog owner is released under the Hacktivismo Enhanced-Source Software License Agreement (HESSLA), unless otherwise noted.  http://www.hacktivismo.com/about/hessla.php

Thursday, June 28, 2012

Parsing the Algorithms Available in MHash Within PHP

The MHash function mhash_count() returns the highest, evaluated, constant value representing a hashing algorithm available within the current MHash install.  For example, 0 indicates CRC32, 1 indicates MD5, 2 indicates SHA1, etc., etc..  You can get the evaluated number for any of these algorithms by doing a print statement with any of the predefined, MHash constants, such as those available here : http://www.php.net/manual/en/mhash.constants.php .

The purpose of mhash_count() in MHash is similar to the purpose of hash_algos() in HASH Message Digest Framework.  Instead of providing an array of available hashing algorithms, it simply provides the highest, evaluated, constant expression for the Algorithm Constants.  The thinking, as indicated in the sample code, is that you will parse a list of mhash algorithms in a for loop using a condition of "$i <= mhash_count()".

However, there is a problem with that: there are several integers that are skipped in the listing of evaluated constant expressions.  While 2 indicates SHA1, 3 indicates HAVAL256, etc., there is nothing for the numbers 4 and 6.  They produce blank results when on that line of the for-loop and you're calling functions like mhash_get_block_size() and mhash_get_hash_name().  These were likely reserved for algorithms that were removed for one reason or another, either inefficiency or lack of security, and the number-to-predefined-constant setup wasn't changed to make it backward compatible with older code.

If you want to know what counts as a good constant and what doesn't, try running this code :

<?php

            // Author: holdoffhunger@gmail.com
   
        // Parse All Hashing Algorithms
        // ---------------------------------------------------

    for($i = 0; $i <= mhash_count(); $i++)
    {
            // Get Algorithm Information
            // ---------------------------------------------------

        $mhash_algorithm_block_size = mhash_get_block_size($i);
        $mhash_algorithm_name = mhash_get_hash_name($i);
       
            // Decide on Printing Algorithm Information
            // ---------------------------------------------------
       
        if(strlen($mhash_algorithm_name) < 1)
        {
                // There *IS NO* Available Algorithm Data
                // ---------------------------------------------------

            print("# $i --- NO ALGORITHM NAME / NO ALGORITHM BLOCKSIZE .<br><br>");
        }
        else
        {
                // There *IS* Available Algorithm Data
                // ---------------------------------------------------
           
            print("# $i --- $mhash_algorithm_name to $mhash_algorithm_block_size .<br><br>");
        }
    }

?>

    Sample Results
    ............................

# 0 --- CRC32 to 4 .

# 1 --- MD5 to 16 .

# 2 --- SHA1 to 20 .

# 3 --- HAVAL256 to 32 .

# 4 --- NO ALGORITHM NAME / NO ALGORITHM BLOCKSIZE .

# 5 --- RIPEMD160 to 20 .

# 6 --- NO ALGORITHM NAME / NO ALGORITHM BLOCKSIZE .

# 7 --- TIGER to 24 .

# 8 --- GOST to 32 .

...(and so on)...

Official Function Page: http://www.php.net/manual/en/function.mhash-count.php

// Note: All code appearing on the PHP Revolution blog by the blog owner is released under the Hacktivismo Enhanced-Source Software License Agreement (HESSLA), unless otherwise noted.  http://www.hacktivismo.com/about/hessla.php

Wednesday, June 27, 2012

MHash compared with HASH Message Digest Framework in PHP

Both cryptography packages, the MHash and the HASH Message Digest Framework, have the same algorithms, and yet, they both sometimes to produce wildly different results from each other when applying the same algorithm to the same piece of data.  The SHA-x algorithms, as designed by the NSA, all seem to have concrete standards for producing their hash values, so they have similar results.  Even the two MD5 implementations produce identical results, and the same goes for Gost, RipeMD, CRC32, Whirlpool, Snefru256 (known as 'Snefru256' in MHash and simply 'Snefru' in HASH-MDF), and Tiger (the three-round versions in HASH-MDF to simply 'Tigerx' in MHash).

However, the algorithms CRC32B and Adler32 each produce different results when called from either MHash or HASH-MDF, possibly because they are hashing algorithms designed to be checksums rather than something that can produce a string as a unique identifier for a particular piece of information.  For that reason, if you ever publish the hash results with the data you're putting out publicly, it's probably wise to indicate whether it's the MHash or HASH-MDF implementation of the algorithm.  Otherwise, the hash value won't provide much use as a unique identifier for the particular piece of data or for the file.

Some example code to better explain what I mean :

<?php

            // Author: holdoffhunger@gmail.com
   
        // SHA-1 Hashing
        // ---------------------------------------------------

    $mhash_sha1_results = bin2hex(mhash(MHASH_SHA1, "secret"));
    $hash_mdf_sha1_results = hash("sha1", "secret", FALSE);

    print("MHash SHA-1: $mhash_sha1_results .<br>");
    print("HASH-MDF SHA-1: $hash_mdf_sha1_results .<br><br>");
   
        // Whirlpool Hashing
        // ---------------------------------------------------

    $mhash_whirlpool_results = bin2hex(mhash(MHASH_WHIRLPOOL, "secret"));
    $hash_mdf_whirlpool_results = hash("whirlpool", "secret", FALSE);

    print("MHash Whirlpool: $mhash_whirlpool_results .<br>");
    print("HASH-MDF Whirlpool: $hash_mdf_whirlpool_results .<br><br>");
   
        // CRC32B Hashing
        // ---------------------------------------------------

    $mhash_crc32b_results = bin2hex(mhash(MHASH_CRC32B, "secret"));
    $hash_mdf_crc32b_results = hash("crc32b", "secret", FALSE);

    print("MHash CRC32B: $mhash_crc32b_results .<br>");
    print("HASH-MDF CRC32B: $hash_mdf_crc32b_results .<br><br>");
   
        // Adler32 Hashing
        // ---------------------------------------------------

    $mhash_adler32_results = bin2hex(mhash(MHASH_ADLER32, "secret"));
    $hash_mdf_adler32_results = hash("adler32", "secret", FALSE);

    print("MHash Adler32: $mhash_adler32_results .<br>");
    print("HASH-MDF Adler32: $hash_mdf_adler32_results .<br><br>");

?>

    Expected Results :
    ........................

MHash SHA-1: e5e9fa1ba31ecd1ae84f75caaa474f3a663f05f4 .
HASH-MDF SHA-1: e5e9fa1ba31ecd1ae84f75caaa474f3a663f05f4 .

MHash Whirlpool: e061b87a674ae3880e159ab55ed35d6c5e8a6aefac6ab08304a50588018d377b28639bb15fdeedf006d57e45f7b4298e6dfefceaf7c92c826a708fe6d1156eb3 .
HASH-MDF Whirlpool: e061b87a674ae3880e159ab55ed35d6c5e8a6aefac6ab08304a50588018d377b28639bb15fdeedf006d57e45f7b4298e6dfefceaf7c92c826a708fe6d1156eb3 .

MHash CRC32B: e5e8a25c .
HASH-MDF CRC32B: 5ca2e8e5 .

MHash Adler32: 8702d108 .
HASH-MDF Adler32: 08d10287 .

Official Function Page: http://www.php.net/manual/en/function.mhash.php

// Note: All code appearing on the PHP Revolution blog by the blog owner is released under the Hacktivismo Enhanced-Source Software License Agreement (HESSLA), unless otherwise noted.  http://www.hacktivismo.com/about/hessla.php

Tuesday, June 26, 2012

Alternate Hash Algorithms for ImageMagick's GetImageSignature in PHP

The getImageSignature function for the ImageMagick package in PHP returns only the SHA-256 hash value for an image.  There are not any other algorithms available for it within the ImageMagick package, but fortunately, this is PHP and you have a wide array of hashing algorithms to use on any image file.  The function hash_algos() will return an array of hashing algorithms available in PHP and the function hash_file() will take three parameters (one for the algorithm to use, one for the filename, and an optional variable for binary output).  Instead of being limited to the SHA-256 algorithm of the getImageSignature function, you could use SHA-1, SHA-384, SHA-512, Whirlpool, HAVAL, Salsa, Gost, Adler32, CRC32, or MD5, among others and variations of these.

However, the SHA-256 result of the hash_file() function performed on a file does not return the same result as the SHA-256 of the getImageSignature() function.  This leads me to believe that the SHA-256 of the getImageSignature() might be performed on the Imagick object itself, instead of the file, whereas the hash_file() function is clearly performed on the file itself.  That's just a guess, though.

Some sample code for the alternate hashing algorithm, with every algorithm performed on the image file :

<?php

            // Author: holdoffhunger@gmail.com

        // Set File for Hashing Function
        // ---------------------------------------------------

    $filename_with_folder_for_hashing = "image_workshop/test_file.bmp";
   
        // Acquire Dynamic Hashing Algorithm List
        // ---------------------------------------------------

    $php_dynamic_hash_algorithms = hash_algos();

        // Count Dynamic Hashing Algorithm List
        // ---------------------------------------------------
   
    $number_of_dynamic_hash_algorithms = count($php_dynamic_hash_algorithms);

        // Parse Dynamic Hashing Algorithm List
        // ---------------------------------------------------
   
    for($i = 0; $i < $number_of_dynamic_hash_algorithms; $i++)
    {
            // Get Current Hashing Algorithm
            // ---------------------------------------------------

        $current_hashing_algorithm = $php_dynamic_hash_algorithms[$i];

            // Perform Hashing on File
            // ---------------------------------------------------

        $current_hashing_algorithm_hex_result = hash_file($current_hashing_algorithm, $filename_with_folder_for_hashing, FALSE);

            // Print Hashed Results
            // ---------------------------------------------------

        print("$current_hashing_algorithm Algorithm ::: $current_hashing_algorithm_hex_result");
        print("<br><br>");
    }

?>

    Example Results:
    ...........................

md2 Algorithm ::: 03205df9c6717d74f1f003c66f58e98a

md4 Algorithm ::: b2a204a2e5c3968d2abd5dc372fbee10

md5 Algorithm ::: b9d92a61714b221d24c7730d4764ca82

sha1 Algorithm ::: 8db4c92346c26568b13ea43fbcf514e37942a41a

(and so on for 34 more algorithms)...

Official Function Page: http://www.php.net/manual/en/imagick.getimagesignature.php

// Note: All code appearing on the PHP Revolution blog by the blog owner is released under the Hacktivismo Enhanced-Source Software License Agreement (HESSLA), unless otherwise noted.  http://www.hacktivismo.com/about/hessla.php

Monday, June 25, 2012

Viewing Hexdec Results as Standard, Non-Scientific Digits in PHP

When given large numbers, the hexdec function automatically converts the value to scientific notation.  So, "aa1233123124121241" as a hexadecimal value will be converted to "3.13725790445E+21".  If you're converting a hexadecimal value that represents a hash value (md5 or sha), then you need every single bit of that representation to make it useful.  By using the number_format function, you can do that perfectly.  For example :

<?php

            // Author: holdoffhunger@gmail.com
   
        // Example Hexadecimal
        // ---------------------------------------------

    $hexadecimal_string = "1234567890abcdef1234567890abcdef";
   
        // Converted to Decimal
        // ---------------------------------------------

    $decimal_result = hexdec($hexadecimal_string);
   
        // Print Pre-Formatted Results
        // ---------------------------------------------

    print($decimal_result);

            // Output Here: "2.41978572002E+37"
            // .....................................
   
        // Format Results to View Whole All Digits in Integer
        // ---------------------------------------------

            // ( Note: All fractional value of the
            //         Hexadecimal variable are ignored
            //         in the conversion. )
                   
    $current_hashing_algorithm_decimal_result = number_format($decimal_result, 0, '', '');
   
        // Print Formatted Results
        // ---------------------------------------------

    print($current_hashing_algorithm_decimal_result);

            // Output Here: "24197857200151253041252346215207534592"
            // .....................................

?>

Official Function Page: http://php.net/manual/en/function.hexdec.php

// Note: All code appearing on the PHP Revolution blog by the blog owner is released under the Hacktivismo Enhanced-Source Software License Agreement (HESSLA), unless otherwise noted.  http://www.hacktivismo.com/about/hessla.php

Sunday, June 24, 2012

Convert Hexadecimal to Binary String in PHP

The function 'base_convert' looks like it would be perfect for converting a hexadecimal number to a binary number.  That code should look like :

<?php

            // Author: holdoffhunger@gmail.com

    $hexadecimal_number = "1234567890aBcDeF";
    $binary_number = base_convert($hexadecimal_number, 16, 2);
    print($binary_number);

?>

However, if the hexadecimal number is too large (more than ~40 characters), the result is always a string of zeros as the binary result.  So, I wrote some simple code to specifically handle base conversion with Hexadecimal-to-Binary in PHP :

<?php

            // Author: holdoffhunger@gmail.com
   
        // Example Hexadecimal
        // ---------------------------------------------

    $hexadecimal_number = "1234567890aBcDeF";

        // Format Hexadecimal
        // ---------------------------------------------

    $hexadecimal_to_convert_to_binary_testable = strtolower($hexadecimal_number);

        // Get String Length of Hexadecimal
        // ---------------------------------------------

    $length_of_text_to_convert_to_binary = strlen($hexadecimal_number);

        // Initialize Result Variable
        // ---------------------------------------------

    $results_of_hexadecimal_to_binary_conversion = "";

        // Parse Hexadecimal String
        // ---------------------------------------------
   
    for($i = 0; $i < $length_of_text_to_convert_to_binary; $i++)
    {
        $current_char_of_hexadecimal_for_conversion = $hexadecimal_to_convert_to_binary_testable[$i];
       
        switch($current_char_of_hexadecimal_for_conversion)
        {
            case '0':
                $results_of_hexadecimal_to_binary_conversion .= "0000";
                break;
               
            case '1':
                $results_of_hexadecimal_to_binary_conversion .= "0001";
                break;
               
            case '2':
                $results_of_hexadecimal_to_binary_conversion .= "0010";
                break;
               
            case '3':
                $results_of_hexadecimal_to_binary_conversion .= "0011";
                break;
               
            case '4':
                $results_of_hexadecimal_to_binary_conversion .= "0100";
                break;
               
            case '5':
                $results_of_hexadecimal_to_binary_conversion .= "0101";
                break;
               
            case '6':
                $results_of_hexadecimal_to_binary_conversion .= "0110";
                break;
               
            case '7':
                $results_of_hexadecimal_to_binary_conversion .= "0111";
                break;
               
            case '8':
                $results_of_hexadecimal_to_binary_conversion .= "1000";
                break;
               
            case '9':
                $results_of_hexadecimal_to_binary_conversion .= "1001";
                break;
               
            case 'a':
                $results_of_hexadecimal_to_binary_conversion .= "1010";
                break;
               
            case 'b':
                $results_of_hexadecimal_to_binary_conversion .= "1011";
                break;
               
            case 'c':
                $results_of_hexadecimal_to_binary_conversion .= "1100";
                break;
               
            case 'd':
                $results_of_hexadecimal_to_binary_conversion .= "1101";
                break;
               
            case 'e':
                $results_of_hexadecimal_to_binary_conversion .= "1110";
                break;
               
            case 'f':
                $results_of_hexadecimal_to_binary_conversion .= "1111";
                break;
        }
    }

        // Print Results
        // ---------------------------------------------

    print($results_of_hexadecimal_to_binary_conversion);

        // Output: (linebreak doesn't appear in results)
    // 00010010001101000101011001111000
    // 10010000101010111100110111101111

?>

Official Function Page: http://www.php.net/manual/en/function.base-convert.php

// Note: All code appearing on the PHP Revolution blog by the blog owner is released under the Hacktivismo Enhanced-Source Software License Agreement (HESSLA), unless otherwise noted.  http://www.hacktivismo.com/about/hessla.php

Saturday, June 23, 2012

Multi-Algorithm Hashing Functions in PHP

If you print the results of the hash_algos function and look at all of the available hashing functions, you will find four with duplicate functions: md5, sha1, crc32, and sha256.  That means you can call the any of these function with either its own function or the hash function.  For example, with the SHA1 function :

<?php

            // Author: holdoffhunger@gmail.com

    $sha1_first_value = sha1("secret", FALSE);

    $sha1_second_value = hash("sha1", "secret", FALSE);

?>

However, the alternate title for the SHA256 algorithm is "getImageSignature", as part of the ImageMagick application package.  Oddly, the CRC32 function returns different values when called from its own particular function (crc32()) compared to when it's called through the hash function (hash()).  This leads me to suspect that they may be different implementations of the crc32 algorithm altogether.  The different functions for SHA1 and MD5, however, produce the same results.  The SHA-256 algorithm, as implemented in the ImageMagick function, also produces different results compared to the results of the hash_file() function within the Hash application package.

For the String "1234567890", the single CRC32() Function (which doesn't have an option for binary, "raw data" representation) produces "639479525", but when called through the Hash() Function, that same string produces "b6536850".  I cannot find the relationship of any of these values, as they are not inverses of each other, nor is their sum or difference equal to any power of two (as I suspected they might be an equal distance from 0 or 2^32).

Both the SHA1 and MD5 alternate functions have the parameter of "TRUE/FALSE" at the end to indicate whether the result is given in binary (raw data) or not.  Unfortunately, this often turns out to be data that doesn't print very well.  It is recommended to be printed with the statement of printf("%u\n", $crc_32_value);.  However, that often doesn't produce any usable results, either.  The only method I have discovered is the "bin2hex" function, like so :

<?php

    $md5_value = hash("md5", "secret", FALSE);
    $md5_value_in_hex = bin2hex($md5_value);

?>

However, bin2hex returns a hexadecimal representation, whereas you probably wanted a string of binary 1's and 0's.  You can use the base_convert function, such as base_convert($md5_value_in_hex, 16, 2);.  However, base_convert doesn't work on large numbers, so you have to write your own function for converting Hex to Binary.

One other thing that will probably catch your attention is that half of the listed algorithms have similar names, but are represented with different numbers.  That means that the algorithm takes parameters itself, such as number of bits for the resultant hash value and number of rounds to do in producing the hashed result.  The first number in the title of the Hash Function usually indicates the size of the hash result, such as 128 bit for "haval128,3" and 160 bit for "tiger160,4".  The second number, however, indicates the number of rounds, such as 5 rounds for "haval224,5".

Official Function Page: http://www.php.net/manual/en/function.hash-algos.php

// Note: All code appearing on the PHP Revolution blog by the blog owner is released under the Hacktivismo Enhanced-Source Software License Agreement (HESSLA), unless otherwise noted.  http://www.hacktivismo.com/about/hessla.php

Friday, June 22, 2012

Determine Clipping Path Defaults for an Image in PHP with ImageMagick

By using the PHP function for getImageUnits, you get back an integer representing the evaluation of a predefined, PATHUNITS constant of the ImageMagick package.  You only have four values for this.  They look like "imagick::PATHUNITS_UNDEFINED", with _VALUE value's being: undefined, userspace, userspaceonuse, and objectboundingbox.  Undefined, if printed, is a 0, userspace is a 1, userspaceonuse is a 2, and objectboundingbox is a 3.

What's the use of knowing the Clipping Path Unit default for an image?  According to the Wikipedia article for "Clipping Path", a Clipping Path is "a closed vector path, or shape, used to cut out a 2D image in image editing software. Anything inside the path will be included after the clipping path is applied; anything outside the path will be omitted from the output."

The official ImageMagick documentation provides only two valid values coming into or out of the clipping path unit value, one being userSpaceOnUse and the other being ObjectBoundingBox.  The only definitions provided: "If userSpaceOnUse, the contents of the clipping path represent values in the current user coordinate system in place at the time when the clipping path is referenced. if objectBoundingBox, then the user coordinate system for the contents of the clipping path is established using the bounding box of the object to which the clipping path is applied. The default is userSpaceOnUse." http://www.imagemagick.org/RMagick/doc/rvgclip.html

In personal experimentation, all JPEG and GIF files have provided '0' for "Undefined" on this function, and all BMP and PNG files have provided '2' for "UserSpaceOnUse" on this function.

And some sample code :

<?php

            // Author: holdoffhunger@gmail.com
   
        // Imagick Type
        // ---------------------------------------------

    $imagick_type = new Imagick();
   
        // Open File
        // ---------------------------------------------
       
    $file_to_grab = "image_workshop_directory/test.gif";
   
    $file_handle_for_viewing_image_file = fopen($file_to_grab, 'a+');
   
        // Grab File
        // ---------------------------------------------

    $imagick_type->readImageFile($file_handle_for_viewing_image_file);
   
        // Get Image Units
        // ---------------------------------------------
       
    $image_page = $imagick_type->getImageUnits();
   
        // Interpret Units Value
        // ---------------------------------------------

    switch($image_units)
    {
        case imagick::PATHUNITS_UNDEFINED:
            $image_units_printable = "Undefined";
            break;
           
        case imagick::PATHUNITS_USERSPACE:
            $image_units_printable = "User Space";
            break;
           
        case imagick::PATHUNITS_USERSPACEONUSE:
            $image_units_printable = "User Space On Use";
            break;
           
        case imagick::PATHUNITS_OBJECTBOUNDINGBOX:
            $image_units_printable = "Object Bounding Box";
            break;
    }
   
        // Print Units Value
        // ---------------------------------------------

    print(" Image Units: # $image_units -- $image_units_printable .");

?>

Official Function Page: http://www.php.net/manual/en/imagick.getimageunits.php

// Note: All code appearing on the PHP Revolution blog by the blog owner is released under the Hacktivismo Enhanced-Source Software License Agreement (HESSLA), unless otherwise noted.  http://www.hacktivismo.com/about/hessla.php