% July 2001 %
% %
% %
-% Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization %
+% Copyright 1999-2014 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 %
/*
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/module.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/string-private.h"
-#include "magick/token.h"
-#include "magick/utility.h"
+#include "MagickCore/studio.h"
+#include "MagickCore/blob.h"
+#include "MagickCore/blob-private.h"
+#include "MagickCore/channel.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"
\f
/*
Forward declarations.
*/
static MagickBooleanType
- WriteMETAImage(const ImageInfo *,Image *);
+ WriteMETAImage(const ImageInfo *,Image *,ExceptionInfo *);
\f
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
int
inputlen = BUFFER_SZ;
- ssize_t
- savedolen = 0L,
- outputlen = 0L;
-
MagickOffsetType
savedpos,
currentpos;
+ ssize_t
+ savedolen = 0L,
+ outputlen = 0L;
+
TokenInfo
*token_info;
}
#endif
-static char psheader[] = "\xFF\xED\0\0Photoshop 3.0\08BIM\x04\x04\0\0\0\0";
-
/* Embed binary IPTC data into a JPEG image. */
static int jpeg_embed(Image *ifile, Image *ofile, Image *iptc)
{
if (iptc != (Image *)NULL)
{
+ char
+ psheader[] = "\xFF\xED\0\0Photoshop 3.0\0" "8BIM\x04\x04\0\0\0\0";
+
len=(unsigned int) GetBlobSize(iptc);
if (len & 1)
len++; /* make the length even */
}
#endif
+static inline void CopyBlob(Image *source,Image *destination)
+{
+ ssize_t
+ i;
+
+ unsigned char
+ *buffer;
+
+ ssize_t
+ count,
+ length;
+
+ buffer=(unsigned char *) AcquireQuantumMemory(MagickMaxBufferExtent,
+ sizeof(*buffer));
+ if (buffer != (unsigned char *) NULL)
+ {
+ i=0;
+ while ((length=ReadBlob(source,MagickMaxBufferExtent,buffer)) != 0)
+ {
+ count=0;
+ for (i=0; i < (ssize_t) length; i+=count)
+ {
+ count=WriteBlob(destination,(size_t) (length-i),buffer+i);
+ if (count <= 0)
+ break;
+ }
+ if (i < (ssize_t) length)
+ break;
+ }
+ buffer=(unsigned char *) RelinquishMagickMemory(buffer);
+ }
+}
+
static Image *ReadMETAImage(const ImageInfo *image_info,
ExceptionInfo *exception)
{
*buff,
*image;
- int
- c;
-
MagickBooleanType
status;
image_info->filename);
assert(exception != (ExceptionInfo *) NULL);
assert(exception->signature == MagickSignature);
- image=AcquireImage(image_info);
+ image=AcquireImage(image_info,exception);
status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
if (status == MagickFalse)
{
}
image->columns=1;
image->rows=1;
- if (SetImageBackgroundColor(image) == MagickFalse)
+ if (SetImageBackgroundColor(image,exception) == MagickFalse)
{
- InheritException(exception,&image->exception);
image=DestroyImageList(image);
return((Image *) NULL);
}
/*
Read 8BIM binary metadata.
*/
- buff=AcquireImage((ImageInfo *) NULL);
+ buff=AcquireImage((ImageInfo *) NULL,exception);
if (buff == (Image *) NULL)
ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
blob=(unsigned char *) AcquireQuantumMemory(length,sizeof(unsigned char));
(void) WriteBlobByte(buff,0x0);
}
else
- {
- for ( ; ; )
- {
- c=ReadBlobByte(image);
- if (c == EOF)
- break;
- (void) WriteBlobByte(buff,(unsigned char) c);
- }
- }
- profile=AcquireStringInfo((size_t) GetBlobSize(buff));
- SetStringInfoDatum(profile,GetBlobStreamData(buff));
- status=SetImageProfile(image,"8bim",profile);
+ CopyBlob(image,buff);
+ profile=BlobToStringInfo(GetBlobStreamData(buff),(size_t)
+ GetBlobSize(buff));
+ if (profile == (StringInfo *) NULL)
+ ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
+ status=SetImageProfile(image,"8bim",profile,exception);
profile=DestroyStringInfo(profile);
if (status == MagickFalse)
ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
char
name[MaxTextExtent];
- (void) FormatMagickString(name,MaxTextExtent,"APP%d",1);
- buff=AcquireImage((ImageInfo *) NULL);
+ (void) FormatLocaleString(name,MaxTextExtent,"APP%d",1);
+ buff=AcquireImage((ImageInfo *) NULL,exception);
if (buff == (Image *) NULL)
ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
blob=(unsigned char *) AcquireQuantumMemory(length,sizeof(unsigned char));
ThrowReaderException(CoderError,"NoIPTCProfileAvailable");
}
profile=CloneStringInfo((StringInfo *) image_info->profile);
- iptc=AcquireImage((ImageInfo *) NULL);
+ iptc=AcquireImage((ImageInfo *) NULL,exception);
if (iptc == (Image *) NULL)
{
blob=DetachBlob(buff->blob);
}
}
else
- {
-#ifdef SLOW_METHOD
- for ( ; ; )
- {
- /* Really - really slow - FIX ME PLEASE!!!! */
- c=ReadBlobByte(image);
- if (c == EOF)
- break;
- (void) WriteBlobByte(buff,c);
- }
-#else
- ssize_t
- i;
-
- unsigned char
- *buffer;
-
- ssize_t
- count,
- length;
-
- buffer=(unsigned char *) AcquireQuantumMemory(MagickMaxBufferExtent,
- sizeof(*buffer));
- if (buffer != (unsigned char *) NULL)
- {
- i=0;
- while ((length=ReadBlob(image,MagickMaxBufferExtent,buffer)) != 0)
- {
- count=0;
- for (i=0; i < (ssize_t) length; i+=count)
- {
- count=WriteBlob(buff,(size_t) (length-i),buffer+i);
- if (count <= 0)
- break;
- }
- if (i < (ssize_t) length)
- break;
- }
- buffer=(unsigned char *) RelinquishMagickMemory(buffer);
- }
-#endif
- }
- profile=AcquireStringInfo((size_t) GetBlobSize(buff));
- SetStringInfoDatum(profile,GetBlobStreamData(buff));
- status=SetImageProfile(image,name,profile);
+ CopyBlob(image,buff);
+ profile=BlobToStringInfo(GetBlobStreamData(buff),(size_t)
+ GetBlobSize(buff));
+ if (profile == (StringInfo *) NULL)
+ ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
+ status=SetImageProfile(image,name,profile,exception);
profile=DestroyStringInfo(profile);
if (status == MagickFalse)
ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
if ((LocaleCompare(image_info->magick,"ICC") == 0) ||
(LocaleCompare(image_info->magick,"ICM") == 0))
{
- buff=AcquireImage((ImageInfo *) NULL);
+ buff=AcquireImage((ImageInfo *) NULL,exception);
if (buff == (Image *) NULL)
ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
blob=(unsigned char *) AcquireQuantumMemory(length,sizeof(unsigned char));
ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
}
AttachBlob(buff->blob,blob,length);
- for ( ; ; )
- {
- c=ReadBlobByte(image);
- if (c == EOF)
- break;
- (void) WriteBlobByte(buff,(unsigned char) c);
- }
- profile=AcquireStringInfo((size_t) GetBlobSize(buff));
- SetStringInfoDatum(profile,GetBlobStreamData(buff));
- (void) SetImageProfile(image,"icc",profile);
+ CopyBlob(image,buff);
+ profile=BlobToStringInfo(GetBlobStreamData(buff),(size_t)
+ GetBlobSize(buff));
+ if (profile == (StringInfo *) NULL)
+ ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
+ (void) SetImageProfile(image,"icc",profile,exception);
profile=DestroyStringInfo(profile);
blob=DetachBlob(buff->blob);
blob=(unsigned char *) RelinquishMagickMemory(blob);
}
if (LocaleCompare(image_info->magick,"IPTC") == 0)
{
- register unsigned char
- *p;
-
- buff=AcquireImage((ImageInfo *) NULL);
+ buff=AcquireImage((ImageInfo *) NULL,exception);
if (buff == (Image *) NULL)
ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
blob=(unsigned char *) AcquireQuantumMemory(length,sizeof(unsigned char));
ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
}
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\0");
- (void) WriteBlobByte(buff,0xc6);
- if (LocaleCompare(image_info->magick,"IPTCTEXT") == 0)
- {
- length=(size_t) parse8BIM(image,buff);
- if (length & 1)
- (void) WriteBlobByte(buff,0x00);
- }
- else if (LocaleCompare(image_info->magick,"IPTCWTEXT") == 0)
- {
- }
- else
- {
- for ( ; ; )
- {
- c=ReadBlobByte(image);
- if (c == EOF)
- break;
- (void) WriteBlobByte(buff,(unsigned char) c);
- }
- }
- profile=AcquireStringInfo((size_t) GetBlobSize(buff));
- /*
- subtract off the length of the 8BIM stuff.
- */
- length=GetStringInfoLength(profile)-12;
- p=GetStringInfoDatum(profile);
- p[10]=(unsigned char) (length >> 8);
- p[11]=(unsigned char) (length & 0xff);
- SetStringInfoDatum(profile,GetBlobStreamData(buff));
- (void) SetImageProfile(image,"8bim",profile);
+ CopyBlob(image,buff);
+ profile=BlobToStringInfo(GetBlobStreamData(buff),(size_t)
+ GetBlobSize(buff));
+ if (profile == (StringInfo *) NULL)
+ ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
+ (void) SetImageProfile(image,"8bim",profile,exception);
profile=DestroyStringInfo(profile);
blob=DetachBlob(buff->blob);
blob=(unsigned char *) RelinquishMagickMemory(blob);
}
if (LocaleCompare(image_info->magick,"XMP") == 0)
{
- buff=AcquireImage((ImageInfo *) NULL);
+ buff=AcquireImage((ImageInfo *) NULL,exception);
if (buff == (Image *) NULL)
ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
blob=(unsigned char *) AcquireQuantumMemory(length,sizeof(unsigned char));
ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
}
AttachBlob(buff->blob,blob,length);
- for ( ; ; )
- {
- c=ReadBlobByte(image);
- if (c == EOF)
- break;
- (void) WriteBlobByte(buff,(unsigned char) c);
- }
- profile=AcquireStringInfo((size_t) GetBlobSize(buff));
- SetStringInfoDatum(profile,GetBlobStreamData(buff));
- (void) SetImageProfile(image,"xmp",profile);
+ CopyBlob(image,buff);
+ profile=BlobToStringInfo(GetBlobStreamData(buff),(size_t)
+ GetBlobSize(buff));
+ if (profile == (StringInfo *) NULL)
+ ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
+ (void) SetImageProfile(image,"xmp",profile,exception);
profile=DestroyStringInfo(profile);
blob=DetachBlob(buff->blob);
blob=(unsigned char *) RelinquishMagickMemory(blob);
entry->description=ConstantString("Photoshop resource format");
entry->module=ConstantString("META");
(void) RegisterMagickInfo(entry);
-
entry=SetMagickInfo("8BIMTEXT");
entry->decoder=(DecodeImageHandler *) ReadMETAImage;
entry->encoder=(EncodeImageHandler *) WriteMETAImage;
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;
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;
entry->description=ConstantString("Raw application information");
entry->module=ConstantString("META");
(void) RegisterMagickInfo(entry);
-
entry=SetMagickInfo("APP1JPEG");
entry->decoder=(DecodeImageHandler *) ReadMETAImage;
entry->encoder=(EncodeImageHandler *) WriteMETAImage;
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;
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;
entry->description=ConstantString("Adobe XML metadata");
entry->module=ConstantString("META");
(void) RegisterMagickInfo(entry);
-
entry=SetMagickInfo("ICM");
entry->decoder=(DecodeImageHandler *) ReadMETAImage;
entry->encoder=(EncodeImageHandler *) WriteMETAImage;
entry->description=ConstantString("ICC Color Profile");
entry->module=ConstantString("META");
(void) RegisterMagickInfo(entry);
-
entry=SetMagickInfo("ICC");
entry->decoder=(DecodeImageHandler *) ReadMETAImage;
entry->encoder=(EncodeImageHandler *) WriteMETAImage;
entry->description=ConstantString("ICC Color Profile");
entry->module=ConstantString("META");
(void) RegisterMagickInfo(entry);
-
entry=SetMagickInfo("IPTC");
entry->decoder=(DecodeImageHandler *) ReadMETAImage;
entry->encoder=(EncodeImageHandler *) WriteMETAImage;
entry->description=ConstantString("IPTC Newsphoto");
entry->module=ConstantString("META");
(void) RegisterMagickInfo(entry);
-
entry=SetMagickInfo("IPTCTEXT");
entry->decoder=(DecodeImageHandler *) ReadMETAImage;
entry->encoder=(EncodeImageHandler *) WriteMETAImage;
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;
% The format of the WriteMETAImage method is:
%
% MagickBooleanType WriteMETAImage(const ImageInfo *image_info,
-% Image *image)
+% Image *image,ExceptionInfo *exception)
%
% Compression code contributed by Kyle Shorter.
%
%
% o image: A pointer to a Image structure.
%
+% o exception: return any errors or warnings in this structure.
+%
*/
static size_t GetIPTCStream(unsigned char **info,size_t length)
extent,
info_length;
- unsigned char
- buffer[4] = { '\0', '\0', '\0', '\0' };
-
unsigned int
marker;
info_length++;
if ((c & 0x80) != 0)
{
+ /*
+ Long format.
+ */
+ tag_length=0;
for (i=0; i < 4; i++)
{
- buffer[i]=(*p++);
+ tag_length<<=8;
+ tag_length|=(*p++);
length--;
if (length == 0)
break;
info_length++;
}
- tag_length=(((size_t) buffer[0]) << 24) |
- (((size_t) buffer[1]) << 16) |
- (((size_t) buffer[2]) << 8) | (((size_t) buffer[3]));
}
else
{
- tag_length=(size_t) (c << 8);
+ /*
+ Short format.
+ */
+ tag_length=((long) c) << 8;
c=(*p++);
length--;
if (length == 0)
break;
info_length++;
- tag_length|=c;
+ tag_length|=(long) c;
}
if (tag_length > (length+1))
break;
(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;
/* 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 );
/* 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 );
resCount=0;
foundOSType=0; /* found the OSType */
+ (void) foundOSType;
c=ReadBlobByte(ifile);
while (c != EOF)
{
* 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)
{
}
static MagickBooleanType WriteMETAImage(const ImageInfo *image_info,
- Image *image)
+ Image *image,ExceptionInfo *exception)
{
const StringInfo
*profile;
profile=GetImageProfile(image,"8bim");
if (profile == (StringInfo *) NULL)
ThrowWriterException(CoderError,"No8BIMDataIsAvailable");
- status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
if (status == MagickFalse)
return(status);
(void) WriteBlob(image,GetStringInfoLength(profile),
profile=GetImageProfile(image,"8bim");
if (profile == (StringInfo *) NULL)
ThrowWriterException(CoderError,"No8BIMDataIsAvailable");
- status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
info=GetStringInfoDatum(profile);
length=GetStringInfoLength(profile);
length=GetIPTCStream(&info,length);
profile=GetImageProfile(image,"8bim");
if (profile == (StringInfo *) NULL)
ThrowWriterException(CoderError,"No8BIMDataIsAvailable");
- status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
if (status == MagickFalse)
return(status);
- buff=AcquireImage((ImageInfo *) NULL);
+ buff=AcquireImage((ImageInfo *) NULL,exception);
if (buff == (Image *) NULL)
ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
AttachBlob(buff->blob,GetStringInfoDatum(profile),
length=GetIPTCStream(&info,length);
if (length == 0)
ThrowWriterException(CoderError,"NoIPTCProfileAvailable");
- status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
if (status == MagickFalse)
return(status);
- buff=AcquireImage((ImageInfo *) NULL);
+ buff=AcquireImage((ImageInfo *) NULL,exception);
if (buff == (Image *) NULL)
ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
AttachBlob(buff->blob,info,length);
profile=GetImageProfile(image,image_info->magick);
if (profile == (StringInfo *) NULL)
ThrowWriterException(CoderError,"NoAPP1DataIsAvailable");
- status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
if (status == MagickFalse)
return(status);
(void) WriteBlob(image,GetStringInfoLength(profile),
profile=GetImageProfile(image,"icc");
if (profile == (StringInfo *) NULL)
ThrowWriterException(CoderError,"NoColorProfileIsAvailable");
- status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+ assert(exception != (ExceptionInfo *) NULL);
+ assert(exception->signature == MagickSignature);
+ status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
if (status == MagickFalse)
return(status);
(void) WriteBlob(image,GetStringInfoLength(profile),