% July 1999 %
% %
% %
-% Copyright 1999-2010 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 %
#include "magick/exception-private.h"
#include "magick/image-private.h"
#include "magick/list.h"
+#include "magick/locale_.h"
#include "magick/log.h"
#include "magick/magick.h"
#include "magick/memory_.h"
Define declarations.
*/
#define MagickMaxBlobExtent 65541
-#if defined(MAGICKCORE_HAVE_FSEEKO)
-# define fseek fseeko
-# define ftell ftello
-#endif
#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
# define MAP_ANONYMOUS MAP_ANON
#endif
%
*/
-static inline size_t MagickMin(const size_t x,const size_t y)
+static inline MagickSizeType MagickMin(const MagickSizeType x,
+ const MagickSizeType y)
{
if (x < y)
return(x);
}
for (i=0; i < length; i+=count)
{
- count=(ssize_t) write(file,(const char *) blob+i,MagickMin(length-i,(size_t)
- SSIZE_MAX));
+ count=(ssize_t) write(file,(const char *) blob+i,(size_t) MagickMin(length-
+ i,(MagickSizeType) SSIZE_MAX));
if (count <= 0)
{
count=0;
return((Image *) NULL);
}
clone_info=CloneImageInfo(blob_info);
- (void) FormatMagickString(clone_info->filename,MaxTextExtent,"%s:%s",
+ (void) FormatLocaleString(clone_info->filename,MaxTextExtent,"%s:%s",
blob_info->magick,blob_info->filename);
image=ReadImage(clone_info,exception);
clone_info=DestroyImageInfo(clone_info);
BlobInfo
*clone_info;
- clone_info=(BlobInfo *) AcquireAlignedMemory(1,sizeof(*clone_info));
+ clone_info=(BlobInfo *) AcquireMagickMemory(sizeof(*clone_info));
if (clone_info == (BlobInfo *) NULL)
ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
GetBlobInfo(clone_info);
case StandardStream:
{
if (image->blob->synchronize != MagickFalse)
- status=fsync(fileno(image->blob->file));
+ {
+ status=fflush(image->blob->file);
+ status=fsync(fileno(image->blob->file));
+ }
status=fclose(image->blob->file);
break;
}
break;
}
case FifoStream:
+ break;
case BlobStream:
+ {
+ if (image->blob->file != (FILE *) NULL)
+ {
+ if (image->blob->synchronize != MagickFalse)
+ (void) fsync(fileno(image->blob->file));
+ status=fclose(image->blob->file);
+ }
break;
+ }
}
(void) DetachBlob(image->blob);
image->blob->status=status < 0 ? MagickTrue : MagickFalse;
% %
% %
% %
++ D i s c a r d B l o b B y t e s %
+% %
+% %
+% %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+% DiscardBlobBytes() discards bytes in a blob.
+%
+% The format of the DiscardBlobBytes method is:
+%
+% MagickBooleanType DiscardBlobBytes(Image *image,const size_t length)
+%
+% A description of each parameter follows.
+%
+% o image: the image.
+%
+% o length: the number of bytes to skip.
+%
+*/
+
+static inline const unsigned char *ReadBlobStream(Image *image,
+ const size_t length,unsigned char *data,ssize_t *count)
+{
+ assert(count != (ssize_t *) NULL);
+ assert(image->blob != (BlobInfo *) NULL);
+ if (image->blob->type != BlobStream)
+ {
+ *count=ReadBlob(image,length,data);
+ return(data);
+ }
+ if (image->blob->offset >= (MagickOffsetType) image->blob->length)
+ {
+ *count=0;
+ image->blob->eof=MagickTrue;
+ return(data);
+ }
+ data=image->blob->data+image->blob->offset;
+ *count=(ssize_t) MagickMin(length,(MagickSizeType) (image->blob->length-
+ image->blob->offset));
+ image->blob->offset+=(*count);
+ if (*count != (ssize_t) length)
+ image->blob->eof=MagickTrue;
+ return(data);
+}
+
+MagickExport MagickBooleanType DiscardBlobBytes(Image *image,
+ const MagickSizeType length)
+{
+ register MagickOffsetType
+ i;
+
+ size_t
+ quantum;
+
+ ssize_t
+ count;
+
+ unsigned char
+ buffer[16384];
+
+ assert(image != (Image *) NULL);
+ assert(image->signature == MagickSignature);
+ count=0;
+ for (i=0; i < (MagickOffsetType) length; i+=count)
+ {
+ quantum=(size_t) MagickMin(length-i,sizeof(buffer));
+ (void) ReadBlobStream(image,quantum,buffer,&count);
+ if (count <= 0)
+ {
+ count=0;
+ if (errno != EINTR)
+ break;
+ }
+ }
+ return(i < (MagickOffsetType) length ? MagickFalse : MagickTrue);
+}
+\f
+/*
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% %
+% %
+% %
+ D u p l i c a t e s B l o b %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
-% FileToBlob() returns the contents of a file as a blob. It returns the
-% file as a blob and its length. If an error occurs, NULL is returned.
+% FileToBlob() returns the contents of a file as a buffer terminated with
+% the '\0' character. The length of the buffer (not including the extra
+% terminating '\0' character) is returned via the 'length' parameter. Free
+% the buffer with RelinquishMagickMemory().
%
% The format of the FileToBlob method is:
%
ThrowFileException(exception,BlobError,"UnableToOpenFile",filename);
return((unsigned char *) NULL);
}
- offset=(MagickOffsetType) MagickSeek(file,0,SEEK_END);
+ offset=(MagickOffsetType) lseek(file,0,SEEK_END);
count=0;
if ((offset < 0) || (offset != (MagickOffsetType) ((ssize_t) offset)))
{
*/
quantum=(size_t) MagickMaxBufferExtent;
if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
- quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
+ quantum=(size_t) MagickMin((MagickSizeType) file_info.st_size,
+ MagickMaxBufferExtent);
blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
for (i=0; blob != (unsigned char *) NULL; i+=count)
{
if ((size_t) (i+count) >= extent)
break;
}
- file=close(file);
+ if (LocaleCompare(filename,"-") != 0)
+ file=close(file);
if (blob == (unsigned char *) NULL)
{
(void) ThrowMagickException(exception,GetMagickModule(),
ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
return((unsigned char *) NULL);
}
- *length=MagickMin(i+count,extent);
+ *length=(size_t) MagickMin(i+count,extent);
blob[*length]='\0';
return(blob);
}
- *length=MagickMin((size_t) offset,extent);
+ *length=(size_t) MagickMin((MagickSizeType) offset,extent);
blob=(unsigned char *) NULL;
- if (~(*length) >= MaxTextExtent)
+ if (~(*length) >= (MaxTextExtent-1))
blob=(unsigned char *) AcquireQuantumMemory(*length+MaxTextExtent,
sizeof(*blob));
if (blob == (unsigned char *) NULL)
{
- file=close(file)-1;
+ file=close(file);
(void) ThrowMagickException(exception,GetMagickModule(),
ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
return((unsigned char *) NULL);
map=MapBlob(file,ReadMode,0,*length);
if (map != (unsigned char *) NULL)
{
- (void) CopyMagickMemory(blob,map,*length);
+ (void) memcpy(blob,map,*length);
(void) UnmapBlob(map,*length);
}
else
{
- (void) MagickSeek(file,0,SEEK_SET);
+ (void) lseek(file,0,SEEK_SET);
for (i=0; i < *length; i+=count)
{
- count=(ssize_t) read(file,blob+i,MagickMin(*length-i,(size_t)
- SSIZE_MAX));
+ count=(ssize_t) read(file,blob+i,(size_t) MagickMin(*length-i,
+ (MagickSizeType) SSIZE_MAX));
if (count <= 0)
{
count=0;
}
}
blob[*length]='\0';
- file=close(file);
+ if (LocaleCompare(filename,"-") != 0)
+ file=close(file);
if (file == -1)
{
blob=(unsigned char *) RelinquishMagickMemory(blob);
return(0);
}
q=image->blob->data+image->blob->offset;
- (void) CopyMagickMemory(q,data,length);
+ (void) memcpy(q,data,length);
image->blob->offset+=length;
if (image->blob->offset >= (MagickOffsetType) image->blob->length)
image->blob->length=(size_t) image->blob->offset;
}
quantum=(size_t) MagickMaxBufferExtent;
if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
- quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
+ quantum=(size_t) MagickMin(file_info.st_size,MagickMaxBufferExtent);
blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
if (blob == (unsigned char *) NULL)
{
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% ImageToBlob() implements direct to memory image formats. It returns the
-% image as a blob and its length. The magick member of the ImageInfo structure
-% determines the format of the returned blob (GIF, JPEG, PNG, etc.)
+% image as a formatted blob and its length. The magick member of the Image
+% structure determines the format of the returned blob (GIF, JPEG, PNG,
+% etc.). This method is the equivalent of WriteImage(), but writes the
+% formatted "file" to a memory buffer rather than to an actual file.
%
% The format of the ImageToBlob method is:
%
blob_info->file=fdopen(file,"wb");
if (blob_info->file != (FILE *) NULL)
{
- (void) FormatMagickString(image->filename,MaxTextExtent,"%s:%s",
+ (void) FormatLocaleString(image->filename,MaxTextExtent,"%s:%s",
image->magick,unique);
status=WriteImage(blob_info,image);
(void) fclose(blob_info->file);
% o exception: return any errors or warnings in this structure.
%
*/
-
-static inline const unsigned char *ReadBlobStream(Image *image,
- const size_t length,unsigned char *data,ssize_t *count)
-{
- assert(count != (ssize_t *) NULL);
- assert(image->blob != (BlobInfo *) NULL);
- if (image->blob->type != BlobStream)
- {
- *count=ReadBlob(image,length,data);
- return(data);
- }
- if (image->blob->offset >= (MagickOffsetType) image->blob->length)
- {
- *count=0;
- image->blob->eof=MagickTrue;
- return(data);
- }
- data=image->blob->data+image->blob->offset;
- *count=(ssize_t) MagickMin(length,(size_t) (image->blob->length-
- image->blob->offset));
- image->blob->offset+=(*count);
- if (*count != (ssize_t) length)
- image->blob->eof=MagickTrue;
- return(data);
-}
-
MagickExport MagickBooleanType ImageToFile(Image *image,char *filename,
ExceptionInfo *exception)
{
}
quantum=(size_t) MagickMaxBufferExtent;
if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
- quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
+ quantum=(size_t) MagickMin((MagickSizeType) file_info.st_size,
+ MagickMaxBufferExtent);
buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
if (buffer == (unsigned char *) NULL)
{
if (i < length)
break;
}
- file=close(file);
+ if (LocaleCompare(filename,"-") != 0)
+ file=close(file);
buffer=(unsigned char *) RelinquishMagickMemory(buffer);
if ((file == -1) || (i < length))
{
blob_info->file=fdopen(file,"wb");
if (blob_info->file != (FILE *) NULL)
{
- (void) FormatMagickString(filename,MaxTextExtent,"%s:%s",
+ (void) FormatLocaleString(filename,MaxTextExtent,"%s:%s",
images->magick,unique);
status=WriteImages(blob_info,images,filename,exception);
(void) fclose(blob_info->file);
(void) RelinquishUniqueFileResource(filename);
return(MagickFalse);
}
- (void) FormatMagickString(byte_image->filename,MaxTextExtent,"%s:%s",format,
+ (void) FormatLocaleString(byte_image->filename,MaxTextExtent,"%s:%s",format,
filename);
DestroyBlob(byte_image);
byte_image->blob=CloneBlobInfo((BlobInfo *) NULL);
}
quantum=(size_t) MagickMaxBufferExtent;
if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
- quantum=MagickMin((size_t) file_info.st_size,MagickMaxBufferExtent);
+ quantum=(size_t) MagickMin(file_info.st_size,MagickMaxBufferExtent);
buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
if (buffer == (unsigned char *) NULL)
{
{
(void) CopyMagickString(filename,image->filename,MaxTextExtent);
if ((image_info->adjoin == MagickFalse) ||
- (IsGlob(filename) != MagickFalse))
+ (strchr(filename,'%') != (char *) NULL))
{
/*
Form filename for multi-part images.
GetPathComponent(image->filename,RootPath,path);
if (*extension == '\0')
- (void) FormatMagickString(filename,MaxTextExtent,"%s-%.20g",
+ (void) FormatLocaleString(filename,MaxTextExtent,"%s-%.20g",
path,(double) image->scene);
else
- (void) FormatMagickString(filename,MaxTextExtent,
- "%s-%.20g.%s",path,(double) image->scene,extension);
+ (void) FormatLocaleString(filename,MaxTextExtent,"%s-%.20g.%s",
+ path,(double) image->scene,extension);
}
(void) CopyMagickString(image->filename,filename,MaxTextExtent);
#if defined(macintosh)
image->blob->type=FileStream;
#if defined(MAGICKCORE_HAVE_SETVBUF)
- (void) setvbuf(image->blob->file,(char *) NULL,(int) _IOFBF,
- 16384);
+ (void) setvbuf(image->blob->file,(char *) NULL,(int) _IOFBF,16384);
#endif
(void) ResetMagickMemory(magick,0,sizeof(magick));
count=fread(magick,1,sizeof(magick),image->blob->file);
image->blob->type=BZipStream;
}
#endif
- if (image->blob->type == FileStream)
- {
- const MagickInfo
- *magick_info;
-
- ExceptionInfo
- *sans_exception;
-
- struct stat
- *properties;
-
- sans_exception=AcquireExceptionInfo();
- magick_info=GetMagickInfo(image_info->magick,sans_exception);
- sans_exception=DestroyExceptionInfo(sans_exception);
- properties=(&image->blob->properties);
- if ((magick_info != (const MagickInfo *) NULL) &&
- (GetMagickBlobSupport(magick_info) != MagickFalse) &&
- (properties->st_size <= MagickMaxBufferExtent))
- {
- size_t
- length;
-
- void
- *blob;
-
- length=(size_t) properties->st_size;
- blob=MapBlob(fileno(image->blob->file),ReadMode,0,length);
- if (blob != (void *) NULL)
- {
- /*
- Format supports blobs-- use memory-mapped I/O.
- */
- if (image_info->file != (FILE *) NULL)
- image->blob->exempt=MagickFalse;
- else
- {
- (void) fclose(image->blob->file);
- image->blob->file=(FILE *) NULL;
- }
- AttachBlob(image->blob,blob,length);
- image->blob->mapped=MagickTrue;
- }
- }
- }
+ if (image->blob->type == FileStream)
+ {
+ const MagickInfo
+ *magick_info;
+
+ ExceptionInfo
+ *sans_exception;
+
+ struct stat
+ *properties;
+
+ sans_exception=AcquireExceptionInfo();
+ magick_info=GetMagickInfo(image_info->magick,sans_exception);
+ sans_exception=DestroyExceptionInfo(sans_exception);
+ properties=(&image->blob->properties);
+ if ((magick_info != (const MagickInfo *) NULL) &&
+ (GetMagickBlobSupport(magick_info) != MagickFalse) &&
+ (properties->st_size <= MagickMaxBufferExtent))
+ {
+ size_t
+ length;
+
+ void
+ *blob;
+
+ length=(size_t) properties->st_size;
+ blob=MapBlob(fileno(image->blob->file),ReadMode,0,length);
+ if (blob != (void *) NULL)
+ {
+ /*
+ Format supports blobs-- use memory-mapped I/O.
+ */
+ if (image_info->file != (FILE *) NULL)
+ image->blob->exempt=MagickFalse;
+ else
+ {
+ (void) fclose(image->blob->file);
+ image->blob->file=(FILE *) NULL;
+ }
+ AttachBlob(image->blob,blob,length);
+ image->blob->mapped=MagickTrue;
+ }
+ }
+ }
}
}
else
ResourceLimitFatalError,"MemoryAllocationFailed","`%s'","");
return((Image *) NULL);
}
- (void) CopyMagickMemory(ping_info->blob,blob,length);
+ (void) memcpy(ping_info->blob,blob,length);
ping_info->length=length;
ping_info->ping=MagickTrue;
image=ReadStream(ping_info,&PingStream,exception);
break;
}
p=image->blob->data+image->blob->offset;
- count=(ssize_t) MagickMin(length,(size_t) (image->blob->length-
- image->blob->offset));
+ count=(ssize_t) MagickMin(length,image->blob->length-image->blob->offset);
image->blob->offset+=count;
if (count != (ssize_t) length)
image->blob->eof=MagickTrue;
- (void) CopyMagickMemory(q,p,(size_t) count);
+ (void) memcpy(q,p,(size_t) count);
break;
}
}
*/
MagickExport MagickSizeType ReadBlobLongLong(Image *image)
{
+ MagickSizeType
+ value;
+
register const unsigned char
*p;
unsigned char
buffer[8];
- MagickSizeType
- value;
-
assert(image != (Image *) NULL);
assert(image->signature == MagickSignature);
*buffer='\0';
count;
unsigned char
- buffer[4];
+ buffer[8];
assert(image != (Image *) NULL);
assert(image->signature == MagickSignature);
break;
case FileStream:
{
- if (fseek(image->blob->file,(long) offset,whence) < 0)
+ if (fseek(image->blob->file,offset,whence) < 0)
return(-1);
image->blob->offset=TellBlob(image);
break;
}
}
q=image->blob->data+image->blob->offset;
- (void) CopyMagickMemory(q,p,length);
+ (void) memcpy(q,p,length);
image->blob->offset+=length;
if (image->blob->offset >= (MagickOffsetType) image->blob->length)
image->blob->length=(size_t) image->blob->offset;