Codebase list exempi / 4aecc6a
Merge branch 'upstream' Michael Biebl 15 years ago
29 changed file(s) with 1188 addition(s) and 37 deletion(s). Raw diff Collapse all Expand all
0 The package is based on Adobe XMP SDK 4.1.1
0 The package is based on Adobe XMP SDK 4.1.1.
1
12
23 Other authors are:
4
35 Hubert Figuiere <hub@figuiere.net>
4
6 Ian Jacobi
7 Jason Kivlighn
0 2007-06-29 Hubert Figuiere <hub@figuiere.net>
0 2007-08-14 Hubert Figuiere <hub@figuiere.net>
11
2 * rpm/SLED10.spec: Added .spec for SLED10 packaging
3 (only in git)
2 * New API xmp_delete_localized_text(), by Ian Jacobi.
43
5 2007-06-28 Hubert Figuiere <hub@figuiere.net>
4 2007-08-13 Hubert Figuiere <hub@figuiere.net>
65
7 * New API wrapped: xmp_serialize{,_and_format}() and the
8 corresponding option bits
6 * source/XMPCore/, public/include/: new call DeleteLocalizedText()
7 by Ian Jacobi.
8
9 * New API xmp_append_array_item(), xmp_delete_property(),
10 xmp_has_property(), xmp_get_localized_text(),
11 xmp_set_localized_text() by Ian Jacobi.
12 * exempi.cpp (xmp_files_open_new): Handle exception properly
13 by Ian Jacobi.
914
10 * New API wrapped: xmp_get_array_item()
15 2007-08-12 Hubert Figuiere <hub@figuiere.net>
1116
17 * Added GIF smart handler support by Ian Jacobi.
18
19 * source/XMPCore/XMPCore_Impl.hpp (kXMPCoreName): Add Exempi
20 name to clearly identify when Exempi is generating.
21
0 1.99.4
1
2 - New: GIF Files smart handlers
3 - New: API xmp_append_array_item(), xmp_delete_property(),
4 xmp_has_property(), xmp_get_localized_text(),
5 xmp_set_localized_text()
6 - New: API xmp_delete_localized_text()
7 - New: Exempi will be visible in the "generator" string of the XMP packet.
8 - Bug: xmp_files_open_new() will handle exceptions properly
9
10 1.99.3
11
12 - New: API xmp_serialize{,_and_format}() and the
13 corresponding option bits
14 - New API xmp_get_array_item()
15
16 1.99.2
17
18 - New: API xmp_copy()
19 - New: API xmp_set_property2(), xmp_set_array_item()
20 and xmp_get_error()
21 - New: API xmp_get_property_and_bits()
22 - Bug: xmp_files_get_xmp() handle exceptions properly.
23
24 1.99.1
25
26 - Bug: store the TIFF tag as BYTE and not UNDEFINED
27 to comply with the spec.
28 - Bug: more exception catched.
29 - New: added NS_CC namespace
30 - New: API xmp_register_namespace()
31
32 1.99.0
33
34 Initial release of the 2.0 series. Based on Adobe XMP SDK 4.1.1
35
22752275
22762276 # Define the identity of the package.
22772277 PACKAGE=exempi
2278 VERSION=1.99.3
2278 VERSION=1.99.4
22792279
22802280
22812281 cat >>confdefs.h <<_ACEOF
24472447
24482448 EXEMPI_REVISION=0
24492449
2450 EXEMPI_AGE=3
2451
2452 EXEMPI_CURRENT=5
2450 EXEMPI_AGE=4
2451
2452 EXEMPI_CURRENT=6
24532453
24542454 EXEMPI_CURRENT_MIN=`expr $EXEMPI_CURRENT - $EXEMPI_AGE`
24552455
00 AC_PREREQ(2.50)
11 AC_INIT(exempi/xmp.h)
2 AM_INIT_AUTOMAKE(exempi, 1.99.3)
2 AM_INIT_AUTOMAKE(exempi, 1.99.4)
33 AM_MAINTAINER_MODE
44
55
2929 dnl 1.99.1 is the revision 3 1 0
3030 dnl 1.99.2 is the revision 4 2 0
3131 dnl 1.99.3 is the revision 5 3 0
32 dnl 1.99.4 is the revision 6 4 0
3233 AC_SUBST([EXEMPI_REVISION], [0])
33 AC_SUBST([EXEMPI_AGE], [3])
34 AC_SUBST([EXEMPI_CURRENT], [5])
34 AC_SUBST([EXEMPI_AGE], [4])
35 AC_SUBST([EXEMPI_CURRENT], [6])
3536 AC_SUBST([EXEMPI_CURRENT_MIN],
3637 [`expr $EXEMPI_CURRENT - $EXEMPI_AGE`])
3738 AC_SUBST([EXEMPI_VERSION_INFO],
126126
127127 XmpFilePtr xmp_files_open_new(const char *path, XmpOpenFileOptions options)
128128 {
129 SXMPFiles *txf = new SXMPFiles(path, XMP_FT_UNKNOWN, options);
129 SXMPFiles *txf = NULL;
130 try {
131 txf = new SXMPFiles(path, XMP_FT_UNKNOWN, options);
132 }
133 catch(const XMP_Error & e) {
134 set_error(e);
135 }
130136
131137 return (XmpFilePtr)txf;
132138 }
298304 SXMPMeta *txmp = (SXMPMeta *)xmp;
299305 delete txmp;
300306 }
301
302307
303308
304309 bool xmp_get_property(XmpPtr xmp, const char *schema,
400405 return ret;
401406 }
402407
408 bool xmp_append_array_item(XmpPtr xmp, const char *schema, const char *name,
409 uint32_t arrayOptions, const char *value,
410 uint32_t optionBits)
411 {
412 bool ret = true;
413 SXMPMeta *txmp = (SXMPMeta *)xmp;
414 try {
415 txmp->AppendArrayItem(schema, name, arrayOptions, value,
416 optionBits);
417 }
418 catch(const XMP_Error & e) {
419 set_error(-e.GetID());
420 ret = false;
421 std::cerr << e.GetErrMsg() << std::endl;
422 }
423 catch(...) {
424 ret = false;
425 }
426 return ret;
427 }
428
429 bool xmp_delete_property(XmpPtr xmp, const char *schema, const char *name)
430 {
431 bool ret = true;
432 SXMPMeta *txmp = (SXMPMeta *)xmp;
433 try {
434 txmp->DeleteProperty(schema, name);
435 }
436 catch(const XMP_Error & e) {
437 set_error(-e.GetID());
438 ret = false;
439 std::cerr << e.GetErrMsg() << std::endl;
440 }
441 catch(...) {
442 ret = false;
443 }
444 return ret;
445 }
446
447 bool xmp_has_property(XmpPtr xmp, const char *schema, const char *name)
448 {
449 bool ret = true;
450 SXMPMeta *txmp = (SXMPMeta *)xmp;
451 try {
452 ret = txmp->DoesPropertyExist(schema, name);
453 }
454 catch(const XMP_Error & e) {
455 set_error(-e.GetID());
456 ret = false;
457 std::cerr << e.GetErrMsg() << std::endl;
458 }
459 catch(...) {
460 ret = false;
461 }
462 return ret;
463 }
464
465 bool xmp_get_localized_text(XmpPtr xmp, const char *schema, const char *name,
466 const char *genericLang, const char *specificLang,
467 XmpStringPtr actualLang, XmpStringPtr itemValue,
468 uint32_t *propsBits)
469 {
470 bool ret = false;
471 try {
472 SXMPMeta *txmp = (SXMPMeta *)xmp;
473 XMP_OptionBits optionBits;
474 ret = txmp->GetLocalizedText(schema, name, genericLang,
475 specificLang, STRING(actualLang),
476 STRING(itemValue), &optionBits);
477 if(propsBits) {
478 *propsBits = optionBits;
479 }
480 }
481 catch(const XMP_Error & e) {
482 set_error(e);
483 ret = false;
484 }
485 return ret;
486 }
487
488 bool xmp_set_localized_text(XmpPtr xmp, const char *schema, const char *name,
489 const char *genericLang, const char *specificLang,
490 const char *value, uint32_t optionBits)
491 {
492 bool ret = true;
493 SXMPMeta *txmp = (SXMPMeta *)xmp;
494 try {
495 txmp->SetLocalizedText(schema, name, genericLang, specificLang,
496 value, optionBits);
497 }
498 catch(const XMP_Error & e) {
499 set_error(-e.GetID());
500 ret = false;
501 std::cerr << e.GetErrMsg() << std::endl;
502 }
503 catch(...) {
504 ret = false;
505 }
506 return ret;
507 }
508
509
510 bool xmp_delete_localized_text(XmpPtr xmp, const char *schema,
511 const char *name, const char *genericLang,
512 const char *specificLang)
513 {
514 bool ret = true;
515 SXMPMeta *txmp = (SXMPMeta *)xmp;
516 try {
517 txmp->DeleteLocalizedText(schema, name, genericLang,
518 specificLang);
519 }
520 catch(const XMP_Error & e) {
521 set_error(-e.GetID());
522 ret = false;
523 std::cerr << e.GetErrMsg() << std::endl;
524 }
525 catch(...) {
526 ret = false;
527 }
528 return ret;
529 }
530
531
532
403533 XmpStringPtr xmp_string_new()
404534 {
405535 return (XmpStringPtr)new std::string;
173173
174174 XmpStringPtr the_prop = xmp_string_new();
175175
176 BOOST_CHECK(xmp_has_property(xmp, NS_TIFF, "Make"));
177 BOOST_CHECK_EQUAL(xmp_has_property(xmp, NS_TIFF, "Foo"), false);
178
176179 BOOST_CHECK(xmp_get_property(xmp, NS_TIFF, "Make", the_prop));
177180 BOOST_CHECK_EQUAL(strcmp("Canon", xmp_string_cstr(the_prop)), 0);
178181
195198 BOOST_CHECK_EQUAL(bits, 0x50);
196199 BOOST_CHECK(XMP_HAS_PROP_QUALIFIERS(bits));
197200
198 BOOST_CHECK(xmp_set_array_item(xmp, NS_DC, "rights", 2,
201 XmpStringPtr the_lang = xmp_string_new();
202 BOOST_CHECK(xmp_get_localized_text(xmp, NS_DC, "rights",
203 NULL, "x-default",
204 the_lang, the_prop, &bits));
205 BOOST_CHECK_EQUAL(strcmp("x-default", xmp_string_cstr(the_lang)), 0);
206 BOOST_CHECK(xmp_set_localized_text(xmp, NS_DC, "rights",
207 "en", "en-CA",
208 xmp_string_cstr(the_prop), 0));
209 BOOST_CHECK(xmp_get_localized_text(xmp, NS_DC, "rights",
210 "en", "en-US",
211 the_lang, the_prop, &bits));
212 BOOST_CHECK(strcmp("en-US", xmp_string_cstr(the_lang)) != 0);
213 BOOST_CHECK_EQUAL(strcmp("en-CA", xmp_string_cstr(the_lang)), 0);
214
215 BOOST_CHECK(xmp_delete_localized_text(xmp, NS_DC, "rights",
216 "en", "en-CA"));
217 BOOST_CHECK(xmp_has_property(xmp, NS_DC, "rights[1]"));
218 BOOST_CHECK_EQUAL(xmp_has_property(xmp, NS_DC, "rights[2]"), false);
219
220
221 xmp_string_free(the_lang);
222
223 BOOST_CHECK(xmp_set_array_item(xmp, NS_DC, "creator", 2,
199224 "foo", 0));
200 BOOST_CHECK(xmp_get_array_item(xmp, NS_DC, "rights", 2,
225 BOOST_CHECK(xmp_get_array_item(xmp, NS_DC, "creator", 2,
201226 the_prop, &bits));
202227 BOOST_CHECK(XMP_IS_PROP_SIMPLE(bits));
203228 BOOST_CHECK_EQUAL(strcmp("foo", xmp_string_cstr(the_prop)), 0);
229 BOOST_CHECK(xmp_append_array_item(xmp, NS_DC, "creator", 0, "bar", 0));
230
231 BOOST_CHECK(xmp_get_array_item(xmp, NS_DC, "creator", 3,
232 the_prop, &bits));
233 BOOST_CHECK(XMP_IS_PROP_SIMPLE(bits));
234 BOOST_CHECK_EQUAL(strcmp("bar", xmp_string_cstr(the_prop)), 0);
235
236 BOOST_CHECK(xmp_delete_property(xmp, NS_DC, "creator[3]"));
237 BOOST_CHECK_EQUAL(xmp_has_property(xmp, NS_DC, "creator[3]"), false);
204238
205239 xmp_string_free(the_prop);
206240 xmp_free(xmp);
88 exit 255
99 fi
1010
11 SAMPLES="BlueSquare.ai BlueSquare.eps BlueSquare.jpg BlueSquare.mp3 BlueSquare.png BlueSquare.tif BlueSquare.avi BlueSquare.indd BlueSquare.pdf BlueSquare.psd BlueSquare.wav"
11 SAMPLES="BlueSquare.ai BlueSquare.eps BlueSquare.gif BlueSquare.jpg BlueSquare.mp3 BlueSquare.png BlueSquare.tif BlueSquare.avi BlueSquare.indd BlueSquare.pdf BlueSquare.psd BlueSquare.wav"
1212 SAMPLES_DIR=$srcdir/../../samples/BlueSquares
1313 DUMPMAINXMP_PROG=../../samples/source/dumpmainxmp
1414
372372 * @param indent the initial indentation level
373373 * @return TRUE if success.
374374 */
375 bool xmp_serialize_and_format(XmpPtr xmp, XmpStringPtr buffer,
375 bool xmp_serialize_and_format(XmpPtr xmp, XmpStringPtr buffer,
376376 uint32_t options,
377377 uint32_t padding, const char *newline,
378378 const char *tab, int32_t indent);
431431 const char *name, int32_t index, const char *value,
432432 uint32_t optionBits);
433433
434 /** Append a value to the XMP Property array in the XMP Packet provided
435 * @param xmp the XMP packet
436 * @param schema the schema of the property
437 * @param name the name of the property
438 * @param arrayOptions option bits of the parent array
439 * @param value null-terminated string
440 * @param optionBits option bits of the value itself.
441 */
442 bool xmp_append_array_item(XmpPtr xmp, const char *schema, const char *name,
443 uint32_t arrayOptions, const char *value,
444 uint32_t optionBits);
445
446 /** Delete a property from the XMP Packet provided
447 * @param xmp the XMP packet
448 * @param schema the schema of the property
449 * @param name the name of the property
450 */
451 bool xmp_delete_property(XmpPtr xmp, const char *schema, const char *name);
452
453 /** Determines if a property exists in the XMP Packet provided
454 * @param xmp the XMP packet
455 * @param schema the schema of the property. Can't be NULL or empty.
456 * @param name the name of the property. Can't be NULL or empty.
457 * @return true is the property exists
458 */
459 bool xmp_has_property(XmpPtr xmp, const char *schema, const char *name);
460
461 /** Get a localised text from a localisable property.
462 * @param xmp the XMP packet
463 * @param schema the schema
464 * @param name the property name.
465 * @param genericLang the generic language you may want as a fall back.
466 * Can be NULL or empty.
467 * @param specificLang the specific language you want. Can't be NULL or empty.
468 * @param actualLang the actual language of the value. Can be NULL if
469 * not wanted.
470 * @param itemValue the localized value. Can be NULL if not wanted.
471 * @param propBits the options flags describing the property. Can be NULL.
472 * @return true if found, false otherwise.
473 */
474 bool xmp_get_localized_text(XmpPtr xmp, const char *schema, const char *name,
475 const char *genericLang, const char *specificLang,
476 XmpStringPtr actualLang, XmpStringPtr itemValue,
477 uint32_t *propBits);
478
479
480 /** Set a localised text in a localisable property.
481 * @param xmp the XMP packet
482 * @param schema the schema
483 * @param name the property name.
484 * @param genericLang the generic language you may want to set too.
485 * Can be NULL or empty.
486 * @param specificLang the specific language you want. Can't be NULL or empty.
487 * @param itemValue the localized value. Cannot be NULL.
488 * @param propBits the options flags describing the property.
489 * @return true if set, false otherwise.
490 */
491 bool xmp_set_localized_text(XmpPtr xmp, const char *schema, const char *name,
492 const char *genericLang, const char *specificLang,
493 const char *value, uint32_t optionBits);
494
495
496
497 bool xmp_delete_localized_text(XmpPtr xmp, const char *schema,
498 const char *name, const char *genericLang,
499 const char *specificLang);
500
434501 /** Instanciate a new string
435502 * @return the new instance. Must be freed with
436503 * xmp_string_free()
11911191 const tStringObj & itemValue,
11921192 XMP_OptionBits options = 0 );
11931193
1194 void
1195 DeleteLocalizedText ( XMP_StringPtr schemaNS,
1196 XMP_StringPtr altTextName,
1197 XMP_StringPtr genericLang,
1198 XMP_StringPtr specificLang );
1199
11941200 /// @}
11951201
11961202 // =============================================================================================
678678 this->SetLocalizedText ( schemaNS, altTextName, genericLang, specificLang, itemValue.c_str(), options );
679679 }
680680
681 XMP_MethodIntro(TXMPMeta,void)::
682 DeleteLocalizedText ( XMP_StringPtr schemaNS,
683 XMP_StringPtr altTextName,
684 XMP_StringPtr genericLang,
685 XMP_StringPtr specificLang )
686 {
687 WrapCheckVoid ( zXMPMeta_DeleteLocalizedText_1 ( schemaNS, altTextName, genericLang, specificLang ) );
688 }
689
681690 // -------------------------------------------------------------------------------------------------
682691
683692 XMP_MethodIntro(TXMPMeta,bool)::
118118
119119 #define zXMPMeta_SetLocalizedText_1(schemaNS,altTextName,genericLang,specificLang,itemValue,options) \
120120 WXMPMeta_SetLocalizedText_1 ( this->xmpRef, schemaNS, altTextName, genericLang, specificLang, itemValue, options, &wResult )
121
122 #define zXMPMeta_DeleteLocalizedText_1(schemaNS,altTextName,genericLang,specificLang) \
123 WXMPMeta_DeleteLocalizedText_1 ( this->xmpRef, schemaNS, altTextName, genericLang, specificLang, &wResult )
121124
122125 #define zXMPMeta_GetProperty_Bool_1(schemaNS,propName,propValue,options) \
123126 WXMPMeta_GetProperty_Bool_1 ( this->xmpRef, schemaNS, propName, propValue, options, &wResult )
459462 XMP_OptionBits options,
460463 WXMP_Result * wResult );
461464
465 extern void
466 WXMPMeta_DeleteLocalizedText_1 ( XMPMetaRef xmpRef,
467 XMP_StringPtr schemaNS,
468 XMP_StringPtr altTextName,
469 XMP_StringPtr genericLang,
470 XMP_StringPtr specificLang,
471 WXMP_Result * wResult );
472
462473 // -------------------------------------------------------------------------------------------------
463474
464475 extern void
3434 #
3535
3636
37 EXTRA_DIST=BlueSquare.ai BlueSquare.eps BlueSquare.jpg BlueSquare.mp3 BlueSquare.png BlueSquare.tif\
37 EXTRA_DIST=BlueSquare.ai BlueSquare.eps BlueSquare.gif BlueSquare.jpg BlueSquare.mp3 BlueSquare.png BlueSquare.tif\
3838 BlueSquare.avi BlueSquare.indd BlueSquare.mov BlueSquare.pdf BlueSquare.psd BlueSquare.wav
196196 target_alias = @target_alias@
197197 top_builddir = @top_builddir@
198198 top_srcdir = @top_srcdir@
199 EXTRA_DIST = BlueSquare.ai BlueSquare.eps BlueSquare.jpg BlueSquare.mp3 BlueSquare.png BlueSquare.tif\
199 EXTRA_DIST = BlueSquare.ai BlueSquare.eps BlueSquare.gif BlueSquare.jpg BlueSquare.mp3 BlueSquare.png BlueSquare.tif\
200200 BlueSquare.avi BlueSquare.indd BlueSquare.mov BlueSquare.pdf BlueSquare.psd BlueSquare.wav
201201
202202 all: all-am
867867 // -------------------------------------------------------------------------------------------------
868868
869869 void
870 WXMPMeta_DeleteLocalizedText_1 ( XMPMetaRef xmpRef,
871 XMP_StringPtr schemaNS,
872 XMP_StringPtr arrayName,
873 XMP_StringPtr genericLang,
874 XMP_StringPtr specificLang,
875 WXMP_Result * wResult )
876 {
877 XMP_ENTER_WRAPPER ( "WXMPMeta_DeleteLocalizedText_1" )
878
879 if ( (schemaNS == 0) || (*schemaNS == 0) ) XMP_Throw ( "Empty schema namespace URI", kXMPErr_BadSchema );
880 if ( (arrayName == 0) || (*arrayName == 0) ) XMP_Throw ( "Empty array name", kXMPErr_BadXPath );
881 if ( genericLang == 0 ) genericLang = "";
882 if ( (specificLang == 0) ||(*specificLang == 0) ) XMP_Throw ( "Empty specific language", kXMPErr_BadParam );
883
884 XMPMeta * meta = WtoXMPMeta_Ptr ( xmpRef );
885 meta->DeleteLocalizedText ( schemaNS, arrayName, genericLang, specificLang );
886
887 XMP_EXIT_WRAPPER
888 }
889
890 // -------------------------------------------------------------------------------------------------
891
892 void
870893 WXMPMeta_GetProperty_Bool_1 ( XMPMetaRef xmpRef,
871894 XMP_StringPtr schemaNS,
872895 XMP_StringPtr propName,
121121 (XMP_API_VERSION_MINOR << 16) | \
122122 (XMP_API_VERSION_MICRO << 8) )
123123
124 #define kXMPCoreName "XMP Core"
124 #define kXMPCoreName "Exempi + XMP Core"
125125 #define kXMPCore_VersionMessage kXMPCoreName " " XMP_API_VERSION_STRING
126126 // =================================================================================================
127127 // Support for asserts
972972
973973
974974 // -------------------------------------------------------------------------------------------------
975 // DeleteLocalizedText
976 // ----------------
977
978 void
979 XMPMeta::DeleteLocalizedText ( XMP_StringPtr schemaNS,
980 XMP_StringPtr arrayName,
981 XMP_StringPtr _genericLang,
982 XMP_StringPtr _specificLang )
983 {
984 XMP_Assert ( (schemaNS != 0) && (arrayName != 0) && (_genericLang != 0) && (_specificLang != 0) ); // Enforced by wrapper.
985
986 XMP_StringPtr itemPath;
987 XMP_StringLen pathLen;
988
989 XMP_VarString zGenericLang ( _genericLang );
990 XMP_VarString zSpecificLang ( _specificLang );
991 NormalizeLangValue ( &zGenericLang );
992 NormalizeLangValue ( &zSpecificLang );
993
994 XMP_StringPtr genericLang = zGenericLang.c_str();
995 XMP_StringPtr specificLang = zSpecificLang.c_str();
996
997 XMP_ExpandedXPath arrayPath;
998 ExpandXPath ( schemaNS, arrayName, &arrayPath );
999
1000 const XMP_Node * arrayNode = FindConstNode ( &tree, arrayPath ); // *** This expand/find idiom is used in 3 Getters.
1001 if ( arrayNode == 0 ) return; // *** Should extract it into a local utility.
1002
1003 XMP_CLTMatch match;
1004 const XMP_Node * itemNode;
1005
1006 match = ChooseLocalizedText ( arrayNode, genericLang, specificLang, &itemNode );
1007 // FIXED: Only remove SpecificMatch
1008 if ( match != kXMP_CLT_SpecificMatch ) return;
1009
1010 XMPUtils::ComposeLangSelector ( schemaNS, arrayName, itemNode->qualifiers[0]->value.c_str(), &itemPath, &pathLen );
1011 DeleteProperty ( schemaNS, itemPath );
1012
1013 } // DeleteLocalizedText
1014
1015
1016 // -------------------------------------------------------------------------------------------------
9751017 // GetProperty_Bool
9761018 // ----------------
9771019
255255 XMP_StringPtr itemValue,
256256 XMP_OptionBits options );
257257
258 void
259 DeleteLocalizedText ( XMP_StringPtr schemaNS,
260 XMP_StringPtr altTextName,
261 XMP_StringPtr genericLang,
262 XMP_StringPtr specificLang);
263
258264 // ---------------------------------------------------------------------------------------------
259265
260266 bool
0 // =================================================================================================
1 // ADOBE SYSTEMS INCORPORATED
2 // Copyright 2002-2007 Adobe Systems Incorporated
3 // All Rights Reserved
4 //
5 // NOTICE: Adobe permits you to use, modify, and distribute this file in accordance with the terms
6 // of the Adobe license agreement accompanying it.
7 //
8 // Derived from PNG_Handler.cpp by Ian Jacobi
9 // =================================================================================================
10
11 #include "GIF_Handler.hpp"
12
13 #include "GIF_Support.hpp"
14
15 using namespace std;
16
17 // =================================================================================================
18 /// \file GIF_Handler.hpp
19 /// \brief File format handler for GIF.
20 ///
21 /// This handler ...
22 ///
23 // =================================================================================================
24
25 // =================================================================================================
26 // GIF_MetaHandlerCTor
27 // ====================
28
29 XMPFileHandler * GIF_MetaHandlerCTor ( XMPFiles * parent )
30 {
31 return new GIF_MetaHandler ( parent );
32
33 } // GIF_MetaHandlerCTor
34
35 // =================================================================================================
36 // GIF_CheckFormat
37 // ===============
38
39 bool GIF_CheckFormat ( XMP_FileFormat format,
40 XMP_StringPtr filePath,
41 LFA_FileRef fileRef,
42 XMPFiles * parent )
43 {
44 IgnoreParam(format); IgnoreParam(fileRef); IgnoreParam(parent);
45 XMP_Assert ( format == kXMP_GIFFile );
46
47 IOBuffer ioBuf;
48
49 LFA_Seek ( fileRef, 0, SEEK_SET );
50 if ( ! CheckFileSpace ( fileRef, &ioBuf, GIF_SIGNATURE_LEN ) ) return false; // We need at least 3, so the buffer is not filled.
51
52 if ( ! CheckBytes ( ioBuf.ptr, GIF_SIGNATURE_DATA, GIF_SIGNATURE_LEN ) ) return false;
53
54 return true;
55
56 } // GIF_CheckFormat
57
58 // =================================================================================================
59 // GIF_MetaHandler::GIF_MetaHandler
60 // ==================================
61
62 GIF_MetaHandler::GIF_MetaHandler ( XMPFiles * _parent )
63 {
64 this->parent = _parent;
65 this->handlerFlags = kGIF_HandlerFlags;
66 // It MUST be UTF-8.
67 this->stdCharForm = kXMP_Char8Bit;
68
69 }
70
71 // =================================================================================================
72 // GIF_MetaHandler::~GIF_MetaHandler
73 // ===================================
74
75 GIF_MetaHandler::~GIF_MetaHandler()
76 {
77 }
78
79 // =================================================================================================
80 // GIF_MetaHandler::CacheFileData
81 // ===============================
82
83 void GIF_MetaHandler::CacheFileData()
84 {
85
86 this->containsXMP = false;
87
88 LFA_FileRef fileRef ( this->parent->fileRef );
89 if ( fileRef == 0) return;
90
91 // We try to navigate through the blocks to find the XMP block.
92 GIF_Support::BlockState blockState;
93 long numBlocks = GIF_Support::OpenGIF ( fileRef, blockState );
94 if ( numBlocks == 0 ) return;
95
96 if (blockState.xmpLen != 0)
97 {
98 // XMP present
99
100 this->xmpPacket.reserve(blockState.xmpLen);
101 this->xmpPacket.assign(blockState.xmpLen, ' ');
102
103 if (GIF_Support::ReadBuffer ( fileRef, blockState.xmpPos, blockState.xmpLen, const_cast<char *>(this->xmpPacket.data()) ))
104 {
105 this->packetInfo.offset = blockState.xmpPos;
106 this->packetInfo.length = blockState.xmpLen;
107 this->containsXMP = true;
108 }
109 }
110 else
111 {
112 // no XMP
113 }
114
115 } // GIF_MetaHandler::CacheFileData
116
117 // =================================================================================================
118 // GIF_MetaHandler::ProcessTNail
119 // ==============================
120
121 void GIF_MetaHandler::ProcessTNail()
122 {
123
124 XMP_Throw ( "GIF_MetaHandler::ProcessTNail isn't implemented yet", kXMPErr_Unimplemented );
125
126 } // GIF_MetaHandler::ProcessTNail
127
128 // =================================================================================================
129 // GIF_MetaHandler::ProcessXMP
130 // ============================
131 //
132 // Process the raw XMP and legacy metadata that was previously cached.
133
134 void GIF_MetaHandler::ProcessXMP()
135 {
136 this->processedXMP = true; // Make sure we only come through here once.
137
138 // Process the XMP packet.
139
140 if ( ! this->xmpPacket.empty() ) {
141
142 XMP_Assert ( this->containsXMP );
143 XMP_StringPtr packetStr = this->xmpPacket.c_str();
144 XMP_StringLen packetLen = this->xmpPacket.size();
145
146 this->xmpObj.ParseFromBuffer ( packetStr, packetLen );
147
148 this->containsXMP = true;
149
150 }
151
152 } // GIF_MetaHandler::ProcessXMP
153
154 // =================================================================================================
155 // GIF_MetaHandler::UpdateFile
156 // ============================
157
158 void GIF_MetaHandler::UpdateFile ( bool doSafeUpdate )
159 {
160 bool updated = false;
161
162 if ( ! this->needsUpdate ) return;
163 if ( doSafeUpdate ) XMP_Throw ( "GIF_MetaHandler::UpdateFile: Safe update not supported", kXMPErr_Unavailable );
164
165 XMP_StringPtr packetStr = xmpPacket.c_str();
166 XMP_StringLen packetLen = xmpPacket.size();
167 if ( packetLen == 0 ) return;
168
169 LFA_FileRef fileRef(this->parent->fileRef);
170 if ( fileRef == 0 ) return;
171
172 GIF_Support::BlockState blockState;
173 long numBlocks = GIF_Support::OpenGIF ( fileRef, blockState );
174 if ( numBlocks == 0 ) return;
175
176 // write/update block(s)
177 if (blockState.xmpLen == 0)
178 {
179 // no current chunk -> inject
180 updated = SafeWriteFile();
181 }
182 else if (blockState.xmpLen >= packetLen )
183 {
184 // current chunk size is sufficient -> write and update CRC (in place update)
185 updated = GIF_Support::WriteBuffer(fileRef, blockState.xmpPos, packetLen, packetStr );
186 // GIF doesn't have a CRC like PNG.
187 }
188 else if (blockState.xmpLen < packetLen)
189 {
190 // XMP is too large for current chunk -> expand
191 updated = SafeWriteFile();
192 }
193
194 if ( ! updated )return; // If there's an error writing the chunk, bail.
195
196 this->needsUpdate = false;
197
198 } // GIF_MetaHandler::UpdateFile
199
200 // =================================================================================================
201 // GIF_MetaHandler::WriteFile
202 // ===========================
203
204 void GIF_MetaHandler::WriteFile ( LFA_FileRef sourceRef, const std::string & sourcePath )
205 {
206 LFA_FileRef destRef = this->parent->fileRef;
207
208 GIF_Support::BlockState blockState;
209 long numBlocks = GIF_Support::OpenGIF ( sourceRef, blockState );
210 if ( numBlocks == 0 ) return;
211
212 LFA_Truncate(destRef, 0);
213 // LFA_Write(destRef, GIF_SIGNATURE_DATA, GIF_SIGNATURE_LEN);
214
215 GIF_Support::BlockIterator curPos = blockState.blocks.begin();
216 GIF_Support::BlockIterator endPos = blockState.blocks.end();
217
218 long blockCount;
219
220 for (blockCount = 0; (curPos != endPos); ++curPos, ++blockCount)
221 {
222 GIF_Support::BlockData block = *curPos;
223
224 // discard existing XMP block
225 if (block.xmp)
226 continue;
227
228 // copy any other block
229 GIF_Support::CopyBlock(sourceRef, destRef, block);
230
231 // place XMP block immediately before trailer
232 if (blockCount == numBlocks - 2)
233 {
234 XMP_StringPtr packetStr = xmpPacket.c_str();
235 XMP_StringLen packetLen = xmpPacket.size();
236
237 GIF_Support::WriteXMPBlock(destRef, packetLen, packetStr );
238 }
239 }
240
241 } // GIF_MetaHandler::WriteFile
242
243 // =================================================================================================
244 // GIF_MetaHandler::SafeWriteFile
245 // ===========================
246
247 bool GIF_MetaHandler::SafeWriteFile ()
248 {
249 bool ret = false;
250
251 std::string origPath = this->parent->filePath;
252 LFA_FileRef origRef = this->parent->fileRef;
253
254 std::string updatePath;
255 LFA_FileRef updateRef = 0;
256
257 CreateTempFile ( origPath, &updatePath, kCopyMacRsrc );
258 updateRef = LFA_Open ( updatePath.c_str(), 'w' );
259
260 this->parent->filePath = updatePath;
261 this->parent->fileRef = updateRef;
262
263 try {
264 this->WriteFile ( origRef, origPath );
265 ret = true;
266 } catch ( ... ) {
267 LFA_Close ( updateRef );
268 this->parent->filePath = origPath;
269 this->parent->fileRef = origRef;
270 throw;
271 }
272
273 LFA_Close ( origRef );
274 LFA_Delete ( origPath.c_str() );
275
276 LFA_Close ( updateRef );
277 LFA_Rename ( updatePath.c_str(), origPath.c_str() );
278 this->parent->filePath = origPath;
279
280 this->parent->fileRef = 0;
281
282 return ret;
283
284 } // GIF_MetaHandler::SafeWriteFile
285
286 // =================================================================================================
0 #ifndef __GIF_Handler_hpp__
1 #define __GIF_Handler_hpp__ 1
2
3 // =================================================================================================
4 // ADOBE SYSTEMS INCORPORATED
5 // Copyright 2002-2007 Adobe Systems Incorporated
6 // All Rights Reserved
7 //
8 // NOTICE: Adobe permits you to use, modify, and distribute this file in accordance with the terms
9 // of the Adobe license agreement accompanying it.
10 //
11 // Derived from PNG_Handler.hpp by Ian Jacobi
12 // =================================================================================================
13
14 #include "GIF_Support.hpp"
15
16 // =================================================================================================
17 /// \file GIF_Handler.hpp
18 /// \brief File format handler for GIF.
19 ///
20 /// This header ...
21 ///
22 // =================================================================================================
23
24 // *** Could derive from Basic_Handler - buffer file tail in a temp file.
25
26 extern XMPFileHandler* GIF_MetaHandlerCTor ( XMPFiles* parent );
27
28 extern bool GIF_CheckFormat ( XMP_FileFormat format,
29 XMP_StringPtr filePath,
30 LFA_FileRef fileRef,
31 XMPFiles* parent );
32
33 static const XMP_OptionBits kGIF_HandlerFlags = ( kXMPFiles_CanInjectXMP |
34 kXMPFiles_CanExpand |
35 kXMPFiles_PrefersInPlace |
36 kXMPFiles_AllowsOnlyXMP |
37 kXMPFiles_ReturnsRawPacket |
38 kXMPFiles_NeedsReadOnlyPacket
39 );
40
41 class GIF_MetaHandler : public XMPFileHandler
42 {
43 public:
44
45 void CacheFileData();
46 void ProcessTNail();
47 void ProcessXMP();
48
49 void UpdateFile ( bool doSafeUpdate );
50 void WriteFile ( LFA_FileRef sourceRef, const std::string& sourcePath );
51
52 bool SafeWriteFile ();
53
54 GIF_MetaHandler ( XMPFiles* parent );
55 virtual ~GIF_MetaHandler();
56
57 }; // GIF_MetaHandler
58
59 // =================================================================================================
60
61 #endif /* __GIF_Handler_hpp__ */
4141 Scanner_Handler.hpp Trivial_Handler.hpp\
4242 Basic_Handler.hpp JPEG_Handler.hpp \
4343 MP3_Handler.hpp PNG_Handler.hpp PSD_Handler.hpp \
44 TIFF_Handler.hpp WAV_Handler.hpp
44 TIFF_Handler.hpp WAV_Handler.hpp GIF_Handler.hpp
4545
4646
4747 INCLUDES = -I$(srcdir)/.. -I$(srcdir)/../FormatSupport \
5858 Trivial_Handler.cpp \
5959 Basic_Handler.cpp JPEG_Handler.cpp MP3_Handler.cpp \
6060 PNG_Handler.cpp PSD_Handler.cpp TIFF_Handler.cpp \
61 WAV_Handler.cpp
61 WAV_Handler.cpp GIF_Handler.cpp
8585 MPEG_Handler.lo PostScript_Handler.lo Scanner_Handler.lo \
8686 Trivial_Handler.lo Basic_Handler.lo JPEG_Handler.lo \
8787 MP3_Handler.lo PNG_Handler.lo PSD_Handler.lo TIFF_Handler.lo \
88 WAV_Handler.lo
88 WAV_Handler.lo GIF_Handler.lo
8989 libxmpfilehandlers_la_OBJECTS = $(am_libxmpfilehandlers_la_OBJECTS)
9090 DEFAULT_INCLUDES = -I.@am__isrc@
9191 depcomp = $(SHELL) $(top_srcdir)/depcomp
228228 Scanner_Handler.hpp Trivial_Handler.hpp\
229229 Basic_Handler.hpp JPEG_Handler.hpp \
230230 MP3_Handler.hpp PNG_Handler.hpp PSD_Handler.hpp \
231 TIFF_Handler.hpp WAV_Handler.hpp
231 TIFF_Handler.hpp WAV_Handler.hpp GIF_Handler.hpp
232232
233233 INCLUDES = -I$(srcdir)/.. -I$(srcdir)/../FormatSupport \
234234 -I$(top_srcdir)/public/include/ -I$(top_srcdir)/build/ \
243243 Trivial_Handler.cpp \
244244 Basic_Handler.cpp JPEG_Handler.cpp MP3_Handler.cpp \
245245 PNG_Handler.cpp PSD_Handler.cpp TIFF_Handler.cpp \
246 WAV_Handler.cpp
246 WAV_Handler.cpp GIF_Handler.cpp
247247
248248 all: all-am
249249
298298
299299 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/AVI_Handler.Plo@am__quote@
300300 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Basic_Handler.Plo@am__quote@
301 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GIF_Handler.Plo@am__quote@
301302 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/InDesign_Handler.Plo@am__quote@
302303 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/JPEG_Handler.Plo@am__quote@
303304 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MP3_Handler.Plo@am__quote@
0 // =================================================================================================
1 // ADOBE SYSTEMS INCORPORATED
2 // Copyright 2002-2007 Adobe Systems Incorporated
3 // All Rights Reserved
4 //
5 // NOTICE: Adobe permits you to use, modify, and distribute this file in accordance with the terms
6 // of the Adobe license agreement accompanying it.
7 //
8 // Derived from PNG_Support.cpp by Ian Jacobi
9 // =================================================================================================
10
11 #include "GIF_Support.hpp"
12
13 typedef std::basic_string<unsigned char> filebuffer;
14
15 // Don't need CRC.
16
17 namespace GIF_Support
18 {
19 // This only really counts for extension blocks.
20 enum blockType {
21 bGraphicControl = 0xF9,
22 bComment = 0xFE,
23 bPlainText = 0x01,
24 bApplication = 0xFF,
25 // Hacky. Don't like the following, but there's no easy way.
26 bImage = 0x2C,
27 bExtension = 0x21,
28 bTerminator = 0x3B,
29 bHeader = 0x47
30 };
31
32 // =============================================================================================
33
34 long OpenGIF ( LFA_FileRef fileRef, BlockState & inOutBlockState )
35 {
36 XMP_Uns64 pos = 0;
37 unsigned char name;
38 XMP_Uns32 len;
39 BlockData newBlock;
40
41 pos = LFA_Seek ( fileRef, 0, SEEK_SET );
42 // header needs to be a block, mostly for our safe write.
43 pos = ReadHeader ( fileRef );
44 if (pos < 13) return 0;
45
46 newBlock.pos = 0;
47 newBlock.len = pos;
48 newBlock.type = bHeader;
49 inOutBlockState.blocks.push_back(newBlock);
50
51 // read first and following blocks
52 while ( ReadBlock ( fileRef, inOutBlockState, &name, &len, pos) ) {}
53
54 return inOutBlockState.blocks.size();
55
56 }
57
58 // =============================================================================================
59
60 long ReadHeader ( LFA_FileRef fileRef )
61 {
62 long bytesRead;
63 long headerSize;
64 long tableSize = 0;
65 long bytesPerColor = 0;
66 unsigned char buffer[256];
67
68 headerSize = 0;
69 bytesRead = LFA_Read ( fileRef, buffer, GIF_SIGNATURE_LEN );
70 if ( bytesRead != GIF_SIGNATURE_LEN ) return 0;
71 if ( memcmp ( buffer, GIF_SIGNATURE_DATA, GIF_SIGNATURE_LEN) != 0 ) return 0;
72 headerSize += bytesRead;
73 bytesRead = LFA_Read ( fileRef, buffer, 3 );
74 if ( bytesRead != 3 ) return 0;
75 if ( memcmp ( buffer, "87a", 3 ) != 0 && memcmp ( buffer, "89a", 3 ) != 0 ) return 0;
76 headerSize += bytesRead;
77 bytesRead = LFA_Read ( fileRef, buffer, 4 );
78 if ( bytesRead != 4 ) return 0;
79 headerSize += bytesRead;
80 bytesRead = LFA_Read ( fileRef, buffer, 3 );
81 if ( bytesRead != 3 ) return 0;
82 headerSize += bytesRead;
83 if ( buffer[0] & 0x80 ) tableSize = (1 << ((buffer[0] & 0x07) + 1)) * 3;
84 bytesRead = LFA_Read ( fileRef, buffer, tableSize );
85 if ( bytesRead != tableSize ) return 0;
86 headerSize += bytesRead;
87
88 return headerSize;
89 }
90
91 // =============================================================================================
92
93 bool ReadBlock ( LFA_FileRef fileRef, BlockState & inOutBlockState, unsigned char * blockType, XMP_Uns32 * blockLength, XMP_Uns64 & inOutPosition )
94 {
95 try
96 {
97 XMP_Uns64 startPosition = inOutPosition;
98 long bytesRead;
99 long blockSize;
100 unsigned char buffer[256];
101
102 bytesRead = LFA_Read ( fileRef, buffer, 1 );
103 if ( bytesRead != 1 ) return false;
104 inOutPosition += 1;
105 if ( buffer[0] == bImage )
106 {
107 // Image is a special case.
108 long tableSize = 0;
109 bytesRead = LFA_Read ( fileRef, buffer, 4 );
110 if ( bytesRead != 4 ) return false;
111 inOutPosition += 4;
112 bytesRead = LFA_Read ( fileRef, buffer, 4 );
113 if ( bytesRead != 4 ) return false;
114 inOutPosition += 4;
115 bytesRead = LFA_Read ( fileRef, buffer, 1 );
116 if ( bytesRead != 1 ) return false;
117 inOutPosition += 1;
118 if ( buffer[0] & 0x80 ) tableSize = (1 << ((buffer[0] & 0x07) + 1)) * 3;
119 bytesRead = LFA_Read ( fileRef, buffer, tableSize );
120 if ( bytesRead != tableSize ) return 0;
121 inOutPosition += tableSize;
122 bytesRead = LFA_Read ( fileRef, buffer, 1 );
123 if ( bytesRead != 1 ) return false;
124 inOutPosition += 1;
125 bytesRead = LFA_Read ( fileRef, buffer, 1 );
126 if ( bytesRead != 1 ) return false;
127 inOutPosition += 1;
128 tableSize = buffer[0];
129 while ( tableSize != 0x00 )
130 {
131 bytesRead = LFA_Read ( fileRef, buffer, tableSize );
132 if ( bytesRead != tableSize ) return false;
133 inOutPosition += tableSize;
134 bytesRead = LFA_Read ( fileRef, buffer, 1 );
135 if ( bytesRead != 1 ) return false;
136 inOutPosition += 1;
137 tableSize = buffer[0];
138 }
139
140 BlockData newBlock;
141
142 newBlock.pos = startPosition;
143 newBlock.len = inOutPosition - startPosition;
144 newBlock.type = bImage;
145
146 inOutBlockState.blocks.push_back ( newBlock );
147 }
148 else if ( buffer[0] == bExtension )
149 {
150 unsigned char type;
151 long tableSize = 0;
152
153 BlockData newBlock;
154
155 newBlock.pos = startPosition;
156
157 bytesRead = LFA_Read ( fileRef, buffer, 1 );
158 if ( bytesRead != 1 ) return false;
159 inOutPosition += 1;
160 type = buffer[0];
161 newBlock.type = type;
162
163 bytesRead = LFA_Read ( fileRef, buffer, 1 );
164 if ( bytesRead != 1 ) return false;
165 inOutPosition += 1;
166 tableSize = buffer[0];
167 while ( tableSize != 0x00 )
168 {
169 bytesRead = LFA_Read ( fileRef, buffer, tableSize );
170 if ( bytesRead != tableSize ) return false;
171 inOutPosition += tableSize;
172 if ( inOutPosition - startPosition == 14 && type == bApplication )
173 {
174 // Check for XMP identifier...
175 CheckApplicationBlockHeader ( fileRef, inOutBlockState, newBlock, inOutPosition );
176
177 if ( newBlock.xmp == true )
178 {
179 newBlock.len = inOutPosition - startPosition;
180
181 inOutBlockState.blocks.push_back ( newBlock );
182
183 return true;
184 }
185 }
186 bytesRead = LFA_Read ( fileRef, buffer, 1 );
187 if ( bytesRead != 1 ) return false;
188 inOutPosition += 1;
189 tableSize = buffer[0];
190 }
191
192 newBlock.len = inOutPosition - startPosition;
193
194 inOutBlockState.blocks.push_back ( newBlock );
195 }
196 else if ( buffer[0] == bTerminator )
197 {
198 BlockData newBlock;
199
200 newBlock.pos = startPosition;
201 newBlock.len = 1;
202 newBlock.type = buffer[0];
203
204 inOutBlockState.blocks.push_back ( newBlock );
205 }
206
207 } catch ( ... ) {
208
209 return false;
210
211 }
212
213 return true;
214
215 }
216
217 // =============================================================================================
218
219 bool WriteXMPBlock ( LFA_FileRef fileRef, XMP_Uns32 len, const char* inBuffer )
220 {
221 bool ret = false;
222 unsigned long datalen = (APPLICATION_HEADER_LEN + len + MAGIC_TRAILER_LEN);
223 unsigned char* buffer = new unsigned char[datalen];
224
225 try
226 {
227 size_t pos = 0;
228 memcpy(&buffer[pos], APPLICATION_HEADER_DATA, APPLICATION_HEADER_LEN);
229 pos += APPLICATION_HEADER_LEN;
230 memcpy(&buffer[pos], inBuffer, len);
231 pos += len;
232 memcpy(&buffer[pos], MAGIC_TRAILER_DATA, MAGIC_TRAILER_LEN);
233
234 LFA_Write(fileRef, buffer, datalen);
235
236 ret = true;
237 }
238 catch ( ... ) {}
239
240 delete [] buffer;
241
242 return ret;
243 }
244
245 // =============================================================================================
246
247 bool CopyBlock ( LFA_FileRef sourceRef, LFA_FileRef destRef, BlockData& block )
248 {
249 try
250 {
251 LFA_Seek (sourceRef, block.pos, SEEK_SET );
252 LFA_Copy (sourceRef, destRef, (block.len));
253
254 } catch ( ... ) {
255
256 return false;
257
258 }
259
260 return true;
261 }
262
263 // =============================================================================================
264
265 // Don't need CRC.
266
267 // =============================================================================================
268
269 unsigned long CheckApplicationBlockHeader ( LFA_FileRef fileRef, BlockState& inOutBlockState, BlockData& inOutBlockData, XMP_Uns64& inOutPosition )
270 {
271 try
272 {
273 LFA_Seek(fileRef, (inOutBlockData.pos), SEEK_SET);
274
275 unsigned char buffer[256];
276 long bytesRead = LFA_Read ( fileRef, buffer, APPLICATION_HEADER_LEN );
277
278 if (bytesRead == APPLICATION_HEADER_LEN)
279 {
280 if (memcmp(buffer, APPLICATION_HEADER_DATA, APPLICATION_HEADER_LEN) == 0)
281 {
282 // We still have to go through all of the data...
283 long tableSize = 0;
284 long xmpSize;
285
286 inOutPosition = inOutBlockData.pos + APPLICATION_HEADER_LEN;
287 inOutBlockState.xmpPos = inOutPosition;
288 bytesRead = LFA_Read ( fileRef, buffer, 1 );
289 if ( bytesRead != 1 ) return 0;
290 inOutPosition += 1;
291 tableSize = buffer[0];
292 while ( tableSize != 0x00 )
293 {
294 bytesRead = LFA_Read ( fileRef, buffer, tableSize );
295 if ( bytesRead != tableSize ) return false;
296 inOutPosition += tableSize;
297 bytesRead = LFA_Read ( fileRef, buffer, 1 );
298 if ( bytesRead != 1 ) return false;
299 inOutPosition += 1;
300 tableSize = buffer[0];
301 }
302 inOutBlockState.xmpLen = inOutPosition - inOutBlockData.pos - APPLICATION_HEADER_LEN - MAGIC_TRAILER_LEN;
303 inOutBlockState.xmpBlock = inOutBlockData;
304 inOutBlockData.xmp = true;
305 }
306 }
307 }
308 catch ( ... ) {}
309
310 return 0;
311 }
312
313 bool ReadBuffer ( LFA_FileRef fileRef, XMP_Uns64 & pos, XMP_Uns32 len, char * outBuffer )
314 {
315 try
316 {
317 if ( (fileRef == 0) || (outBuffer == 0) ) return false;
318
319 LFA_Seek (fileRef, pos, SEEK_SET );
320 long bytesRead = LFA_Read ( fileRef, outBuffer, len );
321 if ( XMP_Uns32(bytesRead) != len ) return false;
322
323 return true;
324 }
325 catch ( ... ) {}
326
327 return false;
328 }
329
330 bool WriteBuffer ( LFA_FileRef fileRef, XMP_Uns64 & pos, XMP_Uns32 len, const char * inBuffer )
331 {
332 try
333 {
334 if ( (fileRef == 0) || (inBuffer == 0) ) return false;
335
336 LFA_Seek (fileRef, pos, SEEK_SET );
337 LFA_Write( fileRef, inBuffer, len );
338
339 return true;
340 }
341 catch ( ... ) {}
342
343 return false;
344 }
345
346 } // namespace GIF_Support
0 #ifndef __GIF_Support_hpp__
1 #define __GIF_Support_hpp__ 1
2
3 // =================================================================================================
4 // ADOBE SYSTEMS INCORPORATED
5 // Copyright 2002-2007 Adobe Systems Incorporated
6 // All Rights Reserved
7 //
8 // NOTICE: Adobe permits you to use, modify, and distribute this file in accordance with the terms
9 // of the Adobe license agreement accompanying it
10 //
11 // Derived from PNG_Support.hpp by Ian Jacobi
12 // =================================================================================================
13
14 #include "XMP_Environment.h" // ! This must be the first include.
15
16 #include "XMPFiles_Impl.hpp"
17
18 #define GIF_SIGNATURE_LEN 3
19 #define GIF_SIGNATURE_DATA "\x47\x49\x46"
20
21 #define APPLICATION_HEADER_LEN 14
22 #define APPLICATION_HEADER_DATA "\x21\xFF\x0B\x58\x4D\x50\x20\x44\x61\x74\x61\x58\x4D\x50"
23
24 #define MAGIC_TRAILER_LEN 258
25 #define MAGIC_TRAILER_DATA "\x01\xFF\xFE\xFD\xFC\xFB\xFA\xF9\xF8\xF7\xF6\xF5\xF4\xF3\xF2\xF1\xF0\xEF\xEE\xED\xEC\xEB\xEA\xE9\xE8\xE7\xE6\xE5\xE4\xE3\xE2\xE1\xE0\xDF\xDE\xDD\xDC\xDB\xDA\xD9\xD8\xD7\xD6\xD5\xD4\xD3\xD2\xD1\xD0\xCF\xCE\xCD\xCC\xCB\xCA\xC9\xC8\xC7\xC6\xC5\xC4\xC3\xC2\xC1\xC0\xBF\xBE\xBD\xBC\xBB\xBA\xB9\xB8\xB7\xB6\xB5\xB4\xB3\xB2\xB1\xB0\xAF\xAE\xAD\xAC\xAB\xAA\xA9\xA8\xA7\xA6\xA5\xA4\xA3\xA2\xA1\xA0\x9F\x9E\x9D\x9C\x9B\x9A\x99\x98\x97\x96\x95\x94\x93\x92\x91\x90\x8F\x8E\x8D\x8C\x8B\x8A\x89\x88\x87\x86\x85\x84\x83\x82\x81\x80\x7F\x7E\x7D\x7C\x7B\x7A\x79\x78\x77\x76\x75\x74\x73\x72\x71\x70\x6F\x6E\x6D\x6C\x6B\x6A\x69\x68\x67\x66\x65\x64\x63\x62\x61\x60\x5F\x5E\x5D\x5C\x5B\x5A\x59\x58\x57\x56\x55\x54\x53\x52\x51\x50\x4F\x4E\x4D\x4C\x4B\x4A\x49\x48\x47\x46\x45\x44\x43\x42\x41\x40\x3F\x3E\x3D\x3C\x3B\x3A\x39\x38\x37\x36\x35\x34\x33\x32\x31\x30\x2F\x2E\x2D\x2C\x2B\x2A\x29\x28\x27\x26\x25\x24\x23\x22\x21\x20\x1F\x1E\x1D\x1C\x1B\x1A\x19\x18\x17\x16\x15\x14\x13\x12\x11\x10\x0F\x0E\x0D\x0C\x0B\x0A\x09\x08\x07\x06\x05\x04\x03\x02\x01\x00\x00"
26
27 namespace GIF_Support
28 {
29 class BlockData
30 {
31 public:
32 BlockData() : pos(0), len(0), type(0), xmp(false) {}
33 virtual ~BlockData() {}
34
35 XMP_Uns64 pos; // file offset of block
36 XMP_Uns32 len; // length of block data, including extension introducer and label
37 char type; // name/type of block
38 bool xmp; // application extension block with XMP ?
39 };
40
41 typedef std::vector<BlockData> BlockVector;
42 typedef BlockVector::iterator BlockIterator;
43
44 class BlockState
45 {
46 public:
47 BlockState() : xmpPos(0), xmpLen(0) {}
48 virtual ~BlockState() {}
49
50 XMP_Uns64 xmpPos;
51 XMP_Uns32 xmpLen;
52 BlockData xmpBlock;
53 BlockVector blocks; /* vector of blocks */
54 };
55
56 long OpenGIF ( LFA_FileRef fileRef, BlockState& inOutBlockState );
57
58 long ReadHeader ( LFA_FileRef fileRef );
59 bool ReadBlock ( LFA_FileRef fileRef, BlockState& inOutBlockState, unsigned char* blockType, XMP_Uns32* blockLength, XMP_Uns64& inOutPosition );
60 bool WriteXMPBlock ( LFA_FileRef fileRef, XMP_Uns32 len, const char* inBuffer );
61 bool CopyBlock ( LFA_FileRef sourceRef, LFA_FileRef destRef, BlockData& block );
62
63 unsigned long CheckApplicationBlockHeader ( LFA_FileRef fileRef, BlockState& inOutBlockState, BlockData& inOutBlockData, XMP_Uns64& inOutPosition );
64
65 bool ReadBuffer ( LFA_FileRef fileRef, XMP_Uns64& pos, XMP_Uns32 len, char* outBuffer );
66 bool WriteBuffer ( LFA_FileRef fileRef, XMP_Uns64& pos, XMP_Uns32 len, const char* inBuffer );
67
68 } // namespace GIF_Support
69
70 #endif // __GIF_Support_hpp__
3737 noinst_HEADERS = EndianUtils.hpp IPTC_Support.hpp PSIR_Support.hpp\
3838 Reconcile_Impl.hpp RIFF_Support.hpp XMPScanner.hpp\
3939 ID3_Support.hpp PNG_Support.hpp QuickTime_Support.hpp\
40 ReconcileLegacy.hpp TIFF_Support.hpp
40 ReconcileLegacy.hpp TIFF_Support.hpp GIF_Support.hpp
4141
4242
4343 INCLUDES = -I$(srcdir)/.. -I$(srcdir)/../../common \
5656 IPTC_Support.cpp PSIR_MemoryReader.cpp ReconcileIPTC.cpp \
5757 RIFF_Support.cpp TIFF_Support.cpp \
5858 PNG_Support.cpp ReconcileLegacy.cpp \
59 TIFF_FileWriter.cpp XMPScanner.cpp
59 TIFF_FileWriter.cpp XMPScanner.cpp GIF_Support.cpp
8585 Reconcile_Impl.lo ReconcileTIFF.lo TIFF_MemoryReader.lo \
8686 IPTC_Support.lo PSIR_MemoryReader.lo ReconcileIPTC.lo \
8787 RIFF_Support.lo TIFF_Support.lo PNG_Support.lo \
88 ReconcileLegacy.lo TIFF_FileWriter.lo XMPScanner.lo
88 ReconcileLegacy.lo TIFF_FileWriter.lo XMPScanner.lo \
89 GIF_Support.lo
8990 libformatsupport_la_OBJECTS = $(am_libformatsupport_la_OBJECTS)
9091 DEFAULT_INCLUDES = -I.@am__isrc@
9192 depcomp = $(SHELL) $(top_srcdir)/depcomp
226227 noinst_HEADERS = EndianUtils.hpp IPTC_Support.hpp PSIR_Support.hpp\
227228 Reconcile_Impl.hpp RIFF_Support.hpp XMPScanner.hpp\
228229 ID3_Support.hpp PNG_Support.hpp QuickTime_Support.hpp\
229 ReconcileLegacy.hpp TIFF_Support.hpp
230 ReconcileLegacy.hpp TIFF_Support.hpp GIF_Support.hpp
230231
231232 INCLUDES = -I$(srcdir)/.. -I$(srcdir)/../../common \
232233 -I$(top_srcdir)/public/include/ -I$(top_srcdir)/build/ \
241242 IPTC_Support.cpp PSIR_MemoryReader.cpp ReconcileIPTC.cpp \
242243 RIFF_Support.cpp TIFF_Support.cpp \
243244 PNG_Support.cpp ReconcileLegacy.cpp \
244 TIFF_FileWriter.cpp XMPScanner.cpp
245 TIFF_FileWriter.cpp XMPScanner.cpp GIF_Support.cpp
245246
246247 all: all-am
247248
294295 distclean-compile:
295296 -rm -f *.tab.c
296297
298 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/GIF_Support.Plo@am__quote@
297299 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ID3_Support.Plo@am__quote@
298300 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IPTC_Support.Plo@am__quote@
299301 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/PNG_Support.Plo@am__quote@
3030 #include "FileHandlers/PNG_Handler.hpp"
3131 #include "FileHandlers/AVI_Handler.hpp"
3232 #include "FileHandlers/WAV_Handler.hpp"
33 #include "FileHandlers/GIF_Handler.hpp"
3334
3435 // =================================================================================================
3536 /// \file XMPFiles.cpp
223224
224225 XMP_Assert ( ! (kMP3_HandlerFlags & kXMPFiles_HandlerOwnsFile) );
225226 RegisterXMPFileHandler ( kXMP_MP3File, kMP3_HandlerFlags, MP3_CheckFormat, MP3_MetaHandlerCTor );
227
228 XMP_Assert ( ! (kGIF_HandlerFlags & kXMPFiles_HandlerOwnsFile) );
229 RegisterXMPFileHandler ( kXMP_GIFFile, kGIF_HandlerFlags, GIF_CheckFormat, GIF_MetaHandlerCTor );
226230
227231 #if XMP_WinBuild
228232
126126 { "", 0 } }; // ! Must be last as a sentinel.
127127
128128 const char * kKnownScannedFiles[] = // Files known to contain XMP but have no smart handling, here or elsewhere.
129 { "gif", // GIF, public format but no smart handler.
130 "ai", // Illustrator, actually a PDF file.
129 { "ai", // Illustrator, actually a PDF file.
131130 "ait", // Illustrator template, actually a PDF file.
132131 "svg", // SVG, an XML file.
133132 "aet", // After Effects template project file.