% MagickCore Binary Large OBjectS Methods %
% %
% Software Design %
-% John Cristy %
+% Cristy %
% July 1999 %
% %
% %
-% 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 "MagickCore/log.h"
#include "MagickCore/magick.h"
#include "MagickCore/memory_.h"
+#include "MagickCore/nt-base-private.h"
#include "MagickCore/policy.h"
#include "MagickCore/resource_.h"
#include "MagickCore/semaphore.h"
#include "MagickCore/string-private.h"
#include "MagickCore/token.h"
#include "MagickCore/utility.h"
-#if defined(MAGICKCORE_HAVE_MMAP_FILEIO) && !defined(MAGICKCORE_WINDOWS_SUPPORT)
-# include <sys/mman.h>
-#endif
+#include "MagickCore/utility-private.h"
#if defined(MAGICKCORE_ZLIB_DELEGATE)
#include "zlib.h"
#endif
#if !defined(MAP_FAILED)
#define MAP_FAILED ((void *) -1)
#endif
-#if !defined(MS_SYNC)
-#define MS_SYNC 0x04
-#endif
#if defined(__OS2__)
#include <io.h>
#define _O_BINARY O_BINARY
/*
Typedef declarations.
*/
+typedef union FileInfo
+{
+ FILE
+ *file;
+
+#if defined(MAGICKCORE_ZLIB_DELEGATE)
+ gzFile
+ gzfile;
+#endif
+
+#if defined(MAGICKCORE_BZLIB_DELEGATE)
+ BZFILE
+ *bzfile;
+#endif
+} FileInfo;
+
struct _BlobInfo
{
size_t
StreamType
type;
- FILE
- *file;
+ FileInfo
+ file_info;
struct stat
properties;
blob_info->quantum=(size_t) MagickMaxBlobExtent;
blob_info->offset=0;
blob_info->type=BlobStream;
- blob_info->file=(FILE *) NULL;
+ blob_info->file_info.file=(FILE *) NULL;
blob_info->data=(unsigned char *) blob;
blob_info->mapped=MagickFalse;
}
if (*filename == '\0')
file=AcquireUniqueFileResource(filename);
else
- file=open(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
+ file=open_utf8(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
if (file == -1)
{
ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
}
for (i=0; i < length; i+=count)
{
- count=(ssize_t) write(file,(const char *) blob+i,(size_t) MagickMin(length-
- i,(MagickSizeType) SSIZE_MAX));
+ count=write(file,(const char *) blob+i,(size_t) MagickMin(length-i,
+ (MagickSizeType) SSIZE_MAX));
if (count <= 0)
{
count=0;
(void) FormatLocaleString(clone_info->filename,MaxTextExtent,"%s:%s",
blob_info->magick,blob_info->filename);
image=ReadImage(clone_info,exception);
+ if (image != (Image *) NULL)
+ {
+ Image
+ *images;
+
+ /*
+ Restore original filenames.
+ */
+ for (images=GetFirstImageInList(image); images != (Image *) NULL; )
+ {
+ (void) CopyMagickMemory(images->filename,image_info->filename,
+ sizeof(images->filename));
+ (void) CopyMagickMemory(images->magick_filename,image_info->filename,
+ sizeof(images->magick_filename));
+ images=GetNextImageInList(images);
+ }
+ }
clone_info=DestroyImageInfo(clone_info);
(void) RelinquishUniqueFileResource(blob_info->filename);
blob_info=DestroyImageInfo(blob_info);
clone_info->status=blob_info->status;
clone_info->temporary=blob_info->temporary;
clone_info->type=blob_info->type;
- clone_info->file=blob_info->file;
+ clone_info->file_info.file=blob_info->file_info.file;
clone_info->properties=blob_info->properties;
clone_info->stream=blob_info->stream;
clone_info->data=blob_info->data;
assert(image->blob != (BlobInfo *) NULL);
if (image->blob->type == UndefinedStream)
return(MagickTrue);
- if (image->blob->synchronize != MagickFalse)
- SyncBlob(image);
- image->blob->size=GetBlobSize(image);
- image->extent=image->blob->size;
- image->blob->eof=MagickFalse;
- if (image->blob->exempt != MagickFalse)
- {
- image->blob->type=UndefinedStream;
- return(MagickTrue);
- }
- status=0;
+ status=SyncBlob(image);
switch (image->blob->type)
{
case UndefinedStream:
+ case StandardStream:
break;
case FileStream:
- case StandardStream:
case PipeStream:
{
- status=ferror(image->blob->file);
+ if (image->blob->synchronize != MagickFalse)
+ status=fsync(fileno(image->blob->file_info.file));
+ status=ferror(image->blob->file_info.file);
break;
}
case ZipStream:
{
#if defined(MAGICKCORE_ZLIB_DELEGATE)
- (void) gzerror(image->blob->file,&status);
+ (void) gzerror(image->blob->file_info.gzfile,&status);
#endif
break;
}
case BZipStream:
{
#if defined(MAGICKCORE_BZLIB_DELEGATE)
- (void) BZ2_bzerror((BZFILE *) image->blob->file,&status);
+ (void) BZ2_bzerror(image->blob->file_info.bzfile,&status);
#endif
break;
}
case FifoStream:
+ break;
case BlobStream:
+ {
+ if ((image->blob->file_info.file != (FILE *) NULL) &&
+ (image->blob->synchronize != MagickFalse))
+ {
+ (void) fsync(fileno(image->blob->file_info.file));
+ status=ferror(image->blob->file_info.file);
+ }
break;
+ }
}
image->blob->status=status < 0 ? MagickTrue : MagickFalse;
+ image->blob->size=GetBlobSize(image);
+ image->extent=image->blob->size;
+ image->blob->eof=MagickFalse;
+ if (image->blob->exempt != MagickFalse)
+ {
+ image->blob->type=UndefinedStream;
+ return(image->blob->status);
+ }
switch (image->blob->type)
{
case UndefinedStream:
+ case StandardStream:
break;
case FileStream:
- case StandardStream:
{
- if (image->blob->synchronize != MagickFalse)
- {
- status=fflush(image->blob->file);
- status=fsync(fileno(image->blob->file));
- }
- status=fclose(image->blob->file);
+ status=fclose(image->blob->file_info.file);
break;
}
case PipeStream:
{
#if defined(MAGICKCORE_HAVE_PCLOSE)
- status=pclose(image->blob->file);
+ status=pclose(image->blob->file_info.file);
#endif
break;
}
case ZipStream:
{
#if defined(MAGICKCORE_ZLIB_DELEGATE)
- status=gzclose(image->blob->file);
+ status=gzclose(image->blob->file_info.gzfile);
#endif
break;
}
case BZipStream:
{
#if defined(MAGICKCORE_BZLIB_DELEGATE)
- BZ2_bzclose((BZFILE *) image->blob->file);
+ BZ2_bzclose(image->blob->file_info.bzfile);
#endif
break;
}
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);
- }
+ if (image->blob->file_info.file != (FILE *) NULL)
+ status=fclose(image->blob->file_info.file);
break;
}
}
return;
(void) CloseBlob(image);
if (image->blob->mapped != MagickFalse)
- (void) UnmapBlob(image->blob->data,image->blob->length);
+ {
+ (void) UnmapBlob(image->blob->data,image->blob->length);
+ RelinquishMagickResource(MapResource,image->blob->length);
+ }
if (image->blob->semaphore != (SemaphoreInfo *) NULL)
- DestroySemaphoreInfo(&image->blob->semaphore);
+ RelinquishSemaphoreInfo(&image->blob->semaphore);
image->blob->signature=(~MagickSignature);
image->blob=(BlobInfo *) RelinquishMagickMemory(image->blob);
}
if (blob_info->debug != MagickFalse)
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
if (blob_info->mapped != MagickFalse)
- (void) UnmapBlob(blob_info->data,blob_info->length);
+ {
+ (void) UnmapBlob(blob_info->data,blob_info->length);
+ RelinquishMagickResource(MapResource,blob_info->length);
+ }
blob_info->mapped=MagickFalse;
blob_info->length=0;
blob_info->offset=0;
blob_info->eof=MagickFalse;
blob_info->exempt=MagickFalse;
blob_info->type=UndefinedStream;
- blob_info->file=(FILE *) NULL;
+ blob_info->file_info.file=(FILE *) NULL;
data=blob_info->data;
blob_info->data=(unsigned char *) NULL;
blob_info->stream=(StreamHandler) NULL;
switch (image->blob->type)
{
case UndefinedStream:
+ case StandardStream:
break;
case FileStream:
- case StandardStream:
case PipeStream:
{
- image->blob->eof=feof(image->blob->file) != 0 ? MagickTrue : MagickFalse;
+ image->blob->eof=feof(image->blob->file_info.file) != 0 ? MagickTrue :
+ MagickFalse;
break;
}
case ZipStream:
status;
status=0;
- (void) BZ2_bzerror((BZFILE *) image->blob->file,&status);
+ (void) BZ2_bzerror(image->blob->file_info.bzfile,&status);
image->blob->eof=status == BZ_UNEXPECTED_EOF ? MagickTrue : MagickFalse;
#endif
break;
*length=0;
file=fileno(stdin);
if (LocaleCompare(filename,"-") != 0)
- file=open(filename,O_RDONLY | O_BINARY);
+ file=open_utf8(filename,O_RDONLY | O_BINARY,0);
if (file == -1)
{
ThrowFileException(exception,BlobError,"UnableToOpenFile",filename);
}
offset=(MagickOffsetType) lseek(file,0,SEEK_END);
count=0;
- if ((offset < 0) || (offset != (MagickOffsetType) ((ssize_t) offset)))
+ if ((file == fileno(stdin)) || (offset < 0) ||
+ (offset != (MagickOffsetType) ((ssize_t) offset)))
{
size_t
quantum;
struct stat
- file_info;
+ file_stats;
/*
Stream is not seekable.
*/
+ offset=(MagickOffsetType) lseek(file,0,SEEK_SET);
quantum=(size_t) MagickMaxBufferExtent;
- if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
- quantum=(size_t) MagickMin((MagickSizeType) file_info.st_size,
+ if ((fstat(file,&file_stats) == 0) && (file_stats.st_size != 0))
+ quantum=(size_t) MagickMin((MagickSizeType) file_stats.st_size,
MagickMaxBufferExtent);
blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
for (i=0; blob != (unsigned char *) NULL; i+=count)
{
- count=(ssize_t) read(file,blob+i,quantum);
+ count=read(file,blob+i,quantum);
if (count <= 0)
{
count=0;
if (errno != EINTR)
break;
}
- if (~(1UL*i) < (quantum+1))
+ if (~((size_t) i) < (quantum+1))
{
blob=(unsigned char *) RelinquishMagickMemory(blob);
break;
(void) lseek(file,0,SEEK_SET);
for (i=0; i < *length; i+=count)
{
- count=(ssize_t) read(file,blob+i,(size_t) MagickMin(*length-i,
- (MagickSizeType) SSIZE_MAX));
+ count=read(file,blob+i,(size_t) MagickMin(*length-i,(MagickSizeType)
+ SSIZE_MAX));
if (count <= 0)
{
count=0;
extent=(MagickSizeType) (image->blob->offset+(MagickOffsetType) length);
if (extent >= image->blob->extent)
{
- image->blob->quantum<<=1;
extent=image->blob->extent+image->blob->quantum+length;
+ image->blob->quantum<<=1;
if (SetBlobExtent(image,extent) == MagickFalse)
return(0);
}
return((ssize_t) length);
}
-MagickExport MagickBooleanType FileToImage(Image *image,const char *filename)
+MagickExport MagickBooleanType FileToImage(Image *image,const char *filename,
+ ExceptionInfo *exception)
{
int
file;
count;
struct stat
- file_info;
+ file_stats;
unsigned char
*blob;
assert(image->signature == MagickSignature);
assert(filename != (const char *) NULL);
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
- file=open(filename,O_RDONLY | O_BINARY);
+ file=fileno(stdin);
+ if (LocaleCompare(filename,"-") != 0)
+ file=open_utf8(filename,O_RDONLY | O_BINARY,0);
if (file == -1)
{
- ThrowFileException(&image->exception,BlobError,"UnableToOpenBlob",
- filename);
+ ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
return(MagickFalse);
}
quantum=(size_t) MagickMaxBufferExtent;
- if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
- quantum=(size_t) MagickMin(file_info.st_size,MagickMaxBufferExtent);
+ if ((fstat(file,&file_stats) == 0) && (file_stats.st_size != 0))
+ quantum=(size_t) MagickMin(file_stats.st_size,MagickMaxBufferExtent);
blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
if (blob == (unsigned char *) NULL)
{
- ThrowFileException(&image->exception,ResourceLimitError,
- "MemoryAllocationFailed",filename);
+ ThrowFileException(exception,ResourceLimitError,"MemoryAllocationFailed",
+ filename);
return(MagickFalse);
}
for ( ; ; )
{
- count=(ssize_t) read(file,blob,quantum);
+ count=read(file,blob,quantum);
if (count <= 0)
{
count=0;
count=WriteBlobStream(image,length,blob);
if (count != (ssize_t) length)
{
- ThrowFileException(&image->exception,BlobError,"UnableToWriteBlob",
- filename);
+ ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
break;
}
}
file=close(file);
if (file == -1)
- ThrowFileException(&image->exception,BlobError,"UnableToWriteBlob",
- filename);
+ ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
blob=(unsigned char *) RelinquishMagickMemory(blob);
return(MagickTrue);
}
% o image: the image.
%
*/
-MagickExport MagickBooleanType GetBlobError(const Image *image)
+MagickPrivate MagickBooleanType GetBlobError(const Image *image)
{
assert(image != (const Image *) NULL);
assert(image->signature == MagickSignature);
{
assert(image != (const Image *) NULL);
assert(image->signature == MagickSignature);
- return(image->blob->file);
+ return(image->blob->file_info.file);
}
\f
/*
% o blob_info: Specifies a pointer to a BlobInfo structure.
%
*/
-MagickExport void GetBlobInfo(BlobInfo *blob_info)
+MagickPrivate void GetBlobInfo(BlobInfo *blob_info)
{
assert(blob_info != (BlobInfo *) NULL);
(void) ResetMagickMemory(blob_info,0,sizeof(*blob_info));
blob_info->properties.st_ctime=time((time_t *) NULL);
blob_info->debug=IsEventLogging();
blob_info->reference_count=1;
- blob_info->semaphore=AllocateSemaphoreInfo();
+ blob_info->semaphore=AcquireSemaphoreInfo();
blob_info->signature=MagickSignature;
}
\f
% o image: the image.
%
*/
-MagickExport const struct stat *GetBlobProperties(const Image *image)
+MagickPrivate const struct stat *GetBlobProperties(const Image *image)
{
assert(image != (Image *) NULL);
assert(image->signature == MagickSignature);
extent=image->blob->size;
break;
}
+ case StandardStream:
+ {
+ extent=image->blob->size;
+ break;
+ }
case FileStream:
{
- if (fstat(fileno(image->blob->file),&image->blob->properties) == 0)
+ if (fstat(fileno(image->blob->file_info.file),&image->blob->properties) == 0)
extent=(MagickSizeType) image->blob->properties.st_size;
break;
}
- case StandardStream:
case PipeStream:
{
extent=image->blob->size;
% o image: the image.
%
*/
-MagickExport StreamHandler GetBlobStreamHandler(const Image *image)
+MagickPrivate StreamHandler GetBlobStreamHandler(const Image *image)
{
assert(image != (const Image *) NULL);
assert(image->signature == MagickSignature);
%
% o image: the image.
%
-% o length: This pointer to a size_t integer sets the initial length of the
-% blob. On return, it reflects the actual length of the blob.
+% o length: return the actual length of the blob.
%
% o exception: return any errors or warnings in this structure.
%
(void) CloseBlob(image);
image->blob->exempt=MagickTrue;
*image->filename='\0';
- status=WriteImage(blob_info,image);
- if ((status == MagickFalse) || (image->blob->length == 0))
- InheritException(exception,&image->exception);
+ status=WriteImage(blob_info,image,exception);
+ *length=image->blob->length;
+ blob=DetachBlob(image->blob);
+ if (status == MagickFalse)
+ blob=(unsigned char *) RelinquishMagickMemory(blob);
else
- {
- *length=image->blob->length;
- blob=DetachBlob(image->blob);
- blob=(unsigned char *) ResizeQuantumMemory(blob,*length,
- sizeof(*blob));
- }
+ blob=(unsigned char *) ResizeQuantumMemory(blob,*length+1,
+ sizeof(*blob));
}
}
else
{
(void) FormatLocaleString(image->filename,MaxTextExtent,"%s:%s",
image->magick,unique);
- status=WriteImage(blob_info,image);
+ status=WriteImage(blob_info,image,exception);
+ (void) CloseBlob(image);
(void) fclose(blob_info->file);
- if (status == MagickFalse)
- InheritException(exception,&image->exception);
- else
- blob=FileToBlob(image->filename,~0UL,length,exception);
+ if (status != MagickFalse)
+ blob=FileToBlob(unique,~0UL,length,exception);
}
(void) RelinquishUniqueFileResource(unique);
}
count;
struct stat
- file_info;
+ file_stats;
unsigned char
*buffer;
if (LocaleCompare(filename,"-") == 0)
file=fileno(stdout);
else
- file=open(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
+ file=open_utf8(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
if (file == -1)
{
ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
return(MagickFalse);
}
quantum=(size_t) MagickMaxBufferExtent;
- if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
- quantum=(size_t) MagickMin((MagickSizeType) file_info.st_size,
+ if ((fstat(file,&file_stats) == 0) && (file_stats.st_size != 0))
+ quantum=(size_t) MagickMin((MagickSizeType) file_stats.st_size,
MagickMaxBufferExtent);
buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
if (buffer == (unsigned char *) NULL)
%
% o images: the image list.
%
-% o length: This pointer to a size_t integer sets the initial length of the
-% blob. On return, it reflects the actual length of the blob.
+% o length: return the actual length of the blob.
%
% o exception: return any errors or warnings in this structure.
%
exception);
if (*blob_info->magick != '\0')
(void) CopyMagickString(images->magick,blob_info->magick,MaxTextExtent);
- if (blob_info->adjoin == MagickFalse)
- {
- blob_info=DestroyImageInfo(blob_info);
- return(ImageToBlob(image_info,images,length,exception));
- }
magick_info=GetMagickInfo(images->magick,exception);
if (magick_info == (const MagickInfo *) NULL)
{
images->filename);
return(blob);
}
+ if (GetMagickAdjoin(magick_info) == MagickFalse)
+ {
+ blob_info=DestroyImageInfo(blob_info);
+ return(ImageToBlob(image_info,images,length,exception));
+ }
(void) CopyMagickString(blob_info->magick,images->magick,MaxTextExtent);
if (GetMagickBlobSupport(magick_info) != MagickFalse)
{
ResourceLimitError,"MemoryAllocationFailed","`%s'",images->filename);
else
{
+ (void) CloseBlob(images);
images->blob->exempt=MagickTrue;
*images->filename='\0';
status=WriteImages(blob_info,images,images->filename,exception);
- if ((status == MagickFalse) || (images->blob->length == 0))
- InheritException(exception,&images->exception);
+ *length=images->blob->length;
+ blob=DetachBlob(images->blob);
+ if (status == MagickFalse)
+ blob=(unsigned char *) RelinquishMagickMemory(blob);
else
- {
- *length=images->blob->length;
- blob=DetachBlob(images->blob);
- blob=(unsigned char *) ResizeQuantumMemory(blob,*length,
- sizeof(*blob));
- }
+ blob=(unsigned char *) ResizeQuantumMemory(blob,*length+1,
+ sizeof(*blob));
}
}
else
(void) FormatLocaleString(filename,MaxTextExtent,"%s:%s",
images->magick,unique);
status=WriteImages(blob_info,images,filename,exception);
+ (void) CloseBlob(images);
(void) fclose(blob_info->file);
- if (status == MagickFalse)
- InheritException(exception,&images->exception);
- else
- blob=FileToBlob(images->filename,~0UL,length,exception);
+ if (status != MagickFalse)
+ blob=FileToBlob(unique,~0UL,length,exception);
}
(void) RelinquishUniqueFileResource(unique);
}
count;
struct stat
- file_info;
+ file_stats;
unsigned char
*buffer;
byte_image->blob=CloneBlobInfo((BlobInfo *) NULL);
write_info=CloneImageInfo(image_info);
SetImageInfoFile(write_info,unique_file);
- status=WriteImage(write_info,byte_image);
+ status=WriteImage(write_info,byte_image,exception);
write_info=DestroyImageInfo(write_info);
byte_image=DestroyImage(byte_image);
(void) fclose(unique_file);
/*
Inject into image stream.
*/
- file=open(filename,O_RDONLY | O_BINARY);
+ file=open_utf8(filename,O_RDONLY | O_BINARY,0);
if (file == -1)
{
(void) RelinquishUniqueFileResource(filename);
return(MagickFalse);
}
quantum=(size_t) MagickMaxBufferExtent;
- if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
- quantum=(size_t) MagickMin(file_info.st_size,MagickMaxBufferExtent);
+ if ((fstat(file,&file_stats) == 0) && (file_stats.st_size != 0))
+ quantum=(size_t) MagickMin(file_stats.st_size,MagickMaxBufferExtent);
buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
if (buffer == (unsigned char *) NULL)
{
}
for (i=0; ; i+=count)
{
- count=(ssize_t) read(file,buffer,quantum);
+ count=read(file,buffer,quantum);
if (count <= 0)
{
count=0;
% o image: the image.
%
*/
-MagickExport MagickBooleanType IsBlobExempt(const Image *image)
+MagickPrivate MagickBooleanType IsBlobExempt(const Image *image)
{
assert(image != (const Image *) NULL);
assert(image->signature == MagickSignature);
% o image: the image.
%
*/
-MagickExport MagickBooleanType IsBlobSeekable(const Image *image)
+MagickPrivate MagickBooleanType IsBlobSeekable(const Image *image)
{
MagickBooleanType
seekable;
assert(image->signature == MagickSignature);
if (image->debug != MagickFalse)
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
- seekable=(image->blob->type == FileStream) ||
- (image->blob->type == BlobStream) ? MagickTrue : MagickFalse;
+ switch (image->blob->type)
+ {
+ case FileStream:
+ case BlobStream:
+ case ZipStream:
+ {
+ seekable=MagickTrue;
+ break;
+ }
+ default:
+ {
+ seekable=MagickFalse;
+ break;
+ }
+ }
return(seekable);
}
\f
% o image: the image.
%
*/
-MagickExport MagickBooleanType IsBlobTemporary(const Image *image)
+MagickPrivate MagickBooleanType IsBlobTemporary(const Image *image)
{
assert(image != (const Image *) NULL);
assert(image->signature == MagickSignature);
MagickExport unsigned char *MapBlob(int file,const MapMode mode,
const MagickOffsetType offset,const size_t length)
{
-#if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
+#if defined(MAGICKCORE_HAVE_MMAP)
int
flags,
protection;
{
protection=PROT_READ;
flags|=MAP_PRIVATE;
- map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
- (off_t) offset);
break;
}
case WriteMode:
{
protection=PROT_WRITE;
flags|=MAP_SHARED;
- map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
- (off_t) offset);
-#if defined(MAGICKCORE_HAVE_POSIX_MADVISE)
- (void) posix_madvise(map,length,POSIX_MADV_SEQUENTIAL |
- POSIX_MADV_WILLNEED);
-#endif
break;
}
case IOMode:
{
protection=PROT_READ | PROT_WRITE;
flags|=MAP_SHARED;
- map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
- (off_t) offset);
break;
}
}
+#if !defined(MAGICKCORE_HAVE_HUGEPAGES) || !defined(MAP_HUGETLB)
+ map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
+ (off_t) offset);
+#else
+ map=(unsigned char *) mmap((char *) NULL,length,protection,flags |
+ MAP_HUGETLB,file,(off_t) offset);
+ if (map == (unsigned char *) MAP_FAILED)
+ map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
+ (off_t) offset);
+#endif
if (map == (unsigned char *) MAP_FAILED)
return((unsigned char *) NULL);
return(map);
if ((LocaleCompare(filename,"-") == 0) ||
((*filename == '\0') && (image_info->file == (FILE *) NULL)))
{
- image->blob->file=(*type == 'r') ? stdin : stdout;
+ image->blob->file_info.file=(*type == 'r') ? stdin : stdout;
#if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
if (strchr(type,'b') != (char *) NULL)
- setmode(_fileno(image->blob->file),_O_BINARY);
+ setmode(_fileno(image->blob->file_info.file),_O_BINARY);
#endif
image->blob->type=StandardStream;
image->blob->exempt=MagickTrue;
*mode=(*type);
mode[1]='\0';
- image->blob->file=fdopen(StringToLong(filename+3),mode);
+ image->blob->file_info.file=fdopen(StringToLong(filename+3),mode);
#if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
if (strchr(type,'b') != (char *) NULL)
- setmode(_fileno(image->blob->file),_O_BINARY);
+ setmode(_fileno(image->blob->file_info.file),_O_BINARY);
#endif
image->blob->type=StandardStream;
image->blob->exempt=MagickTrue;
#endif
*mode=(*type);
mode[1]='\0';
- image->blob->file=(FILE *) popen(filename+1,mode);
- if (image->blob->file == (FILE *) NULL)
+ image->blob->file_info.file=(FILE *) popen_utf8(filename+1,mode);
+ if (image->blob->file_info.file == (FILE *) NULL)
{
ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
return(MagickFalse);
#endif
status=GetPathAttributes(filename,&image->blob->properties);
#if defined(S_ISFIFO)
- if ((status == MagickTrue) && S_ISFIFO(image->blob->properties.st_mode))
+ if ((status != MagickFalse) && S_ISFIFO(image->blob->properties.st_mode))
{
- image->blob->file=(FILE *) OpenMagickStream(filename,type);
- if (image->blob->file == (FILE *) NULL)
+ image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
+ if (image->blob->file_info.file == (FILE *) NULL)
{
ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
return(MagickFalse);
Form filename for multi-part images.
*/
(void) InterpretImageFilename(image_info,image,image->filename,(int)
- image->scene,filename);
+ image->scene,filename,exception);
if ((LocaleCompare(filename,image->filename) == 0) &&
((GetPreviousImageInList(image) != (Image *) NULL) ||
(GetNextImageInList(image) != (Image *) NULL)))
}
if (image_info->file != (FILE *) NULL)
{
- image->blob->file=image_info->file;
+ image->blob->file_info.file=image_info->file;
image->blob->type=FileStream;
image->blob->exempt=MagickTrue;
}
else
if (*type == 'r')
{
- image->blob->file=(FILE *) OpenMagickStream(filename,type);
- if (image->blob->file != (FILE *) NULL)
+ image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
+ if (image->blob->file_info.file != (FILE *) NULL)
{
size_t
count;
image->blob->type=FileStream;
#if defined(MAGICKCORE_HAVE_SETVBUF)
- (void) setvbuf(image->blob->file,(char *) NULL,(int) _IOFBF,16384);
+ (void) setvbuf(image->blob->file_info.file,(char *) NULL,(int)
+ _IOFBF,16384);
#endif
(void) ResetMagickMemory(magick,0,sizeof(magick));
- count=fread(magick,1,sizeof(magick),image->blob->file);
- (void) rewind(image->blob->file);
+ count=fread(magick,1,sizeof(magick),image->blob->file_info.file);
+ (void) fseek(image->blob->file_info.file,-((off_t) count),SEEK_CUR);
+ (void) fflush(image->blob->file_info.file);
(void) LogMagickEvent(BlobEvent,GetMagickModule(),
" read %.20g magic header bytes",(double) count);
#if defined(MAGICKCORE_ZLIB_DELEGATE)
if (((int) magick[0] == 0x1F) && ((int) magick[1] == 0x8B) &&
((int) magick[2] == 0x08))
{
- (void) fclose(image->blob->file);
- image->blob->file=(FILE *) gzopen(filename,type);
- if (image->blob->file != (FILE *) NULL)
+ (void) fclose(image->blob->file_info.file);
+ image->blob->file_info.gzfile=gzopen(filename,type);
+ if (image->blob->file_info.gzfile != (gzFile) NULL)
image->blob->type=ZipStream;
}
#endif
#if defined(MAGICKCORE_BZLIB_DELEGATE)
if (strncmp((char *) magick,"BZh",3) == 0)
{
- (void) fclose(image->blob->file);
- image->blob->file=(FILE *) BZ2_bzopen(filename,type);
- if (image->blob->file != (FILE *) NULL)
+ (void) fclose(image->blob->file_info.file);
+ image->blob->file_info.bzfile=BZ2_bzopen(filename,type);
+ if (image->blob->file_info.bzfile != (BZFILE *) NULL)
image->blob->type=BZipStream;
}
#endif
ExceptionInfo
*sans_exception;
- struct stat
- *properties;
+ size_t
+ length;
sans_exception=AcquireExceptionInfo();
magick_info=GetMagickInfo(image_info->magick,sans_exception);
sans_exception=DestroyExceptionInfo(sans_exception);
- properties=(&image->blob->properties);
+ length=(size_t) image->blob->properties.st_size;
if ((magick_info != (const MagickInfo *) NULL) &&
(GetMagickBlobSupport(magick_info) != MagickFalse) &&
- (properties->st_size <= MagickMaxBufferExtent))
+ (length <= MagickMaxBufferExtent) &&
+ (AcquireMagickResource(MapResource,length) != MagickFalse))
{
- size_t
- length;
-
void
*blob;
- length=(size_t) properties->st_size;
- blob=MapBlob(fileno(image->blob->file),ReadMode,0,length);
- if (blob != (void *) NULL)
+ blob=MapBlob(fileno(image->blob->file_info.file),ReadMode,0,
+ length);
+ if (blob == (void *) NULL)
+ RelinquishMagickResource(MapResource,length);
+ else
{
/*
Format supports blobs-- use memory-mapped I/O.
image->blob->exempt=MagickFalse;
else
{
- (void) fclose(image->blob->file);
- image->blob->file=(FILE *) NULL;
+ (void) fclose(image->blob->file_info.file);
+ image->blob->file_info.file=(FILE *) NULL;
}
AttachBlob(image->blob,blob,length);
image->blob->mapped=MagickTrue;
{
if (mode == WriteBinaryBlobMode)
type="wb";
- image->blob->file=(FILE *) gzopen(filename,type);
- if (image->blob->file != (FILE *) NULL)
+ image->blob->file_info.gzfile=gzopen(filename,type);
+ if (image->blob->file_info.gzfile != (gzFile) NULL)
image->blob->type=ZipStream;
}
else
#endif
#if defined(MAGICKCORE_BZLIB_DELEGATE)
- if (LocaleCompare(extension,".bz2") == 0)
+ if (LocaleCompare(extension,"bz2") == 0)
{
- image->blob->file=(FILE *) BZ2_bzopen(filename,type);
- if (image->blob->file != (FILE *) NULL)
+ image->blob->file_info.bzfile=BZ2_bzopen(filename,type);
+ if (image->blob->file_info.bzfile != (BZFILE *) NULL)
image->blob->type=BZipStream;
}
else
#endif
{
- image->blob->file=(FILE *) OpenMagickStream(filename,type);
- if (image->blob->file != (FILE *) NULL)
+ image->blob->file_info.file=(FILE *) fopen_utf8(filename,type);
+ if (image->blob->file_info.file != (FILE *) NULL)
{
image->blob->type=FileStream;
#if defined(MAGICKCORE_HAVE_SETVBUF)
- (void) setvbuf(image->blob->file,(char *) NULL,(int) _IOFBF,
- 16384);
+ (void) setvbuf(image->blob->file_info.file,(char *) NULL,(int)
+ _IOFBF,16384);
#endif
}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% ReadBlob() reads data from the blob or image file and returns it. It
-% returns the number of bytes read.
+% returns the number of bytes read. If length is zero, ReadBlob() returns
+% zero and has no other results. If length is greater than SSIZE_MAX, the
+% result is unspecified.
%
% The format of the ReadBlob method is:
%
{
case UndefinedStream:
break;
- case FileStream:
case StandardStream:
+ {
+ register ssize_t
+ i;
+
+ for (i=0; i < (ssize_t) length; i+=count)
+ {
+ count=read(fileno(image->blob->file_info.file),q+i,(size_t)
+ MagickMin(length-i,(MagickSizeType) SSIZE_MAX));
+ if (count <= 0)
+ {
+ count=0;
+ if (errno != EINTR)
+ break;
+ }
+ }
+ count=i;
+ break;
+ }
+ case FileStream:
case PipeStream:
{
switch (length)
{
default:
{
- count=(ssize_t) fread(q,1,length,image->blob->file);
+ count=(ssize_t) fread(q,1,length,image->blob->file_info.file);
break;
}
case 2:
{
- c=getc(image->blob->file);
+ c=getc(image->blob->file_info.file);
if (c == EOF)
break;
*q++=(unsigned char) c;
}
case 1:
{
- c=getc(image->blob->file);
+ c=getc(image->blob->file_info.file);
if (c == EOF)
break;
*q++=(unsigned char) c;
{
default:
{
- count=(ssize_t) gzread(image->blob->file,q,(unsigned int) length);
+ count=(ssize_t) gzread(image->blob->file_info.gzfile,q,
+ (unsigned int) length);
break;
}
case 2:
{
- c=gzgetc(image->blob->file);
+ c=gzgetc(image->blob->file_info.gzfile);
if (c == EOF)
break;
*q++=(unsigned char) c;
}
case 1:
{
- c=gzgetc(image->blob->file);
+ c=gzgetc(image->blob->file_info.gzfile);
if (c == EOF)
break;
*q++=(unsigned char) c;
case BZipStream:
{
#if defined(MAGICKCORE_BZLIB_DELEGATE)
- count=(ssize_t) BZ2_bzread((BZFILE *) image->blob->file,q,(int) length);
+ count=(ssize_t) BZ2_bzread(image->blob->file_info.bzfile,q,(int) length);
#endif
break;
}
break;
}
p=image->blob->data+image->blob->offset;
- count=(ssize_t) MagickMin(length,image->blob->length-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;
{
case UndefinedStream:
break;
+ case StandardStream:
+ return(-1);
case FileStream:
{
- if (fseek(image->blob->file,offset,whence) < 0)
+ if (fseek(image->blob->file_info.file,offset,whence) < 0)
return(-1);
image->blob->offset=TellBlob(image);
break;
}
- case StandardStream:
case PipeStream:
case ZipStream:
{
#if defined(MAGICKCORE_ZLIB_DELEGATE)
- if (gzseek(image->blob->file,(off_t) offset,whence) < 0)
+ if (gzseek(image->blob->file_info.gzfile,(off_t) offset,whence) < 0)
return(-1);
#endif
image->blob->offset=TellBlob(image);
{
image->blob->extent=(size_t) (image->blob->offset+
image->blob->quantum);
+ image->blob->quantum<<=1;
image->blob->data=(unsigned char *) ResizeQuantumMemory(
image->blob->data,image->blob->extent+1,
sizeof(*image->blob->data));
% o exempt: Set to true if this blob is exempt from being closed.
%
*/
-MagickExport void SetBlobExempt(Image *image,const MagickBooleanType exempt)
+MagickPrivate void SetBlobExempt(Image *image,const MagickBooleanType exempt)
{
assert(image != (const Image *) NULL);
assert(image->signature == MagickSignature);
% o extent: the blob maximum extent.
%
*/
-MagickExport MagickBooleanType SetBlobExtent(Image *image,
+MagickPrivate MagickBooleanType SetBlobExtent(Image *image,
const MagickSizeType extent)
{
assert(image != (Image *) NULL);
{
case UndefinedStream:
break;
+ case StandardStream:
+ return(MagickFalse);
case FileStream:
{
+ MagickOffsetType
+ offset;
+
+ ssize_t
+ count;
+
if (extent != (MagickSizeType) ((off_t) extent))
return(MagickFalse);
-#if !defined(MAGICKCORE_POSIX_FALLOCATE)
+ offset=SeekBlob(image,0,SEEK_END);
+ if (offset < 0)
return(MagickFalse);
-#else
- {
- int
- status;
-
- MagickOffsetType
- offset;
+ if ((MagickSizeType) offset >= extent)
+ break;
+ offset=SeekBlob(image,(MagickOffsetType) extent-1,SEEK_SET);
+ count=(ssize_t) fwrite((const unsigned char *) "",1,1,
+ image->blob->file_info.file);
+#if defined(MAGICKCORE_HAVE_POSIX_FALLOCATE)
+ if (image->blob->synchronize != MagickFalse)
+ {
+ int
+ status;
- offset=TellBlob(image);
- status=posix_fallocate(fileno(image->blob->file),(off_t) offset,
- (off_t) (extent-offset));
- if (status != 0)
- return(MagickFalse);
- }
+ status=posix_fallocate(fileno(image->blob->file_info.file),offset,
+ extent-offset);
+ if (status != 0)
+ return(MagickFalse);
+ }
#endif
+ offset=SeekBlob(image,offset,SEEK_SET);
+ if (count != 1)
+ return(MagickFalse);
break;
}
- case StandardStream:
case PipeStream:
case ZipStream:
return(MagickFalse);
return(MagickFalse);
case BlobStream:
{
+ if (extent != (MagickSizeType) ((size_t) extent))
+ return(MagickFalse);
if (image->blob->mapped != MagickFalse)
{
- if (image->blob->file == (FILE *) NULL)
- return(MagickFalse);
- (void) UnmapBlob(image->blob->data,image->blob->length);
-#if !defined(MAGICKCORE_POSIX_FALLOCATE)
- return(MagickFalse);
-#else
- {
- int
- status;
+ MagickOffsetType
+ offset;
- MagickOffsetType
- offset;
+ ssize_t
+ count;
- offset=TellBlob(image);
- status=posix_fallocate(fileno(image->blob->file),(off_t) offset,
- (off_t) (extent-offset));
- if (status != 0)
- return(MagickFalse);
- }
- image->blob->data=(unsigned char*) MapBlob(fileno(image->blob->file),
- WriteMode,0,(size_t) extent);
+ (void) UnmapBlob(image->blob->data,image->blob->length);
+ RelinquishMagickResource(MapResource,image->blob->length);
+ if (extent != (MagickSizeType) ((off_t) extent))
+ return(MagickFalse);
+ offset=SeekBlob(image,0,SEEK_END);
+ if (offset < 0)
+ return(MagickFalse);
+ if ((MagickSizeType) offset >= extent)
+ break;
+ offset=SeekBlob(image,(MagickOffsetType) extent-1,SEEK_SET);
+ count=(ssize_t) fwrite((const unsigned char *) "",1,1,
+ image->blob->file_info.file);
+#if defined(MAGICKCORE_HAVE_POSIX_FALLOCATE)
+ if (image->blob->synchronize != MagickFalse)
+ {
+ int
+ status;
+
+ status=posix_fallocate(fileno(image->blob->file_info.file),offset,
+ extent-offset);
+ if (status != 0)
+ return(MagickFalse);
+ }
+#endif
+ offset=SeekBlob(image,offset,SEEK_SET);
+ if (count != 1)
+ return(MagickFalse);
+ (void) AcquireMagickResource(MapResource,extent);
+ image->blob->data=(unsigned char*) MapBlob(fileno(
+ image->blob->file_info.file),WriteMode,0,(size_t) extent);
image->blob->extent=(size_t) extent;
image->blob->length=(size_t) extent;
(void) SyncBlob(image);
break;
-#endif
}
- if (extent != (MagickSizeType) ((size_t) extent))
- return(MagickFalse);
image->blob->extent=(size_t) extent;
image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data,
image->blob->extent+1,sizeof(*image->blob->data));
switch (image->blob->type)
{
case UndefinedStream:
+ case StandardStream:
break;
case FileStream:
- case StandardStream:
case PipeStream:
{
- status=fflush(image->blob->file);
+ status=fflush(image->blob->file_info.file);
break;
}
case ZipStream:
{
#if defined(MAGICKCORE_ZLIB_DELEGATE)
- status=gzflush(image->blob->file,Z_SYNC_FLUSH);
+ status=gzflush(image->blob->file_info.gzfile,Z_SYNC_FLUSH);
#endif
break;
}
case BZipStream:
{
#if defined(MAGICKCORE_BZLIB_DELEGATE)
- status=BZ2_bzflush((BZFILE *) image->blob->file);
+ status=BZ2_bzflush(image->blob->file_info.bzfile);
#endif
break;
}
case FifoStream:
break;
case BlobStream:
- {
-#if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
- if (image->blob->mapped != MagickFalse)
- status=msync(image->blob->data,image->blob->length,MS_SYNC);
-#endif
break;
- }
}
return(status);
}
switch (image->blob->type)
{
case UndefinedStream:
+ case StandardStream:
break;
case FileStream:
{
- offset=ftell(image->blob->file);
+ offset=ftell(image->blob->file_info.file);
break;
}
- case StandardStream:
case PipeStream:
break;
case ZipStream:
{
#if defined(MAGICKCORE_ZLIB_DELEGATE)
- offset=(MagickOffsetType) gztell(image->blob->file);
+ offset=(MagickOffsetType) gztell(image->blob->file_info.gzfile);
#endif
break;
}
*/
MagickExport MagickBooleanType UnmapBlob(void *map,const size_t length)
{
-#if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
+#if defined(MAGICKCORE_HAVE_MMAP)
int
status;
{
case UndefinedStream:
break;
- case FileStream:
case StandardStream:
+ {
+ count=write(fileno(image->blob->file_info.file),data,length);
+ break;
+ }
+ case FileStream:
case PipeStream:
{
switch (length)
default:
{
count=(ssize_t) fwrite((const char *) data,1,length,
- image->blob->file);
+ image->blob->file_info.file);
break;
}
case 2:
{
- c=putc((int) *p++,image->blob->file);
+ c=putc((int) *p++,image->blob->file_info.file);
if (c == EOF)
break;
count++;
}
case 1:
{
- c=putc((int) *p++,image->blob->file);
+ c=putc((int) *p++,image->blob->file_info.file);
if (c == EOF)
break;
count++;
{
default:
{
- count=(ssize_t) gzwrite(image->blob->file,(void *) data,
+ count=(ssize_t) gzwrite(image->blob->file_info.gzfile,(void *) data,
(unsigned int) length);
break;
}
case 2:
{
- c=gzputc(image->blob->file,(int) *p++);
+ c=gzputc(image->blob->file_info.gzfile,(int) *p++);
if (c == EOF)
break;
count++;
}
case 1:
{
- c=gzputc(image->blob->file,(int) *p++);
+ c=gzputc(image->blob->file_info.gzfile,(int) *p++);
if (c == EOF)
break;
count++;
case BZipStream:
{
#if defined(MAGICKCORE_BZLIB_DELEGATE)
- count=(ssize_t) BZ2_bzwrite((BZFILE *) image->blob->file,(void *) data,
+ count=(ssize_t) BZ2_bzwrite(image->blob->file_info.bzfile,(void *) data,
(int) length);
#endif
break;
{
if (image->blob->mapped != MagickFalse)
return(0);
- image->blob->quantum<<=1;
image->blob->extent+=length+image->blob->quantum;
+ image->blob->quantum<<=1;
image->blob->data=(unsigned char *) ResizeQuantumMemory(
image->blob->data,image->blob->extent+1,sizeof(*image->blob->data));
(void) SyncBlob(image);