Paste: factor FFI for libexempi

Author: maali
Mode: factor
Date: Wed, 11 Feb 2009 00:39:46
Plain Text |
! bindings for xmp library exempi
! 2009feb10 maali@socialdynamics.ca

! current filename: work/libexempi/ffi/ffi.factor

USING: accessors alien alien.syntax 
       combinators kernel system math locals ;

IN: libexempi.ffi

<< "exempi" {
    { [ os winnt? ]  [ "libexempi.dll" ] }
    { [ os macosx? ] [ "libexempi.dylib" ] }
    { [ os unix?  ]  [ "libexempi.so" ] }
} cond "cdecl" add-library >>

LIBRARY: exempi

! typedefs.fact
! typedefs.fact - custom
TYPEDEF: uint uint32_t
TYPEDEF: int int32_t
TYPEDEF: longlong int64_t
TYPEDEF: ulonglong uint64_t
! typedefs.fact - structs
TYPEDEF: void* XmpPtr
TYPEDEF: void* XmpFilePtr
TYPEDEF: void* XmpStringPtr
TYPEDEF: void* XmpIteratorPtr
! typedefs.fact - enums
TYPEDEF: uint XmpOpenFileOptions
TYPEDEF: uint XmpCloseFileOptions
TYPEDEF: uint XmpFileType
TYPEDEF: uint XmpIterOptions
TYPEDEF: uint XmpIterSkipOptions
TYPEDEF: uint XmpPropsBits

! consts.fact
: XMP_OPEN_NOOPTION        ( -- n )  HEX: 00000000 ; inline
: XMP_OPEN_READ            ( -- n )  HEX: 00000001 ; inline
: XMP_OPEN_FORUPDATE       ( -- n )  HEX: 00000002 ; inline
: XMP_OPEN_ONLYXMP         ( -- n )  HEX: 00000004 ; inline
: XMP_OPEN_CACHETNAIL      ( -- n )  HEX: 00000008 ; inline
: XMP_OPEN_STRICTLY        ( -- n )  HEX: 00000010 ; inline
: XMP_OPEN_USESMARTHANDLER ( -- n )  HEX: 00000020 ; inline
: XMP_OPEN_USEPACKETSCANNING  ( -- n )  HEX: 00000040 ; inline
: XMP_OPEN_LIMITSCANNING   ( -- n )  HEX: 00000080 ; inline
: XMP_OPEN_INBACKGROUND    ( -- n )  HEX: 10000000   ; inline
: XMP_CLOSE_NOOPTION       ( -- n )  HEX: 0000 ; inline
: XMP_CLOSE_SAFEUPDATE     ( -- n )  HEX: 0001   ; inline
: XMP_FT_PDF       ( -- n )  HEX:  50444620 ; inline
: XMP_FT_PS        ( -- n )  HEX:  50532020 ; inline
: XMP_FT_EPS       ( -- n )  HEX:  45505320 ; inline
: XMP_FT_JPEG      ( -- n )  HEX:  4A504547 ; inline
: XMP_FT_JPEG2K    ( -- n )  HEX:  4A505820 ; inline
: XMP_FT_TIFF      ( -- n )  HEX:  54494646 ; inline
: XMP_FT_GIF       ( -- n )  HEX:  47494620 ; inline
: XMP_FT_PNG       ( -- n )  HEX:  504E4720 ; inline
: XMP_FT_SWF       ( -- n )  HEX:  53574620 ; inline
: XMP_FT_FLA       ( -- n )  HEX:  464C4120 ; inline
: XMP_FT_FLV       ( -- n )  HEX:  464C5620 ; inline
: XMP_FT_MOV       ( -- n )  HEX:  4D4F5620 ; inline
: XMP_FT_AVI       ( -- n )  HEX:  41564920 ; inline
: XMP_FT_CIN       ( -- n )  HEX:  43494E20 ; inline
: XMP_FT_WAV       ( -- n )  HEX:  57415620 ; inline
: XMP_FT_MP3       ( -- n )  HEX:  4D503320 ; inline
: XMP_FT_SES       ( -- n )  HEX:  53455320 ; inline
: XMP_FT_CEL       ( -- n )  HEX:  43454C20 ; inline
: XMP_FT_MPEG      ( -- n )  HEX:  4D504547 ; inline
: XMP_FT_MPEG2     ( -- n )  HEX:  4D503220 ; inline
: XMP_FT_MPEG4     ( -- n )  HEX:  4D503420 ; inline
: XMP_FT_WMAV      ( -- n )  HEX:  574D4156 ; inline
: XMP_FT_AIFF      ( -- n )  HEX:  41494646 ; inline
: XMP_FT_HTML      ( -- n )  HEX:  48544D4C ; inline
: XMP_FT_XML       ( -- n )  HEX:  584D4C20 ; inline
: XMP_FT_TEXT      ( -- n )  HEX:  74657874 ; inline
: XMP_FT_PHOTOSHOP        ( -- n )  HEX:  50534420 ; inline
: XMP_FT_ILLUSTRATOR      ( -- n )  HEX:  41492020 ; inline
: XMP_FT_INDESIGN         ( -- n )  HEX:  494E4444 ; inline
: XMP_FT_AEPROJECT        ( -- n )  HEX:  41455020 ; inline
: XMP_FT_AEPROJTEMPLATE   ( -- n )  HEX:  41455420 ; inline
: XMP_FT_AEFILTERPRESET   ( -- n )  HEX:  46465820 ; inline
: XMP_FT_ENCOREPROJECT    ( -- n )  HEX:  4E434F52 ; inline
: XMP_FT_PREMIEREPROJECT  ( -- n )  HEX:  5052504A ; inline
: XMP_FT_PREMIERETITLE    ( -- n )  HEX:  5052544C ; inline
: XMP_FT_UNKNOWN   ( -- n )  HEX:  20202020    ; inline
: XMP_ITER_CLASSMASK       ( -- n )  HEX:  00FF ; inline
: XMP_ITER_PROPERTIES      ( -- n )  HEX:  0000 ; inline
: XMP_ITER_ALIASES         ( -- n )  HEX:  0001 ; inline
: XMP_ITER_NAMESPACES      ( -- n )  HEX:  0002 ; inline
: XMP_ITER_JUSTCHILDREN    ( -- n )  HEX:  0100 ; inline
: XMP_ITER_JUSTLEAFNODES   ( -- n )  HEX:  0200 ; inline
: XMP_ITER_JUSTLEAFNAME    ( -- n )  HEX:  0400 ; inline
: XMP_ITER_INCLUDEALIASES  ( -- n )  HEX:  0800 ; inline
: XMP_ITER_OMITQUALIFIERS  ( -- n )  HEX:  1000    ; inline
: XMP_ITER_SKIPSUBTREE    ( -- n )  HEX:  0001 ; inline
: XMP_ITER_SKIPSIBLINGS   ( -- n )  HEX:  0002    ; inline
: XMP_PROP_VALUE_IS_URI      ( -- n )  HEX:  00000002 ; inline
: XMP_PROP_HAS_QUALIFIERS    ( -- n )  HEX:  00000010 ; inline
: XMP_PROP_IS_QUALIFIER      ( -- n )  HEX:  00000020 ; inline
: XMP_PROP_HAS_LANG          ( -- n )  HEX:  00000040 ; inline
: XMP_PROP_HAS_TYPE          ( -- n )  HEX:  00000080 ; inline
: XMP_PROP_VALUE_IS_STRUCT  ( -- n )  HEX:  00000100 ; inline
: XMP_PROP_VALUE_IS_ARRAY   ( -- n )  HEX:  00000200 ; inline
: XMP_PROP_ARRAY_IS_UNORDERED  ( -- n )  XMP_PROP_VALUE_IS_ARRAY ; inline
: XMP_PROP_ARRAY_IS_ORDERED  ( -- n )  HEX:  00000400 ; inline
: XMP_PROP_ARRAY_IS_ALT     ( -- n )  HEX:  00000800 ; inline
: XMP_PROP_ARRAY_IS_ALTTEXT  ( -- n )  HEX:  00001000 ; inline
: XMP_PROP_IS_ALIAS          ( -- n )  HEX:  00010000 ; inline
: XMP_PROP_HAS_ALIASES       ( -- n )  HEX:  00020000 ; inline
: XMP_PROP_IS_INTERNAL       ( -- n )  HEX:  00040000 ; inline
: XMP_PROP_IS_STABLE         ( -- n )  HEX:  00100000 ; inline
: XMP_PROP_IS_DERIVED        ( -- n )  HEX:  00200000 ; inline
: XMP_PROP_ARRAY_FORM_MASK   ( -- n )  XMP_PROP_VALUE_IS_ARRAY XMP_PROP_ARRAY_IS_ORDERED bitor  XMP_PROP_ARRAY_IS_ALT bitor  XMP_PROP_ARRAY_IS_ALTTEXT bitor ; inline
: XMP_PROP_COMPOSITE_MASK    ( -- n )  XMP_PROP_VALUE_IS_STRUCT  XMP_PROP_ARRAY_FORM_MASK bitor ; inline
: XMP_IMPL_RESERVED_MASK     ( -- n )  HEX:  70000000    ; inline
: XMP_SERIAL_OMITPACKETWRAPPER    ( -- n )  HEX:  0010 ; inline
: XMP_SERIAL_READONLYPACKET       ( -- n )  HEX:  0020 ; inline
: XMP_SERIAL_USECOMPACTFORMAT     ( -- n )  HEX:  0040 ; inline
: XMP_SERIAL_INCLUDETHUMBNAILPAD  ( -- n )  HEX:  0100 ; inline
: XMP_SERIAL_EXACTPACKETLENGTH    ( -- n )  HEX:  0200 ; inline
: XMP_SERIAL_WRITEALIASCOMMENTS   ( -- n )  HEX:  0400 ; inline
: XMP_SERIAL_OMITALLFORMATTING    ( -- n )  HEX:  0800 ; inline
: _XMP_LITTLEENDIAN_BIT     ( -- n )  HEX:  0001 ; inline
: _XMP_UTF16_BIT            ( -- n )  HEX:  0002 ; inline
: _XMP_UTF32_BIT            ( -- n )  HEX:  0004 ; inline
: XMP_SERIAL_ENCODINGMASK         ( -- n )  HEX:  0007 ; inline
: XMP_SERIAL_ENCODEUTF8           ( -- n )   0 ; inline
: XMP_SERIAL_ENCODEUTF16BIG       ( -- n )  _XMP_UTF16_BIT ; inline
: XMP_SERIAL_ENCODEUTF16LITTLE    ( -- n )  _XMP_UTF16_BIT  _XMP_LITTLEENDIAN_BIT bitor ; inline
: XMP_SERIAL_ENCODEUTF32BIG       ( -- n )  _XMP_UTF32_BIT ; inline
: XMP_SERIAL_ENCODEUTF32LITTLE    ( -- n )  _XMP_UTF32_BIT  _XMP_LITTLEENDIAN_BIT bitor ; inline
: XMP_TZ_WEST  ( -- n )  -1 ; inline
: XMP_TZ_UTC  ( -- n )   0 ; inline
: XMP_TZ_EAST  ( -- n )  1   ; inline
! consts.fact - custom
: XMP_SCHEMA_NODE ( -- n ) HEX: 80000000 ; inline

! structs.fact
C-STRUCT: _XmpDateTime 
    { "int32_t" "year" } 
    { "int32_t" "month" }       
    { "int32_t" "day" }         
    { "int32_t" "hour" }        
    { "int32_t" "minute" }      
    { "int32_t" "second" }      
    { "int32_t" "tzSign" }      
    { "int32_t" "tzHour" }      
    { "int32_t" "tzMinute" }    
    { "int32_t" "nanoSecond" } 
;

! defines.fact
::  XMP_SET_OPTION ( var opt -- x )         var opt bitor ;
::  XMP_CLEAR_OPTION ( var opt -- x )       var opt bitnot bitand ;
::  XMP_TEST_OPTION_SET ( var opt -- x )    var opt bitand 0 = not ;
::  XMP_TEST_OPTION_CLEAR ( var opt -- x )  var opt bitand 0 =  ;
::  XMP_IS_PROP_SIMPLE ( opt -- x )       opt XMP_PROP_COMPOSITE_MASK bitand 0 =  ;
::  XMP_IS_PROP_STRUCT ( opt -- x )       opt XMP_PROP_VALUE_IS_STRUCT bitand 0 = not ;
::  XMP_IS_PROP_ARRAY ( opt -- x )        opt XMP_PROP_VALUE_IS_ARRAY bitand 0 = not ;
::  XMP_IS_ARRAY_UNORDERED ( opt -- x )   opt XMP_PROP_ARRAY_IS_ORDERED bitand 0 =  ;
::  XMP_IS_ARRAY_ORDERED ( opt -- x )     opt XMP_PROP_ARRAY_IS_ORDERED bitand 0 = not ;
::  XMP_IS_ARRAY_ALT ( opt -- x )         opt XMP_PROP_ARRAY_IS_ALT bitand 0 = not ;
::  XMP_IS_ARRAY_ALTTEXT ( opt -- x )     opt XMP_PROP_ARRAY_IS_ALTTEXT bitand 0 = not ;
::  XMP_HAS_PROP_QUALIFIERS ( opt -- x )  opt XMP_PROP_HAS_QUALIFIERS bitand 0 = not ;
::  XMP_IS_PROP_QUALIFIER ( opt -- x )    opt XMP_PROP_IS_QUALIFIER bitand 0 = not ;
::  XMP_HAS_PROP_LANG ( opt -- x )        opt XMP_PROP_HAS_LANG bitand 0 = not ;
::  XMP_IS_NODE_SCHEMA ( opt -- x )       opt XMP_SCHEMA_NODE bitand 0 = not ;
::  XMP_IS_PROP_ALIAS ( opt -- x )        opt XMP_PROP_IS_ALIAS bitand 0 = not ;

! funcs.fact
FUNCTION: bool xmp_init ( ) ;
FUNCTION: void xmp_terminate ( ) ;
FUNCTION: int xmp_get_error ( ) ;
FUNCTION: XmpFilePtr xmp_files_new ( ) ;
FUNCTION: XmpFilePtr xmp_files_open_new ( char* , XmpOpenFileOptions options ) ;
FUNCTION: bool xmp_files_open ( XmpFilePtr xf, char* , XmpOpenFileOptions options ) ;
FUNCTION: bool xmp_files_close ( XmpFilePtr xf, XmpCloseFileOptions options ) ;
FUNCTION: XmpPtr xmp_files_get_new_xmp ( XmpFilePtr xf ) ;
FUNCTION: bool xmp_files_get_xmp ( XmpFilePtr xf, XmpPtr xmp ) ;
FUNCTION: bool xmp_files_can_put_xmp ( XmpFilePtr xf, XmpPtr xmp ) ;
FUNCTION: bool xmp_files_put_xmp ( XmpFilePtr xf, XmpPtr xmp ) ;
FUNCTION: bool xmp_files_free ( XmpFilePtr xf ) ;
FUNCTION: bool xmp_register_namespace ( char* namespaceURI, char* suggestedPrefix, XmpStringPtr registeredPrefix ) ;
FUNCTION: XmpPtr xmp_new_empty ( ) ;
FUNCTION: XmpPtr xmp_new ( char* buffer, size_t len ) ;
FUNCTION: XmpPtr xmp_copy ( XmpPtr xmp ) ;
FUNCTION: bool xmp_free ( XmpPtr xmp ) ;
FUNCTION: bool xmp_parse ( XmpPtr xmp, char* buffer, size_t len ) ;
FUNCTION: bool xmp_serialize ( XmpPtr xmp, XmpStringPtr buffer, uint32_t options, uint32_t padding ) ;
FUNCTION: bool xmp_serialize_and_format ( XmpPtr xmp, XmpStringPtr buffer, uint32_t options, uint32_t padding, char* newline, char* tab, int32_t indent ) ;
FUNCTION: bool xmp_get_property ( XmpPtr xmp, char* schema, char* name, XmpStringPtr property, uint32_t* propsBits ) ;
FUNCTION: bool xmp_get_property_date ( XmpPtr xmp, char* schema, char* name, XmpDateTime* property, uint32_t* propsBits ) ;
FUNCTION: bool xmp_get_property_float ( XmpPtr xmp, char* schema, char* name, double* property, uint32_t* propsBits ) ;
FUNCTION: bool xmp_get_property_bool ( XmpPtr xmp, char* schema, char* name, bool* property, uint32_t* propsBits ) ;
FUNCTION: bool xmp_get_property_int32 ( XmpPtr xmp, char* schema, char* name, int32_t* property, uint32_t* propsBits ) ;
FUNCTION: bool xmp_get_property_int64 ( XmpPtr xmp, char* schema, char* name, int64_t* property, uint32_t* propsBits ) ;
FUNCTION: bool xmp_get_array_item ( XmpPtr xmp, char* schema, char* name, int32_t index, XmpStringPtr property, uint32_t* propsBits ) ;
FUNCTION: bool xmp_set_property ( XmpPtr xmp, char* schema, char* name, char* value, uint32_t optionBits ) ;
FUNCTION: bool xmp_set_property_date ( XmpPtr xmp, char* schema, char* name, XmpDateTime* value, uint32_t optionBits ) ;
FUNCTION: bool xmp_set_property_float ( XmpPtr xmp, char* schema, char* name, double value, uint32_t optionBits ) ;
FUNCTION: bool xmp_set_property_bool ( XmpPtr xmp, char* schema, char* name, bool value, uint32_t optionBits ) ;
FUNCTION: bool xmp_set_property_int32 ( XmpPtr xmp, char* schema, char* name, int32_t value, uint32_t optionBits ) ;
FUNCTION: bool xmp_set_property_int64 ( XmpPtr xmp, char* schema, char* name, int64_t value, uint32_t optionBits ) ;
FUNCTION: bool xmp_set_array_item ( XmpPtr xmp, char* schema, char* name, int32_t index, char* value, uint32_t optionBits ) ;
FUNCTION: bool xmp_append_array_item ( XmpPtr xmp, char* schema, char* name, uint32_t arrayOptions, char* value, uint32_t optionBits ) ;
FUNCTION: bool xmp_delete_property ( XmpPtr xmp, char* schema, char* name ) ;
FUNCTION: bool xmp_has_property ( XmpPtr xmp, char* schema, char* name ) ;
FUNCTION: bool xmp_get_localized_text ( XmpPtr xmp, char* schema, char* name, char* genericLang, char* specificLang, XmpStringPtr actualLang, XmpStringPtr itemValue, uint32_t* propBits ) ;
FUNCTION: bool xmp_set_localized_text ( XmpPtr xmp, char* schema, char* name, char* genericLang, char* specificLang, char* value, uint32_t optionBits ) ;
FUNCTION: bool xmp_delete_localized_text ( XmpPtr xmp, char* schema, char* name, char* genericLang, char* specificLang ) ;
FUNCTION: XmpStringPtr xmp_string_new ( ) ;
FUNCTION: void xmp_string_free ( XmpStringPtr s ) ;
FUNCTION: bool xmp_iterator_free ( XmpIteratorPtr iter ) ;
FUNCTION: bool xmp_iterator_next ( XmpIteratorPtr iter, XmpStringPtr schema, XmpStringPtr propName, XmpStringPtr propValue, uint32_t* options ) ;
FUNCTION: bool xmp_iterator_skip ( XmpIteratorPtr iter, XmpIterSkipOptions options ) ;

Annotation: shell/perl garbage that generated binding file

Author: maali
Mode: shellscript
Date: Wed, 11 Feb 2009 00:43:27
Plain Text |
#!/bin/bash

# filename: ~/factor/work/libexempi/ffi/mk-ffi.sh

# yes disgusting -- run on Debian exempi package 
# to gen bindings for factor

# for XMP factor FFI, order of ops
# header 
# typedefs
# constants
# c structs
# utility #defines -> words
# functions
# 

mkdir -p tmp
cd tmp

echo Creating header.fact
cat <<EOFACT > header.fact
! bindings for xmp library exempi
! 2009feb10 maali@socialdynamics.ca

USING: accessors alien alien.syntax 
       combinators kernel system math locals ;

IN: libexempi.ffi

<< "exempi" {
    { [ os winnt? ]  [ "libexempi.dll" ] }
    { [ os macosx? ] [ "libexempi.dylib" ] }
    { [ os unix?  ]  [ "libexempi.so" ] }
} cond "cdecl" add-library >>

LIBRARY: exempi

EOFACT

echo Creating typedefs.fact
( 
echo '! typedefs.fact' 
echo '! typedefs.fact - custom' 
echo TYPEDEF: uint uint32_t 
echo TYPEDEF: int int32_t 
echo TYPEDEF: longlong int64_t 
echo TYPEDEF: ulonglong uint64_t 
echo '! typedefs.fact - structs' 
grep 'typedef struct .*;' /usr/include/exempi-2.0/exempi/xmp.h | sed 's/typedef /TYPEDEF:/; s/struct//; s/_.*\*/void* /; s/;//' 
echo '! typedefs.fact - enums' 
perl -n0e 'while (m/(typedef enum.*{[^}]*}[ ]*([A-Za-z0-9_]+);)/gm) {print "TYPEDEF: uint ".$2."\n" ; } ' "/usr/include/exempi-2.0/exempi/xmp.h" 
echo 
) > typedefs.fact

echo Creating consts.fact
(
echo '! consts.fact' 
grep '^[[:space:]]*_*XMP.*=.*' "/usr/include/exempi-2.0/exempi/xmp.h"  | sed -e 's|/\*.*\*/||; s|/\*.*$||; s/=/ ( -- n ) /; s/0x/HEX: /; s/,.*$// ; s/^[[:space:]]*\(_*XMP\)/: \1/ ; s/$/ ;/; s/0x// ; s/;/; inline/; s/\+1/1/ ; s/| \([_A-Z]*\)/ \1 bitor/g; ' | sed -e 's/\( [0-9a-fA-F]\+\)U\?L/ \1/g' | grep X | perl -pe 's/\t//g'
echo '! consts.fact - custom'
echo ': XMP_SCHEMA_NODE ( -- n ) HEX: 80000000 ; inline'
echo 
) > consts.fact

echo Creating structs.fact
(
echo '! structs.fact' 
perl -n0e 'while (m/(typedef struct.*{[^}]*})/gm) {print $1."\n" ; } ' "/usr/include/exempi-2.0/exempi/xmp.h" | sed -e 's=/\*.*\*/==; s/;//; s/typedef \+struct/C-STRUCT:/; s/{// ; s/}/;/; s/^[ \t]\+\(\b[A-Za-z0-9_]\+\b\) \(\b[A-Za-z0-9_]\+\b\)/    { "\1" "\2" } /g ; ' 
echo 
) > structs.fact

echo Creating defines.fact
(
echo '! defines.fact'
grep '#define.*(' "/usr/include/exempi-2.0/exempi/xmp.h"  | sed -e 's/.*#define/:: /' | sed -e 's/(\([^()]*opt)\)/ ( \1/; s/,/ /; s/opt)/opt -- x )/; s/$/ ;/; s/(\([^ ]\)/\1/g ; s/(\([^ ]\)/\1/g ; s/(\([^ ]\)/\1/g ; s/\([^ ]\))/\1/g ;  s/\([^ ]\))/\1/g ; s/\([^ ]\))/\1/g ;  s/\([A-Za-z0-9_]\+\) & \([A-Za-z0-9_]\+\)/\1 \2 bitand/g; s/!= \([0-9A-Za-z_]\+\)/\1 = not/; s/== \([0-9A-Za-z_]\+\)/\1 = /; s/|= \([0-9A-Za-z_]\+\)/\1 bitor/ ;  s/~\([0-9A-Za-z_]\+\)/\1 bitnot/ ; s/ &= \(.*\) ;/ \1 bitand ;/'
echo 
) > defines.fact

echo Creating funcs.fact
(
echo '! funcs.fact'
perl -n0e 'while(m/^[         ]*((bool|int|void|XmpFilePtr|XmpStringPtr|XmpPtr) [^(\n]*\([^)]*\)[^;]*;)/xsgm) {print $1."\n" ; } ' "/usr/include/exempi-2.0/exempi/xmp.h"  | perl -n0e 's/\n//sgm ; s/;/;\n/g ; print ' | perl -pe 's/\t+/ /g; s/ +/ /g;' | perl -pe 's/\b([a-zA-Z0-9_]+)[ ]*\*/\1* /g' | perl -pe 's/const//g' | perl -pe 's/(.?)\((.?)/\1 ( \2/g; s/(.?)\)(.?)/\1 ) \2/g; ' | perl -pe 's/^/FUNCTION: / ; s/ +/ /g'
echo 
) > funcs.fact





echo Catting into ffi.factor
cat header.fact typedefs.fact consts.fact structs.fact defines.fact funcs.fact > ffi.factor
cp ffi.factor ..
cd ..

Annotation: bad example of using the XMP FFI

Author: maali
Mode: factor
Date: Wed, 11 Feb 2009 00:47:16
Plain Text |
! rough example code using libexempi FFI
! 
! filename: "exempi-example.factor"
! 
! note make sure there's a '034.jpg' valid jpeg in the current
! working directory

USE: libexempi.ffi

xmp_init

"034.jpg" XMP_OPEN_FORUPDATE xmp_files_open_new "f" set

"f" get xmp_files_get_new_xmp "xmp" set 

xmp_string_new "s" set

"sdi" "sdi" f xmp_register_namespace

"xmp" get "sdi" "license" 
"http://creativeuncommons.org/licenses/by-sa/2.5/" 
XMP_PROP_VALUE_IS_URI 
xmp_set_property

"f" get "xmp" get xmp_files_put_xmp

"f" get XMP_CLOSE_SAFEUPDATE xmp_files_close

"xmp" get xmp_free

xmp_terminate

New Annotation

Summary:
Author:
Mode:
Body: