/trunk/CHANGELOG.md |
---|
6,6 → 6,8 |
- In the Make dialog, if you clicked "OK" and then cancelled the save dialog, you didn't get back to the Make-dialog. Fixed. |
- "Filters Unlimited" filters (FFX files) can now be loaded. However, only the basic Filter Factory commands are supported. |
- You can now also save to the "Premiere Filter Factory" (.pff) file format. |
- Internal change: The resource fork type 'TpLT' is now 'tpLT'. |
- Internal change: Obfuscated data is stored in resource fork 'obFS' instead of 'DATA'. For Windows "OBFS" instead of RCDATA. |
(*) This bug/solution was tested on Windows but needs to be verified and/or implemented on Mac. |
86,7 → 88,7 |
- Fixed problem where 32bit Windows plugin tries to load 64bit standalone plugin |
- Bugfix: Windows Open/Save dialogs: At the title, the first character was missing. Fixed. |
- Internal change: "Manifest" resource gets individualized in standalone plugins |
- Internal change: PiPL/Manifest-template is now stored in 'TpTL' instead of 'DATA'/RCDATA. (But obfuscated data stays at 'DATA'/RCDATA) |
- Internal change: PiPL/Manifest-template is now stored in 'TpLT' instead of 'DATA'/RCDATA. (But obfuscated data stays at 'DATA'/RCDATA) |
- Bugfix: If you called a standalone filter two times, then the main dialog opened (bug introduced in 1.7.0.3) |
- Ifanview/GIMP can now also work with standalone filters |
- If the user tries to open a protected 8BF file, the error message will now state that it can't be opened because the filter is protected |
/trunk/Obfuscation.md |
---|
3,12 → 3,12 |
## Resource location |
Obfuscated standalone filters: |
- Windows resource: RCDATA\16001\0 |
- MacOS resource: 'DATA' 16001 |
- Windows resource: OBFS\16\0 (previously RCDATA\16001\0) |
- MacOS resource: 'obFS' 16 (previously 'DATA' 16001) |
Normal standalone filters: |
- Windows resource: PARM\16\0 |
- MacOS resource: 'PARM' 16 |
- Windows resource: PARM\16\0 (previously PARM\16000\0) |
- MacOS resource: 'PARM' 16 (previously 'PARM' 16000) |
## Implementation |
/trunk/PiPL_macho.r |
---|
36,6 → 36,9 |
#include "PiPL_common.r" |
#if (defined(__x86_64__)) |
CodeMacIntel64 { "PluginMain" }, |
#endif |
#if (defined(__i386__)) |
CodeMacIntel32 { "PluginMain" }, |
#endif |
53,6 → 56,9 |
{ |
#include "pipl_common.r" |
#if (defined(__x86_64__)) |
CodeMacIntel64 { "PluginMain" }, |
#endif |
#if (defined(__i386__)) |
CodeMacIntel32 { "PluginMain" }, |
#endif |
/trunk/ff.h |
---|
51,9 → 51,28 |
CHUNK_ROWS = 64, |
PARM_TYPE = 'PARM', |
PARM_ID = 16, // older versions of Filter Foundry used 16000. Now 16 for compatibility with Filter Factory |
OBFUSCDATA_ID = 16001, |
#ifdef MAC_ENV |
PARM_TYPE = 'PARM', // Note: There is also a Rez type in PARM.h |
PARM_ID_OLD = 16000, |
PARM_ID_NEW = 16, // Filter Factory compatibility |
#else |
PARM_TYPE = "PARM", |
PARM_ID_OLD = MAKEINTRESOURCE(16000), |
PARM_ID_NEW = MAKEINTRESOURCE(16), // Filter Factory compatibility |
#endif |
#ifdef MAC_ENV |
OBFUSCDATA_TYPE_OLD = 'DATA'; |
OBFUSCDATA_TYPE_NEW = 'obFS'; |
OBFUSCDATA_ID_OLD = 16001, |
OBFUSCDATA_ID_NEW = 16, |
#else |
OBFUSCDATA_TYPE_OLD = RT_RCDATA; |
OBFUSCDATA_TYPE_NEW = "OBFS"; |
OBFUSCDATA_ID_OLD = MAKEINTRESOURCE(16001), |
OBFUSCDATA_ID_NEW = MAKEINTRESOURCE(16), |
#endif |
TEXT_FILETYPE = 'TEXT', |
SIG_SIMPLETEXT = 'ttxt', |
PS_FILTER_FILETYPE = '8BFM', |
/trunk/load_mac.c |
---|
28,9 → 28,11 |
Boolean res = false; |
Handle h; |
if( !(h = Get1Resource(PARM_TYPE,PARM_ID)) |
if( !(h = Get1Resource(PARM_TYPE,PARM_ID_NEW)) |
&& !(h = Get1Resource(PARM_TYPE,PARM_ID_OLD)) |
&& readobfusc |
&& (h = Get1Resource('DATA',OBFUSCDATA_ID)) ){ |
&& ((h = Get1Resource(OBFUSCDATA_TYPE_NEW,OBFUSCDATA_ID_NEW)) || |
(h = Get1Resource(OBFUSCDATA_TYPE_OLD,OBFUSCDATA_ID_OLD))) ){ |
HLock(h); |
if(GetHandleSize(h) == sizeof(PARM_T)) { |
deobfusc((PARM_T*)*h); |
/trunk/load_win.c |
---|
42,16 → 42,18 |
Ptr pparm; |
int res = false; |
parm_id = PARM_ID; // default value |
EnumResourceNames(hm,"PARM",enumnames,0); // callback function enumnames() will find the actual found parm_id |
parm_id = 0; |
EnumResourceNames(hm,PARM_TYPE,enumnames,0); // callback function enumnames() will find the actual found parm_id |
// load first PARM resource |
if( (resinfo = FindResource(hm,MAKEINTRESOURCE(parm_id),"PARM")) ){ |
if( (resinfo = FindResource(hm,MAKEINTRESOURCE(parm_id),PARM_TYPE)) ){ |
if ((h = LoadResource(hm, resinfo)) && (pparm = (Ptr)LockResource(h))) { |
res = readPARM(pparm, &gdata->parm, reason, 1 /*Windows format resource*/); |
gdata->obfusc = false; |
} |
}else if( readobfusc && (resinfo = FindResource(hm,MAKEINTRESOURCE(OBFUSCDATA_ID),RT_RCDATA)) ){ |
}else if( readobfusc && |
((resinfo = FindResource(hm,OBFUSCDATA_ID_NEW,OBFUSCDATA_TYPE_NEW)) || |
(resinfo = FindResource(hm,OBFUSCDATA_ID_OLD,OBFUSCDATA_TYPE_OLD))) ){ |
if( (h = LoadResource(hm,resinfo)) && (pparm = (Ptr)LockResource(h)) ){ |
// Fix by DM, 18 Dec 2018: |
// We need to copy the information, because the resource data is read-only |
/trunk/make_mac.c |
---|
108,11 → 108,11 |
HLock(h); |
obfusc((PARM_T*)*h); |
HUnlock(h); |
parm_type = 'DATA'; |
parm_id = OBFUSCDATA_ID; |
parm_type = OBFUSCDATA_TYPE_NEW; |
parm_id = OBFUSCDATA_ID_NEW; |
}else{ |
parm_type = 'PARM'; |
parm_id = PARM_ID; |
parm_type = PARM_TYPE; |
parm_id = PARM_ID_NEW; |
} |
AddResource(h,parm_type,parm_id,"\p"); |
} |
/trunk/make_win.c |
---|
467,14 → 467,14 |
// ====== Obfuscate pparm! |
if (gdata->obfusc) { |
parm_type = RT_RCDATA; |
parm_id = OBFUSCDATA_ID; |
parm_type = OBFUSCDATA_TYPE_NEW; |
parm_id = OBFUSCDATA_ID_NEW; |
// Note: After we have finished updating the resources, we will write <obfuscseed> into the binary code of the 8BF file |
obfuscseed = obfusc(pparm); |
}else{ |
parm_type = "PARM"; |
parm_id = PARM_ID; |
parm_type = PARM_TYPE; |
parm_id = PARM_ID_NEW; |
} |
// ====== Save AETE, PIPL, Manifest and PARM/RCDATA |
/trunk/os_types.md |
---|
29,40 → 29,50 |
| `cTl6` | 1666477110 | 0x63546c36 | Slider 6 (for non-standalone filter) | Telegraphics | |
| `cTl7` | 1666477111 | 0x63546c37 | Slider 7 (for non-standalone filter) | Telegraphics | |
Resource types |
-------------- |
Note: For standalone plugins, all FourCC codes above will be replaced by different hashes based on the parameter data of the filter (except `tELE` and `Fltr`). |
Resource fork types |
------------------- |
| Type | Dec | Hex | Description | Vendor | |
|--------|------------|------------|---------------------------------------------------------|-----------------| |
| `aete` | 1634038885 | 0x61657465 | Apple Event Terminology | Apple | |
| `PiPL` | 1349079116 | 0x5069504c | PlugIn Property List | Adobe | |
| `DATA` | 1145132097 | 0x44415441 | Generic data (replaced by `tpLT` and `obFS`) | ? | |
| `tpLT` | 1953516628 | 0x74704c54 | Template for standalone filter resources | Telegraphics | |
| `DATA` | 1145132097 | 0x44415441 | Generic Data (used in for obfuscated filters) | Apple? | |
| `obFS` | 1868711507 | 0x6f624653 | Filter Foundry obfuscated data | Telegraphics | |
| `PARM` | 1346458189 | 0x5041524d | Filter Factory parameter data (PARM.h) | Adobe (illegal) | |
| `ALRT` | 1095520852 | 0x414c5254 | Alert | Apple | |
| `CITL` | 1128879180 | 0x4349544c | Dialog template | Apple | |
| `CNTL` | 1129206860 | 0x434e544c | Control | Apple | |
| `DLOG` | 1145851719 | 0x444c4f47 | Dialog | Apple | |
| `dlgx` | 1684825976 | 0x646c6778 | Extended Dialog | Apple | |
| `dftb` | 1684436066 | 0x64667462 | Dialog Font Table | Apple | |
| `PICT` | 1346978644 | 0x50494354 | Picture | Apple | |
| `CURS` | 1129665107 | 0x43555253 | Cursor | Apple | |
| `vers` | 1986359923 | 0x76657273 | Version number | Apple | |
| `ALRT` | 1095520852 | 0x414c5254 | Alert (only Macintosh build) | Apple | |
| `DITL` | 1145656396 | 0x4449544c | Dialog template (only Macintosh build) | Apple | |
| `CNTL` | 1129206860 | 0x434e544c | Control (only Macintosh build) | Apple | |
| `DLOG` | 1145851719 | 0x444c4f47 | Dialog (only Macintosh build) | Apple | |
| `dlgx` | 1684825976 | 0x646c6778 | Extended Dialog (only Macintosh build) | Apple | |
| `dftb` | 1684436066 | 0x64667462 | Dialog Font Table (only Macintosh build) | Apple | |
| `PICT` | 1346978644 | 0x50494354 | Picture (only Macintosh build) | Apple | |
| `CURS` | 1129665107 | 0x43555253 | Cursor (only Macintosh build) | Apple | |
| `vers` | 1986359923 | 0x76657273 | Version number (only Macintosh build) | Apple | |
PlugIn Property List (PiPL) related |
----------------------------------- |
Creator codes |
------------- |
| Type | Dec | Hex | Description | Vendor | |
|--------|------------|------------|---------------------------------------------------------|-----------------| |
| `PiPL` | 1349079116 | 0x5069504c | PlugIn Property List | Adobe | |
| `catg` | 1667331175 | 0x63617467 | PiPL property "Category" | Adobe (illegal) | |
| `name` | 1851878757 | 0x6e616d65 | PiPL property "Name" | Adobe (illegal) | |
| `hstm` | 1752396909 | 0x6873746d | PiPL property "Has terminology" | Adobe (illegal) | |
| `8BIM` | 943868237 | 0x3842494d | Adobe Photoshop vendor code | Adobe (illegal) | |
| `wx86` | 2004367414 | 0x77783836 | PIWin32X86CodeProperty (PIGeneral.h) | Adobe (illegal) | |
| `8664` | 943076916 | 0x38363634 | PIWin64X86CodeProperty (PIGeneral.h) | Adobe (illegal) | |
| `kind` | 1802071652 | 0x6b696e64 | PiPL property "Kind" (PIPL.r) | Adobe (illegal) | |
| `8BFM` | 943867469 | 0x3842464d | Adobe Filter module (used in 'kind' property) | Adobe (illegal) | |
| `vers` | 1986359923 | 0x76657273 | PiPL property "Version" (PIPL.r) | Adobe (illegal) | |
| `mode` | 1836016741 | 0x6d6f6465 | PiPL property "SupportedModes" (PIPL.r) | Adobe (illegal) | |
| `ms32` | 1836266290 | 0x6d733332 | PiPL property "PlugInMaxSize" (PIPL.r) | Adobe (illegal) | |
| `fici` | 1718182761 | 0x66696369 | PiPL property "FilterCaseInfo" (PIPL.r) | Adobe (illegal) | |
| `8BIM` | 943868237 | 0x3842494d | Adobe Photoshop | Adobe | |
| `8BFM` | 943867469 | 0x3842464d | Adobe Filter module (used in `kind` PiPL property) | Adobe | |
PlugIn Property List (PiPL) properties |
-------------------------------------- |
| C.code | Prpty. | Dec | Hex | Description | Vendor | |
|--------|--------|-----------------------|-----------------------|---------------------------------------------------------|-----------------| |
| `8BIM` | `catg` | 943868237 1667331175 | 0x3842494d 0x63617467 | PiPL property "Category" | Adobe | |
| `8BIM` | `name` | 943868237 1851878757 | 0x3842494d 0x6e616d65 | PiPL property "Name" | Adobe | |
| `8BIM` | `hstm` | 943868237 1752396909 | 0x3842494d 0x6873746d | PiPL property "Has terminology" | Adobe | |
| `8BIM` | `wx86` | 943868237 2004367414 | 0x3842494d 0x77783836 | PiPL property PIWin32X86CodeProperty (PIGeneral.h) | Adobe | |
| `8BIM` | `8664` | 943868237 943076916 | 0x3842494d 0x38363634 | PiPL property PIWin64X86CodeProperty (PIGeneral.h) | Adobe | |
| `8BIM` | `kind` | 943868237 1802071652 | 0x3842494d 0x6b696e64 | PiPL property "Kind" (PIPL.r) | Adobe | |
| `8BIM` | `vers` | 943868237 1986359923 | 0x3842494d 0x76657273 | PiPL property "Version" (PIPL.r) | Adobe | |
| `8BIM` | `mode` | 943868237 1836016741 | 0x3842494d 0x6d6f6465 | PiPL property "SupportedModes" (PIPL.r) | Adobe | |
| `8BIM` | `ms32` | 943868237 1836266290 | 0x3842494d 0x6d733332 | PiPL property "PlugInMaxSize" (PIPL.r) | Adobe | |
| `8BIM` | `fici` | 943868237 1718182761 | 0x3842494d 0x66696369 | PiPL property "FilterCaseInfo" (PIPL.r) | Adobe | |
/trunk/os_types.php |
---|
38,39 → 38,49 |
ostype_info('cTl7', 'Slider 7 (for non-standalone filter)', 'Telegraphics'); |
ostype_footer(); |
ostype_header("Resource types"); |
echo "Note: For standalone plugins, all FourCC codes above will be replaced "; |
echo "by different hashes based on the parameter data of the filter (except `tELE` and `Fltr`).\n\n"; |
// TODO: also display Windows types, e.g. RT_RCDATA = 'DATA' ? |
ostype_header("Resource fork types"); |
ostype_info('aete', 'Apple Event Terminology', 'Apple'); // https://developer.apple.com/library/archive/documentation/mac/pdf/Interapplication_Communication/AE_Term_Resources.pdf |
ostype_info('tpLT', 'Template for standalone filter resources', 'Telegraphics'); |
ostype_info('DATA', 'Generic Data (used in for obfuscated filters)', 'Apple?'); |
//ostype_info('PiMI', 'Plug-in Meta Information', 'Adobe'); |
ostype_info('PiPL', 'PlugIn Property List', 'Adobe'); |
ostype_info('DATA', 'Generic data (replaced by `tpLT` and `obFS`)', '?'); |
ostype_info('tpLT', 'Template for standalone filter resources', 'Telegraphics'); // actually defined by ViaThinkSoft for Filter Foundry |
ostype_info('obFS', 'Filter Foundry obfuscated data', 'Telegraphics'); // actually defined by ViaThinkSoft |
ostype_info('PARM', 'Filter Factory parameter data (PARM.h)', 'Adobe'); |
// https://developer.apple.com/library/archive/documentation/mac/pdf/ResEditReference.pdf |
// https://developer.apple.com/library/archive/documentation/mac/pdf/MoreMacintoshToolbox.pdf |
ostype_info('ALRT', 'Alert', 'Apple'); |
ostype_info('CITL', 'Dialog template', 'Apple'); |
ostype_info('CNTL', 'Control', 'Apple'); |
ostype_info('DLOG', 'Dialog', 'Apple'); |
ostype_info('dlgx', 'Extended Dialog', 'Apple'); |
ostype_info('dftb', 'Dialog Font Table', 'Apple'); |
ostype_info('PICT', 'Picture', 'Apple'); |
ostype_info('CURS', 'Cursor', 'Apple'); |
ostype_info('vers', 'Version number', 'Apple'); |
ostype_info('ALRT', 'Alert (only Macintosh build)', 'Apple'); |
ostype_info('DITL', 'Dialog template (only Macintosh build)', 'Apple'); |
ostype_info('CNTL', 'Control (only Macintosh build)', 'Apple'); |
ostype_info('DLOG', 'Dialog (only Macintosh build)', 'Apple'); |
ostype_info('dlgx', 'Extended Dialog (only Macintosh build)', 'Apple'); |
ostype_info('dftb', 'Dialog Font Table (only Macintosh build)', 'Apple'); |
ostype_info('PICT', 'Picture (only Macintosh build)', 'Apple'); |
ostype_info('CURS', 'Cursor (only Macintosh build)', 'Apple'); |
ostype_info('vers', 'Version number (only Macintosh build)', 'Apple'); |
ostype_footer(); |
ostype_header("PlugIn Property List (PiPL) related"); |
//ostype_info('PiMI', 'Plug-in Meta Information', 'Adobe'); |
ostype_info('PiPL', 'PlugIn Property List', 'Adobe'); |
ostype_info('catg', 'PiPL property "Category"', 'Adobe'); |
ostype_info('name', 'PiPL property "Name"', 'Adobe'); |
ostype_info('hstm', 'PiPL property "Has terminology"', 'Adobe'); |
ostype_info('8BIM', 'Adobe Photoshop vendor code', 'Adobe'); // was '8B##" assigned to Adobe by Apple? |
ostype_info('wx86', 'PIWin32X86CodeProperty (PIGeneral.h)', 'Adobe'); |
ostype_info('8664', 'PIWin64X86CodeProperty (PIGeneral.h)', 'Adobe'); |
ostype_info('kind', 'PiPL property "Kind" (PIPL.r)', 'Adobe'); |
ostype_info('8BFM', 'Adobe Filter module (used in \'kind\' property)', 'Adobe'); // was '8B##" assigned to Adobe by Apple? |
ostype_info('vers', 'PiPL property "Version" (PIPL.r)', 'Adobe'); |
ostype_info('mode', 'PiPL property "SupportedModes" (PIPL.r)', 'Adobe'); |
ostype_info('ms32', 'PiPL property "PlugInMaxSize" (PIPL.r)', 'Adobe'); |
ostype_info('fici', 'PiPL property "FilterCaseInfo" (PIPL.r)', 'Adobe'); |
ostype_header("Creator codes"); |
ostype_info('8BIM', 'Adobe Photoshop', 'Adobe'); |
ostype_info('8BFM', 'Adobe Filter module (used in `kind` PiPL property)', 'Adobe'); |
ostype_footer(); |
pipl_property_header("PlugIn Property List (PiPL) properties"); |
pipl_property_info('8BIM', 'catg', 'PiPL property "Category"', 'Adobe'); |
pipl_property_info('8BIM', 'name', 'PiPL property "Name"', 'Adobe'); |
pipl_property_info('8BIM', 'hstm', 'PiPL property "Has terminology"', 'Adobe'); |
pipl_property_info('8BIM', 'wx86', 'PiPL property PIWin32X86CodeProperty (PIGeneral.h)', 'Adobe'); |
pipl_property_info('8BIM', '8664', 'PiPL property PIWin64X86CodeProperty (PIGeneral.h)', 'Adobe'); |
pipl_property_info('8BIM', 'kind', 'PiPL property "Kind" (PIPL.r)', 'Adobe'); |
pipl_property_info('8BIM', 'vers', 'PiPL property "Version" (PIPL.r)', 'Adobe'); |
pipl_property_info('8BIM', 'mode', 'PiPL property "SupportedModes" (PIPL.r)', 'Adobe'); |
pipl_property_info('8BIM', 'ms32', 'PiPL property "PlugInMaxSize" (PIPL.r)', 'Adobe'); |
pipl_property_info('8BIM', 'fici', 'PiPL property "FilterCaseInfo" (PIPL.r)', 'Adobe'); |
pipl_property_footer(); |
# ------------------------------------------------------------------------------ |
$out = ob_get_contents(); |
89,16 → 99,21 |
$dec = str_pad($dec, strlen(hexdec('ffffffff')), " ", STR_PAD_LEFT); |
$desc = str_pad($desc, DESC_WIDTH, " ", STR_PAD_RIGHT); |
$illegal = false; |
if ($vendor != '?') { |
$is_all_uppercase = strtoupper($type) == $type; |
$is_all_lowercase = strtolower($type) == $type; |
$starts_with_uppercase = strtoupper($type[0]) == $type[0]; |
if (($is_all_uppercase || $is_all_lowercase) && (strpos($vendor,'Apple') === false)) $vendor .= ' (illegal)'; |
else if (!($is_all_uppercase || $is_all_lowercase) && (strpos($vendor,'Apple') !== false)) $vendor .= ' (illegal)'; |
else if ($starts_with_uppercase && !$is_all_uppercase && (strpos($vendor,'Adobe') === false)) $vendor .= ' (illegal)'; |
else if (!$starts_with_uppercase && !$is_all_uppercase && (strpos($vendor,'Adobe') !== false)) $vendor .= ' (illegal)'; |
if (($is_all_uppercase || $is_all_lowercase) && (strpos($vendor,'Apple') === false)) $illegal = true; |
else if (!($is_all_uppercase || $is_all_lowercase) && (strpos($vendor,'Apple') !== false)) $illegal = true; |
else if ($starts_with_uppercase && !$is_all_uppercase && (strpos($vendor,'Adobe') === false)) $illegal = true; |
else if (!$starts_with_uppercase && !$is_all_uppercase && (strpos($vendor,'Adobe') !== false)) $illegal = true; |
} |
// In re 8B##, we just assume that 8B## was legally assigned to Adobe by Apple |
// Note: "8B" sounds like "Adobe" |
if ((substr($type,0,2) === '8B') && (strpos($vendor,'Adobe') !== false)) $illegal = false; |
if ($illegal) $vendor .= ' (illegal)'; |
$vendor = str_pad($vendor, VENDOR_WIDTH, " ", STR_PAD_RIGHT); |
echo "| `$type` | $dec | $hex | $desc | $vendor |\n"; |
114,5 → 129,42 |
echo "\n"; |
echo "| Type | Dec | Hex | ".str_pad('Description', DESC_WIDTH, " ", STR_PAD_RIGHT)." | ".str_pad('Vendor', VENDOR_WIDTH, " ", STR_PAD_RIGHT)." |\n"; |
echo "|--------|------------|------------|".str_repeat('-', DESC_WIDTH+2)."|".str_repeat('-', VENDOR_WIDTH+2)."|\n"; |
} |
# ------------------------------------------------------------------------------ |
function pipl_property_info($ven, $type, $desc, $vendor) { |
$vdec = 0; |
for ($i=0;$i<4;$i++) $vdec = ($vdec<<8) + ord($ven[$i]); |
$vhex = "0x".str_pad(dechex($vdec), 8, "0", STR_PAD_LEFT); |
$vdec = str_pad($vdec, strlen(hexdec('ffffffff')), " ", STR_PAD_LEFT); |
$dec = 0; |
for ($i=0;$i<4;$i++) $dec = ($dec<<8) + ord($type[$i]); |
$hex = "0x".str_pad(dechex($dec), 8, "0", STR_PAD_LEFT); |
$dec = str_pad($dec, strlen(hexdec('ffffffff')), " ", STR_PAD_LEFT); |
$desc = str_pad($desc, DESC_WIDTH, " ", STR_PAD_RIGHT); |
// In re 8B##, we just assume that 8B## was legally assigned to Adobe by Apple |
// Note: "8B" sounds like "Adobe" |
$illegal = (substr($ven,0,2) === '8B') != (strpos($vendor,'Adobe') !== false); |
if ($illegal) $vendor .= ' (illegal)'; |
$vendor = str_pad($vendor, VENDOR_WIDTH, " ", STR_PAD_RIGHT); |
echo "| `$ven` | `$type` | $vdec $dec | $vhex $hex | $desc | $vendor |\n"; |
} |
function pipl_property_footer() { |
echo "\n"; |
} |
function pipl_property_header($title) { |
echo "$title\n"; |
echo str_repeat('-',strlen($title))."\n"; |
echo "\n"; |
echo "| C.code | Prpty. | Dec | Hex | ".str_pad('Description', DESC_WIDTH, " ", STR_PAD_RIGHT)." | ".str_pad('Vendor', VENDOR_WIDTH, " ", STR_PAD_RIGHT)." |\n"; |
echo "|--------|--------|-----------------------|-----------------------|".str_repeat('-', DESC_WIDTH+2)."|".str_repeat('-', VENDOR_WIDTH+2)."|\n"; |
} |