X-Git-Url: https://granicus.if.org/sourcecode?a=blobdiff_plain;f=coders%2Fmeta.c;h=03fbbf4c1f4f28d6b14992b048f6530abf591369;hb=4c08aed51c5899665ade97263692328eea4af106;hp=e3928e06b72b5426687d1eef65e16f882584819e;hpb=8496075c7834324293def15e9a663e804ce35a2b;p=imagemagick diff --git a/coders/meta.c b/coders/meta.c index e3928e06b..03fbbf4c1 100644 --- a/coders/meta.c +++ b/coders/meta.c @@ -17,7 +17,7 @@ % July 2001 % % % % % -% Copyright 1999-2009 ImageMagick Studio LLC, a non-profit organization % +% Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization % % dedicated to making software imaging solutions freely available. % % % % You may not use this file except in compliance with the License. You may % @@ -39,24 +39,25 @@ /* Include declarations. */ -#include "magick/studio.h" -#include "magick/blob.h" -#include "magick/blob-private.h" -#include "magick/exception.h" -#include "magick/exception-private.h" -#include "magick/image.h" -#include "magick/image-private.h" -#include "magick/list.h" -#include "magick/magick.h" -#include "magick/memory_.h" -#include "magick/profile.h" -#include "magick/splay-tree.h" -#include "magick/quantum-private.h" -#include "magick/static.h" -#include "magick/string_.h" -#include "magick/module.h" -#include "magick/token.h" -#include "magick/utility.h" +#include "MagickCore/studio.h" +#include "MagickCore/blob.h" +#include "MagickCore/blob-private.h" +#include "MagickCore/exception.h" +#include "MagickCore/exception-private.h" +#include "MagickCore/image.h" +#include "MagickCore/image-private.h" +#include "MagickCore/list.h" +#include "MagickCore/magick.h" +#include "MagickCore/memory_.h" +#include "MagickCore/module.h" +#include "MagickCore/profile.h" +#include "MagickCore/splay-tree.h" +#include "MagickCore/quantum-private.h" +#include "MagickCore/static.h" +#include "MagickCore/string_.h" +#include "MagickCore/string-private.h" +#include "MagickCore/token.h" +#include "MagickCore/utility.h" /* Forward declarations. @@ -161,7 +162,7 @@ static html_code html_codes[] = { static int stringnicmp(const char *p,const char *q,size_t n) { - register long + register ssize_t i, j; @@ -287,7 +288,7 @@ static char *super_fgets(char **b, int *blen, Image *file) #define IPTC_ID 1028 #define THUMBNAIL_ID 1033 -static long parse8BIM(Image *ifile, Image *ofile) +static ssize_t parse8BIM(Image *ifile, Image *ofile) { char brkused, @@ -310,14 +311,14 @@ static long parse8BIM(Image *ifile, Image *ofile) int inputlen = BUFFER_SZ; - long - savedolen = 0L, - outputlen = 0L; - MagickOffsetType savedpos, currentpos; + ssize_t + savedolen = 0L, + outputlen = 0L; + TokenInfo *token_info; @@ -358,10 +359,10 @@ static long parse8BIM(Image *ifile, Image *ofile) if (strcmp(newstr,"8BIM")==0) dataset = 255; else - dataset = (unsigned char) atoi(newstr); + dataset = (unsigned char) StringToLong(newstr); break; case 1: - recnum = (unsigned int) atoi(newstr); + recnum = (unsigned int) StringToUnsignedLong(newstr); break; case 2: name=(char *) AcquireQuantumMemory(strlen(newstr)+MaxTextExtent, @@ -379,7 +380,7 @@ static long parse8BIM(Image *ifile, Image *ofile) int next; - long + ssize_t len; char @@ -387,7 +388,7 @@ static long parse8BIM(Image *ifile, Image *ofile) quoted; next=0; - len = (long) strlen(token); + len = (ssize_t) strlen(token); while (Tokenizer(token_info,0,newstr,(size_t) inputlen,token,"","&", "",0,&brkused,&next,"ed)==0) { @@ -396,7 +397,7 @@ static long parse8BIM(Image *ifile, Image *ofile) char *s = &token[next-1]; - len -= (long) convertHTMLcodes(s,(int) strlen(s)); + len -= (ssize_t) convertHTMLcodes(s,(int) strlen(s)); } } @@ -413,12 +414,12 @@ static long parse8BIM(Image *ifile, Image *ofile) MagickOffsetType offset; - long diff = outputlen - savedolen; + ssize_t diff = outputlen - savedolen; currentpos = TellBlob(ofile); offset=SeekBlob(ofile,savedpos,SEEK_SET); if (offset < 0) return(-1); - (void) WriteBlobMSBLong(ofile,(unsigned long) diff); + (void) WriteBlobMSBLong(ofile,(unsigned int) diff); offset=SeekBlob(ofile,currentpos,SEEK_SET); if (offset < 0) return(-1); @@ -446,7 +447,7 @@ static long parse8BIM(Image *ifile, Image *ofile) } if (recnum != IPTC_ID) { - (void) WriteBlobMSBLong(ofile, (unsigned long) len); + (void) WriteBlobMSBLong(ofile, (unsigned int) len); outputlen += 4; next=0; @@ -464,7 +465,7 @@ static long parse8BIM(Image *ifile, Image *ofile) { /* patch in a fake length for now and fix it later */ savedpos = TellBlob(ofile); - (void) WriteBlobMSBLong(ofile,0xFFFFFFFFUL); + (void) WriteBlobMSBLong(ofile,0xFFFFFFFFU); outputlen += 4; savedolen = outputlen; } @@ -499,13 +500,13 @@ static long parse8BIM(Image *ifile, Image *ofile) MagickOffsetType offset; - long diff = outputlen - savedolen; + ssize_t diff = outputlen - savedolen; currentpos = TellBlob(ofile); offset=SeekBlob(ofile,savedpos,SEEK_SET); if (offset < 0) return(-1); - (void) WriteBlobMSBLong(ofile,(unsigned long) diff); + (void) WriteBlobMSBLong(ofile,(unsigned int) diff); offset=SeekBlob(ofile,currentpos,SEEK_SET); if (offset < 0) return(-1); @@ -563,7 +564,7 @@ static char *super_fgets_w(char **b, int *blen, Image *file) return((char *) p); } -static long parse8BIMW(Image *ifile, Image *ofile) +static ssize_t parse8BIMW(Image *ifile, Image *ofile) { char brkused, @@ -586,7 +587,7 @@ static long parse8BIMW(Image *ifile, Image *ofile) int inputlen = BUFFER_SZ; - long + ssize_t savedolen = 0L, outputlen = 0L; @@ -634,10 +635,10 @@ static long parse8BIMW(Image *ifile, Image *ofile) if (strcmp(newstr,"8BIM")==0) dataset = 255; else - dataset = (unsigned char) atoi(newstr); + dataset = (unsigned char) StringToLong(newstr); break; case 1: - recnum=(unsigned int) atoi(newstr); + recnum=(unsigned int) StringToUnsignedLong(newstr); break; case 2: name=(char *) AcquireQuantumMemory(strlen(newstr)+MaxTextExtent, @@ -655,7 +656,7 @@ static long parse8BIMW(Image *ifile, Image *ofile) int next; - long + ssize_t len; char @@ -663,7 +664,7 @@ static long parse8BIMW(Image *ifile, Image *ofile) quoted; next=0; - len = (long) strlen(token); + len = (ssize_t) strlen(token); while (Tokenizer(token_info,0,newstr,(size_t) inputlen,token,"","&", "",0,&brkused,&next,"ed)==0) { @@ -672,7 +673,7 @@ static long parse8BIMW(Image *ifile, Image *ofile) char *s = &token[next-1]; - len -= (long) convertHTMLcodes(s,(int) strlen(s)); + len -= (ssize_t) convertHTMLcodes(s,(int) strlen(s)); } } @@ -689,12 +690,12 @@ static long parse8BIMW(Image *ifile, Image *ofile) MagickOffsetType offset; - long diff = outputlen - savedolen; + ssize_t diff = outputlen - savedolen; currentpos = TellBlob(ofile); offset=SeekBlob(ofile,savedpos,SEEK_SET); if (offset < 0) return(-1); - (void) WriteBlobMSBLong(ofile,(unsigned long) diff); + (void) WriteBlobMSBLong(ofile,(unsigned int) diff); offset=SeekBlob(ofile,currentpos,SEEK_SET); if (offset < 0) return(-1); @@ -722,7 +723,7 @@ static long parse8BIMW(Image *ifile, Image *ofile) } if (recnum != IPTC_ID) { - (void) WriteBlobMSBLong(ofile,(unsigned long) len); + (void) WriteBlobMSBLong(ofile,(unsigned int) len); outputlen += 4; next=0; @@ -740,7 +741,7 @@ static long parse8BIMW(Image *ifile, Image *ofile) { /* patch in a fake length for now and fix it later */ savedpos = TellBlob(ofile); - (void) WriteBlobMSBLong(ofile,0xFFFFFFFFUL); + (void) WriteBlobMSBLong(ofile,0xFFFFFFFFU); outputlen += 4; savedolen = outputlen; } @@ -774,13 +775,13 @@ static long parse8BIMW(Image *ifile, Image *ofile) MagickOffsetType offset; - long diff = outputlen - savedolen; + ssize_t diff = outputlen - savedolen; currentpos = TellBlob(ofile); offset=SeekBlob(ofile,savedpos,SEEK_SET); if (offset < 0) return(-1); - (void) WriteBlobMSBLong(ofile,(unsigned long) diff); + (void) WriteBlobMSBLong(ofile,(unsigned int) diff); offset=SeekBlob(ofile,currentpos,SEEK_SET); if (offset < 0) return(-1); @@ -1101,7 +1102,12 @@ static Image *ReadMETAImage(const ImageInfo *image_info, } image->columns=1; image->rows=1; - (void) SetImageBackgroundColor(image); + if (SetImageBackgroundColor(image) == MagickFalse) + { + InheritException(exception,&image->exception); + image=DestroyImageList(image); + return((Image *) NULL); + } length=1; if (LocaleNCompare(image_info->magick,"8BIM",4) == 0) { @@ -1155,7 +1161,7 @@ static Image *ReadMETAImage(const ImageInfo *image_info, char name[MaxTextExtent]; - (void) FormatMagickString(name,MaxTextExtent,"APP%d",1); + (void) FormatLocaleString(name,MaxTextExtent,"APP%d",1); buff=AcquireImage((ImageInfo *) NULL); if (buff == (Image *) NULL) ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); @@ -1216,7 +1222,7 @@ static Image *ReadMETAImage(const ImageInfo *image_info, (void) WriteBlobByte(buff,c); } #else - long + ssize_t i; unsigned char @@ -1234,13 +1240,13 @@ static Image *ReadMETAImage(const ImageInfo *image_info, while ((length=ReadBlob(image,MagickMaxBufferExtent,buffer)) != 0) { count=0; - for (i=0; i < (long) length; i+=count) + for (i=0; i < (ssize_t) length; i+=count) { count=WriteBlob(buff,(size_t) (length-i),buffer+i); if (count <= 0) break; } - if (i < (long) length) + if (i < (ssize_t) length) break; } buffer=(unsigned char *) RelinquishMagickMemory(buffer); @@ -1301,8 +1307,8 @@ static Image *ReadMETAImage(const ImageInfo *image_info, } AttachBlob(buff->blob,blob,length); /* write out the header - length field patched below */ - (void) WriteBlob(buff,11,(unsigned char *) "8BIM\04\04\0\0\0\0\01"); - (void) WriteBlobByte(buff,0xe0); + (void) WriteBlob(buff,11,(unsigned char *) "8BIM\04\04\0\0\0\0\0"); + (void) WriteBlobByte(buff,0xc6); if (LocaleCompare(image_info->magick,"IPTCTEXT") == 0) { length=(size_t) parse8BIM(image,buff); @@ -1388,10 +1394,10 @@ static Image *ReadMETAImage(const ImageInfo *image_info, % % The format of the RegisterMETAImage method is: % -% unsigned long RegisterMETAImage(void) +% size_t RegisterMETAImage(void) % */ -ModuleExport unsigned long RegisterMETAImage(void) +ModuleExport size_t RegisterMETAImage(void) { MagickInfo *entry; @@ -1405,7 +1411,6 @@ ModuleExport unsigned long RegisterMETAImage(void) entry->description=ConstantString("Photoshop resource format"); entry->module=ConstantString("META"); (void) RegisterMagickInfo(entry); - entry=SetMagickInfo("8BIMTEXT"); entry->decoder=(DecodeImageHandler *) ReadMETAImage; entry->encoder=(EncodeImageHandler *) WriteMETAImage; @@ -1415,7 +1420,6 @@ ModuleExport unsigned long RegisterMETAImage(void) entry->description=ConstantString("Photoshop resource text format"); entry->module=ConstantString("META"); (void) RegisterMagickInfo(entry); - entry=SetMagickInfo("8BIMWTEXT"); entry->decoder=(DecodeImageHandler *) ReadMETAImage; entry->encoder=(EncodeImageHandler *) WriteMETAImage; @@ -1425,7 +1429,6 @@ ModuleExport unsigned long RegisterMETAImage(void) entry->description=ConstantString("Photoshop resource wide text format"); entry->module=ConstantString("META"); (void) RegisterMagickInfo(entry); - entry=SetMagickInfo("APP1"); entry->decoder=(DecodeImageHandler *) ReadMETAImage; entry->encoder=(EncodeImageHandler *) WriteMETAImage; @@ -1435,7 +1438,6 @@ ModuleExport unsigned long RegisterMETAImage(void) entry->description=ConstantString("Raw application information"); entry->module=ConstantString("META"); (void) RegisterMagickInfo(entry); - entry=SetMagickInfo("APP1JPEG"); entry->decoder=(DecodeImageHandler *) ReadMETAImage; entry->encoder=(EncodeImageHandler *) WriteMETAImage; @@ -1445,7 +1447,6 @@ ModuleExport unsigned long RegisterMETAImage(void) entry->description=ConstantString("Raw JPEG binary data"); entry->module=ConstantString("META"); (void) RegisterMagickInfo(entry); - entry=SetMagickInfo("EXIF"); entry->decoder=(DecodeImageHandler *) ReadMETAImage; entry->encoder=(EncodeImageHandler *) WriteMETAImage; @@ -1455,7 +1456,6 @@ ModuleExport unsigned long RegisterMETAImage(void) entry->description=ConstantString("Exif digital camera binary data"); entry->module=ConstantString("META"); (void) RegisterMagickInfo(entry); - entry=SetMagickInfo("XMP"); entry->decoder=(DecodeImageHandler *) ReadMETAImage; entry->encoder=(EncodeImageHandler *) WriteMETAImage; @@ -1465,7 +1465,6 @@ ModuleExport unsigned long RegisterMETAImage(void) entry->description=ConstantString("Adobe XML metadata"); entry->module=ConstantString("META"); (void) RegisterMagickInfo(entry); - entry=SetMagickInfo("ICM"); entry->decoder=(DecodeImageHandler *) ReadMETAImage; entry->encoder=(EncodeImageHandler *) WriteMETAImage; @@ -1475,7 +1474,6 @@ ModuleExport unsigned long RegisterMETAImage(void) entry->description=ConstantString("ICC Color Profile"); entry->module=ConstantString("META"); (void) RegisterMagickInfo(entry); - entry=SetMagickInfo("ICC"); entry->decoder=(DecodeImageHandler *) ReadMETAImage; entry->encoder=(EncodeImageHandler *) WriteMETAImage; @@ -1485,7 +1483,6 @@ ModuleExport unsigned long RegisterMETAImage(void) entry->description=ConstantString("ICC Color Profile"); entry->module=ConstantString("META"); (void) RegisterMagickInfo(entry); - entry=SetMagickInfo("IPTC"); entry->decoder=(DecodeImageHandler *) ReadMETAImage; entry->encoder=(EncodeImageHandler *) WriteMETAImage; @@ -1495,7 +1492,6 @@ ModuleExport unsigned long RegisterMETAImage(void) entry->description=ConstantString("IPTC Newsphoto"); entry->module=ConstantString("META"); (void) RegisterMagickInfo(entry); - entry=SetMagickInfo("IPTCTEXT"); entry->decoder=(DecodeImageHandler *) ReadMETAImage; entry->encoder=(EncodeImageHandler *) WriteMETAImage; @@ -1505,7 +1501,6 @@ ModuleExport unsigned long RegisterMETAImage(void) entry->description=ConstantString("IPTC Newsphoto text format"); entry->module=ConstantString("META"); (void) RegisterMagickInfo(entry); - entry=SetMagickInfo("IPTCWTEXT"); entry->decoder=(DecodeImageHandler *) ReadMETAImage; entry->encoder=(EncodeImageHandler *) WriteMETAImage; @@ -1587,7 +1582,7 @@ static size_t GetIPTCStream(unsigned char **info,size_t length) int c; - register long + register ssize_t i; register unsigned char @@ -1603,7 +1598,7 @@ static size_t GetIPTCStream(unsigned char **info,size_t length) unsigned int marker; - unsigned long + size_t tag_length; p=(*info); @@ -1631,17 +1626,19 @@ static size_t GetIPTCStream(unsigned char **info,size_t length) extent-=c; if (extent < 4) break; - tag_length=(((unsigned long) *p) << 24) | (((unsigned long) *(p+1)) << 16) | - (((unsigned long) *(p+2)) << 8) | ((unsigned long) *(p+3)); + tag_length=(((size_t) *p) << 24) | (((size_t) *(p+1)) << 16) | + (((size_t) *(p+2)) << 8) | ((size_t) *(p+3)); p+=4; extent-=4; if (tag_length > extent) break; if (marker == IPTC_ID) { - *info=p; /* let the caller know were it is */ - return(extent); + *info=p; + return(tag_length); } + if ((tag_length & 0x01) != 0) + tag_length++; p+=tag_length; extent-=tag_length; } @@ -1701,7 +1698,7 @@ iptc_find: goto iptc_find; info_length++; /* - Decode the length of the block that follows - long or short format. + Decode the length of the block that follows - ssize_t or short format. */ c=(*p++); length--; @@ -1718,13 +1715,13 @@ iptc_find: break; info_length++; } - tag_length=(((unsigned long) buffer[0]) << 24) | - (((unsigned long) buffer[1]) << 16) | - (((unsigned long) buffer[2]) << 8) | (((unsigned long) buffer[3])); + tag_length=(((size_t) buffer[0]) << 24) | + (((size_t) buffer[1]) << 16) | + (((size_t) buffer[2]) << 8) | (((size_t) buffer[3])); } else { - tag_length=(unsigned long) (c << 8); + tag_length=(size_t) (c << 8); c=(*p++); length--; if (length == 0) @@ -1771,13 +1768,13 @@ static void formatString(Image *ofile, const char *s, int len) (void) WriteBlobByte(ofile,(unsigned char) *s); else { - (void) FormatMagickString(temp,MaxTextExtent,"&#%d;", c & 255); + (void) FormatLocaleString(temp,MaxTextExtent,"&#%d;", c & 255); (void) WriteBlobString(ofile,temp); } break; } } -#if defined(__WINDOWS__) +#if defined(MAGICKCORE_WINDOWS_SUPPORT) (void) WriteBlobString(ofile,"\"\r\n"); #else #if defined(macintosh) @@ -1870,7 +1867,7 @@ static int formatIPTC(Image *ifile, Image *ofile) *readable, *str; - long + ssize_t tagindx, taglen; @@ -1915,7 +1912,7 @@ static int formatIPTC(Image *ifile, Image *ofile) else readable = (unsigned char *) ""; /* - We decode the length of the block that follows - long or short fmt. + We decode the length of the block that follows - ssize_t or short fmt. */ c=ReadBlobByte(ifile); if (c == EOF) return -1; @@ -1949,10 +1946,10 @@ static int formatIPTC(Image *ifile, Image *ofile) /* now finish up by formatting this binary data into ASCII equivalent */ if (strlen((char *)readable) > 0) - (void) FormatMagickString(temp,MaxTextExtent,"%d#%d#%s=", + (void) FormatLocaleString(temp,MaxTextExtent,"%d#%d#%s=", (unsigned int) dataset, (unsigned int) recnum, readable); else - (void) FormatMagickString(temp,MaxTextExtent,"%d#%d=", + (void) FormatLocaleString(temp,MaxTextExtent,"%d#%d=", (unsigned int) dataset,(unsigned int) recnum); (void) WriteBlobString(ofile,temp); formatString( ofile, (char *)str, taglen ); @@ -1965,7 +1962,7 @@ static int formatIPTC(Image *ifile, Image *ofile) return((int) tagsfound); } -static int readWordFromBuffer(char **s, long *len) +static int readWordFromBuffer(char **s, ssize_t *len) { unsigned char buffer[2]; @@ -1984,7 +1981,7 @@ static int readWordFromBuffer(char **s, long *len) (((int) buffer[ 1 ])); } -static int formatIPTCfromBuffer(Image *ofile, char *s, long len) +static int formatIPTCfromBuffer(Image *ofile, char *s, ssize_t len) { char temp[MaxTextExtent]; @@ -2001,7 +1998,7 @@ static int formatIPTCfromBuffer(Image *ofile, char *s, long len) *readable, *str; - long + ssize_t tagindx, taglen; @@ -2045,7 +2042,7 @@ static int formatIPTCfromBuffer(Image *ofile, char *s, long len) else readable=(unsigned char *) ""; /* - We decode the length of the block that follows - long or short fmt. + We decode the length of the block that follows - ssize_t or short fmt. */ c=(*s++); len--; @@ -2080,10 +2077,10 @@ static int formatIPTCfromBuffer(Image *ofile, char *s, long len) /* now finish up by formatting this binary data into ASCII equivalent */ if (strlen((char *)readable) > 0) - (void) FormatMagickString(temp,MaxTextExtent,"%d#%d#%s=", + (void) FormatLocaleString(temp,MaxTextExtent,"%d#%d#%s=", (unsigned int) dataset,(unsigned int) recnum, readable); else - (void) FormatMagickString(temp,MaxTextExtent,"%d#%d=", + (void) FormatLocaleString(temp,MaxTextExtent,"%d#%d=", (unsigned int) dataset,(unsigned int) recnum); (void) WriteBlobString(ofile,temp); formatString( ofile, (char *)str, taglen ); @@ -2117,6 +2114,7 @@ static int format8BIM(Image *ifile, Image *ofile) resCount=0; foundOSType=0; /* found the OSType */ + (void) foundOSType; c=ReadBlobByte(ifile); while (c != EOF) { @@ -2179,7 +2177,7 @@ static int format8BIM(Image *ifile, Image *ofile) return(-1); } } - count = (ssize_t) ReadBlobMSBLong(ifile); + count = (int) ReadBlobMSBLong(ifile); if (count < 0) return -1; /* make a buffer to hold the datand snag it from the input stream */ str=(unsigned char *) AcquireQuantumMemory((size_t) count,sizeof(*str)); @@ -2188,7 +2186,7 @@ static int format8BIM(Image *ifile, Image *ofile) printf("MemoryAllocationFailed"); return 0; } - for (i=0; i < (long) count; i++) + for (i=0; i < (ssize_t) count; i++) { c=ReadBlobByte(ifile); if (c == EOF) @@ -2205,18 +2203,18 @@ static int format8BIM(Image *ifile, Image *ofile) * ASCII equivalent */ if (strlen((const char *)PString) > 0) - (void) FormatMagickString(temp,MaxTextExtent,"8BIM#%d#%s=",ID, + (void) FormatLocaleString(temp,MaxTextExtent,"8BIM#%d#%s=",ID, PString); else - (void) FormatMagickString(temp,MaxTextExtent,"8BIM#%d=",ID); + (void) FormatLocaleString(temp,MaxTextExtent,"8BIM#%d=",ID); (void) WriteBlobString(ofile,temp); if (ID == IPTC_ID) { formatString(ofile, "IPTC", 4); - formatIPTCfromBuffer(ofile, (char *)str, (long) count); + formatIPTCfromBuffer(ofile, (char *)str, (ssize_t) count); } else - formatString(ofile, (char *)str, (long) count); + formatString(ofile, (char *)str, (ssize_t) count); } str=(unsigned char *) RelinquishMagickMemory(str); PString=(unsigned char *) RelinquishMagickMemory(PString); @@ -2272,7 +2270,9 @@ static MagickBooleanType WriteMETAImage(const ImageInfo *image_info, unsigned char *info; - profile=GetImageProfile(image,"8bim"); + profile=GetImageProfile(image,"iptc"); + if (profile == (StringInfo *) NULL) + profile=GetImageProfile(image,"8bim"); if (profile == (StringInfo *) NULL) ThrowWriterException(CoderError,"No8BIMDataIsAvailable"); status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);