2
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10
% BBBB LLLLL OOO BBBB %
13
% MagickCore Binary Large OBjectS Methods %
20
% Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization %
21
% dedicated to making software imaging solutions freely available. %
23
% You may not use this file except in compliance with the License. You may %
24
% obtain a copy of the License at %
26
% http://www.imagemagick.org/script/license.php %
28
% Unless required by applicable law or agreed to in writing, software %
29
% distributed under the License is distributed on an "AS IS" BASIS, %
30
% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31
% See the License for the specific language governing permissions and %
32
% limitations under the License. %
34
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
43
#include "magick/studio.h"
44
#include "magick/blob.h"
45
#include "magick/blob-private.h"
46
#include "magick/cache.h"
47
#include "magick/client.h"
48
#include "magick/constitute.h"
49
#include "magick/delegate.h"
50
#include "magick/exception.h"
51
#include "magick/exception-private.h"
52
#include "magick/image-private.h"
53
#include "magick/list.h"
54
#include "magick/log.h"
55
#include "magick/magick.h"
56
#include "magick/memory_.h"
57
#include "magick/policy.h"
58
#include "magick/resource_.h"
59
#include "magick/semaphore.h"
60
#include "magick/string_.h"
61
#include "magick/string-private.h"
62
#include "magick/token.h"
63
#include "magick/utility.h"
64
#if defined(MAGICKCORE_HAVE_MMAP_FILEIO) && !defined(MAGICKCORE_WINDOWS_SUPPORT)
65
# include <sys/mman.h>
67
#if defined(MAGICKCORE_ZLIB_DELEGATE)
70
#if defined(MAGICKCORE_BZLIB_DELEGATE)
77
#define MagickMaxBlobExtent 65541
78
#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
79
# define MAP_ANONYMOUS MAP_ANON
81
#if !defined(MAP_FAILED)
82
#define MAP_FAILED ((void *) -1)
89
#define _O_BINARY O_BINARY
147
Forward declarations.
153
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
157
+ A t t a c h B l o b %
161
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
163
% AttachBlob() attaches a blob to the BlobInfo structure.
165
% The format of the AttachBlob method is:
167
% void AttachBlob(BlobInfo *blob_info,const void *blob,const size_t length)
169
% A description of each parameter follows:
171
% o blob_info: Specifies a pointer to a BlobInfo structure.
173
% o blob: the address of a character stream in one of the image formats
174
% understood by ImageMagick.
176
% o length: This size_t integer reflects the length in bytes of the blob.
179
MagickExport void AttachBlob(BlobInfo *blob_info,const void *blob,
182
assert(blob_info != (BlobInfo *) NULL);
183
if (blob_info->debug != MagickFalse)
184
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
185
blob_info->length=length;
186
blob_info->extent=length;
187
blob_info->quantum=(size_t) MagickMaxBlobExtent;
189
blob_info->type=BlobStream;
190
blob_info->file=(FILE *) NULL;
191
blob_info->data=(unsigned char *) blob;
192
blob_info->mapped=MagickFalse;
196
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
200
+ B l o b T o F i l e %
204
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
206
% BlobToFile() writes a blob to a file. It returns MagickFalse if an error
207
% occurs otherwise MagickTrue.
209
% The format of the BlobToFile method is:
211
% MagickBooleanType BlobToFile(char *filename,const void *blob,
212
% const size_t length,ExceptionInfo *exception)
214
% A description of each parameter follows:
216
% o filename: Write the blob to this file.
218
% o blob: the address of a blob.
220
% o length: This length in bytes of the blob.
222
% o exception: return any errors or warnings in this structure.
226
static inline MagickSizeType MagickMin(const MagickSizeType x,
227
const MagickSizeType y)
234
MagickExport MagickBooleanType BlobToFile(char *filename,const void *blob,
235
const size_t length,ExceptionInfo *exception)
246
assert(filename != (const char *) NULL);
247
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
248
assert(blob != (const void *) NULL);
249
if (*filename == '\0')
250
file=AcquireUniqueFileResource(filename);
252
file=open(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
255
ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
258
for (i=0; i < length; i+=count)
260
count=(ssize_t) write(file,(const char *) blob+i,(size_t) MagickMin(length-
261
i,(MagickSizeType) SSIZE_MAX));
270
if ((file == -1) || (i < length))
272
ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
279
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
283
% B l o b T o I m a g e %
287
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
289
% BlobToImage() implements direct to memory image formats. It returns the
292
% The format of the BlobToImage method is:
294
% Image *BlobToImage(const ImageInfo *image_info,const void *blob,
295
% const size_t length,ExceptionInfo *exception)
297
% A description of each parameter follows:
299
% o image_info: the image info.
301
% o blob: the address of a character stream in one of the image formats
302
% understood by ImageMagick.
304
% o length: This size_t integer reflects the length in bytes of the blob.
306
% o exception: return any errors or warnings in this structure.
309
MagickExport Image *BlobToImage(const ImageInfo *image_info,const void *blob,
310
const size_t length,ExceptionInfo *exception)
325
assert(image_info != (ImageInfo *) NULL);
326
assert(image_info->signature == MagickSignature);
327
if (image_info->debug != MagickFalse)
328
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
329
image_info->filename);
330
assert(exception != (ExceptionInfo *) NULL);
331
if ((blob == (const void *) NULL) || (length == 0))
333
(void) ThrowMagickException(exception,GetMagickModule(),BlobError,
334
"ZeroLengthBlobNotPermitted","`%s'",image_info->filename);
335
return((Image *) NULL);
337
blob_info=CloneImageInfo(image_info);
338
blob_info->blob=(void *) blob;
339
blob_info->length=length;
340
if (*blob_info->magick == '\0')
341
(void) SetImageInfo(blob_info,0,exception);
342
magick_info=GetMagickInfo(blob_info->magick,exception);
343
if (magick_info == (const MagickInfo *) NULL)
345
blob_info=DestroyImageInfo(blob_info);
346
(void) ThrowMagickException(exception,GetMagickModule(),
347
MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
348
image_info->filename);
349
return((Image *) NULL);
351
if (GetMagickBlobSupport(magick_info) != MagickFalse)
354
Native blob support for this image format.
356
(void) CopyMagickString(blob_info->filename,image_info->filename,
358
(void) CopyMagickString(blob_info->magick,image_info->magick,
360
image=ReadImage(blob_info,exception);
361
if (image != (Image *) NULL)
362
(void) DetachBlob(image->blob);
363
blob_info=DestroyImageInfo(blob_info);
367
Write blob to a temporary file on disk.
369
blob_info->blob=(void *) NULL;
371
*blob_info->filename='\0';
372
status=BlobToFile(blob_info->filename,blob,length,exception);
373
if (status == MagickFalse)
375
(void) RelinquishUniqueFileResource(blob_info->filename);
376
blob_info=DestroyImageInfo(blob_info);
377
return((Image *) NULL);
379
clone_info=CloneImageInfo(blob_info);
380
(void) FormatMagickString(clone_info->filename,MaxTextExtent,"%s:%s",
381
blob_info->magick,blob_info->filename);
382
image=ReadImage(clone_info,exception);
383
clone_info=DestroyImageInfo(clone_info);
384
(void) RelinquishUniqueFileResource(blob_info->filename);
385
blob_info=DestroyImageInfo(blob_info);
390
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
394
+ C l o n e B l o b I n f o %
398
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
400
% CloneBlobInfo() makes a duplicate of the given blob info structure, or if
401
% blob info is NULL, a new one.
403
% The format of the CloneBlobInfo method is:
405
% BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
407
% A description of each parameter follows:
409
% o blob_info: the blob info.
412
MagickExport BlobInfo *CloneBlobInfo(const BlobInfo *blob_info)
417
clone_info=(BlobInfo *) AcquireMagickMemory(sizeof(*clone_info));
418
if (clone_info == (BlobInfo *) NULL)
419
ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
420
GetBlobInfo(clone_info);
421
if (blob_info == (BlobInfo *) NULL)
423
clone_info->length=blob_info->length;
424
clone_info->extent=blob_info->extent;
425
clone_info->synchronize=blob_info->synchronize;
426
clone_info->quantum=blob_info->quantum;
427
clone_info->mapped=blob_info->mapped;
428
clone_info->eof=blob_info->eof;
429
clone_info->offset=blob_info->offset;
430
clone_info->size=blob_info->size;
431
clone_info->exempt=blob_info->exempt;
432
clone_info->status=blob_info->status;
433
clone_info->temporary=blob_info->temporary;
434
clone_info->type=blob_info->type;
435
clone_info->file=blob_info->file;
436
clone_info->properties=blob_info->properties;
437
clone_info->stream=blob_info->stream;
438
clone_info->data=blob_info->data;
439
clone_info->debug=IsEventLogging();
440
clone_info->reference_count=1;
445
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
449
+ C l o s e B l o b %
453
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
455
% CloseBlob() closes a stream associated with the image.
457
% The format of the CloseBlob method is:
459
% MagickBooleanType CloseBlob(Image *image)
461
% A description of each parameter follows:
463
% o image: the image.
466
MagickExport MagickBooleanType CloseBlob(Image *image)
474
assert(image != (Image *) NULL);
475
assert(image->signature == MagickSignature);
476
if (image->debug != MagickFalse)
477
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
478
assert(image->blob != (BlobInfo *) NULL);
479
if (image->blob->type == UndefinedStream)
481
if (image->blob->synchronize != MagickFalse)
483
image->blob->size=GetBlobSize(image);
484
image->extent=image->blob->size;
485
image->blob->eof=MagickFalse;
486
if (image->blob->exempt != MagickFalse)
488
image->blob->type=UndefinedStream;
492
switch (image->blob->type)
494
case UndefinedStream:
500
status=ferror(image->blob->file);
505
#if defined(MAGICKCORE_ZLIB_DELEGATE)
506
(void) gzerror(image->blob->file,&status);
512
#if defined(MAGICKCORE_BZLIB_DELEGATE)
513
(void) BZ2_bzerror((BZFILE *) image->blob->file,&status);
521
image->blob->status=status < 0 ? MagickTrue : MagickFalse;
522
switch (image->blob->type)
524
case UndefinedStream:
529
if (image->blob->synchronize != MagickFalse)
531
status=fflush(image->blob->file);
532
status=fsync(fileno(image->blob->file));
534
status=fclose(image->blob->file);
539
#if defined(MAGICKCORE_HAVE_PCLOSE)
540
status=pclose(image->blob->file);
546
#if defined(MAGICKCORE_ZLIB_DELEGATE)
547
status=gzclose(image->blob->file);
553
#if defined(MAGICKCORE_BZLIB_DELEGATE)
554
BZ2_bzclose((BZFILE *) image->blob->file);
562
if (image->blob->file != (FILE *) NULL)
564
if (image->blob->synchronize != MagickFalse)
565
(void) fsync(fileno(image->blob->file));
566
status=fclose(image->blob->file);
571
(void) DetachBlob(image->blob);
572
image->blob->status=status < 0 ? MagickTrue : MagickFalse;
573
return(image->blob->status);
577
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
581
+ D e s t r o y B l o b %
585
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
587
% DestroyBlob() deallocates memory associated with a blob.
589
% The format of the DestroyBlob method is:
591
% void DestroyBlob(Image *image)
593
% A description of each parameter follows:
595
% o image: the image.
598
MagickExport void DestroyBlob(Image *image)
603
assert(image != (Image *) NULL);
604
assert(image->signature == MagickSignature);
605
if (image->debug != MagickFalse)
606
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
607
assert(image->blob != (BlobInfo *) NULL);
608
assert(image->blob->signature == MagickSignature);
610
LockSemaphoreInfo(image->blob->semaphore);
611
image->blob->reference_count--;
612
assert(image->blob->reference_count >= 0);
613
if (image->blob->reference_count == 0)
615
UnlockSemaphoreInfo(image->blob->semaphore);
616
if (destroy == MagickFalse)
618
(void) CloseBlob(image);
619
if (image->blob->mapped != MagickFalse)
620
(void) UnmapBlob(image->blob->data,image->blob->length);
621
if (image->blob->semaphore != (SemaphoreInfo *) NULL)
622
DestroySemaphoreInfo(&image->blob->semaphore);
623
image->blob->signature=(~MagickSignature);
624
image->blob=(BlobInfo *) RelinquishMagickMemory(image->blob);
628
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
632
+ D e t a c h B l o b %
636
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
638
% DetachBlob() detaches a blob from the BlobInfo structure.
640
% The format of the DetachBlob method is:
642
% unsigned char *DetachBlob(BlobInfo *blob_info)
644
% A description of each parameter follows:
646
% o blob_info: Specifies a pointer to a BlobInfo structure.
649
MagickExport unsigned char *DetachBlob(BlobInfo *blob_info)
654
assert(blob_info != (BlobInfo *) NULL);
655
if (blob_info->debug != MagickFalse)
656
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
657
if (blob_info->mapped != MagickFalse)
658
(void) UnmapBlob(blob_info->data,blob_info->length);
659
blob_info->mapped=MagickFalse;
662
blob_info->eof=MagickFalse;
663
blob_info->exempt=MagickFalse;
664
blob_info->type=UndefinedStream;
665
blob_info->file=(FILE *) NULL;
666
data=blob_info->data;
667
blob_info->data=(unsigned char *) NULL;
668
blob_info->stream=(StreamHandler) NULL;
673
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
677
+ D i s c a r d B l o b B y t e s %
681
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
683
% DiscardBlobBytes() discards bytes in a blob.
685
% The format of the DiscardBlobBytes method is:
687
% MagickBooleanType DiscardBlobBytes(Image *image,const size_t length)
689
% A description of each parameter follows.
691
% o image: the image.
693
% o length: the number of bytes to skip.
697
static inline const unsigned char *ReadBlobStream(Image *image,
698
const size_t length,unsigned char *data,ssize_t *count)
700
assert(count != (ssize_t *) NULL);
701
assert(image->blob != (BlobInfo *) NULL);
702
if (image->blob->type != BlobStream)
704
*count=ReadBlob(image,length,data);
707
if (image->blob->offset >= (MagickOffsetType) image->blob->length)
710
image->blob->eof=MagickTrue;
713
data=image->blob->data+image->blob->offset;
714
*count=(ssize_t) MagickMin(length,(MagickSizeType) (image->blob->length-
715
image->blob->offset));
716
image->blob->offset+=(*count);
717
if (*count != (ssize_t) length)
718
image->blob->eof=MagickTrue;
722
MagickExport MagickBooleanType DiscardBlobBytes(Image *image,
723
const MagickSizeType length)
725
register MagickOffsetType
737
assert(image != (Image *) NULL);
738
assert(image->signature == MagickSignature);
740
for (i=0; i < (MagickOffsetType) length; i+=count)
742
quantum=(size_t) MagickMin(length-i,sizeof(buffer));
743
(void) ReadBlobStream(image,quantum,buffer,&count);
751
return(i < (MagickOffsetType) length ? MagickFalse : MagickTrue);
755
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
759
+ D u p l i c a t e s B l o b %
763
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
765
% DuplicateBlob() duplicates a blob descriptor.
767
% The format of the DuplicateBlob method is:
769
% void DuplicateBlob(Image *image,const Image *duplicate)
771
% A description of each parameter follows:
773
% o image: the image.
775
% o duplicate: the duplicate image.
778
MagickExport void DuplicateBlob(Image *image,const Image *duplicate)
780
assert(image != (Image *) NULL);
781
assert(image->signature == MagickSignature);
782
if (image->debug != MagickFalse)
783
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
784
assert(duplicate != (Image *) NULL);
785
assert(duplicate->signature == MagickSignature);
787
image->blob=ReferenceBlob(duplicate->blob);
791
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
799
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
801
% EOFBlob() returns a non-zero value when EOF has been detected reading from
804
% The format of the EOFBlob method is:
806
% int EOFBlob(const Image *image)
808
% A description of each parameter follows:
810
% o image: the image.
813
MagickExport int EOFBlob(const Image *image)
815
assert(image != (Image *) NULL);
816
assert(image->signature == MagickSignature);
817
if (image->debug != MagickFalse)
818
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
819
assert(image->blob != (BlobInfo *) NULL);
820
assert(image->blob->type != UndefinedStream);
821
switch (image->blob->type)
823
case UndefinedStream:
829
image->blob->eof=feof(image->blob->file) != 0 ? MagickTrue : MagickFalse;
834
image->blob->eof=MagickFalse;
839
#if defined(MAGICKCORE_BZLIB_DELEGATE)
844
(void) BZ2_bzerror((BZFILE *) image->blob->file,&status);
845
image->blob->eof=status == BZ_UNEXPECTED_EOF ? MagickTrue : MagickFalse;
851
image->blob->eof=MagickFalse;
857
return((int) image->blob->eof);
861
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
865
+ F i l e T o B l o b %
869
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
871
% FileToBlob() returns the contents of a file as a buffer terminated with
872
% the '\0' character. The length of the buffer (not including the extra
873
% terminating '\0' character) is returned via the 'length' parameter. Free
874
% the buffer with RelinquishMagickMemory().
876
% The format of the FileToBlob method is:
878
% unsigned char *FileToBlob(const char *filename,const size_t extent,
879
% size_t *length,ExceptionInfo *exception)
881
% A description of each parameter follows:
883
% o blob: FileToBlob() returns the contents of a file as a blob. If
884
% an error occurs NULL is returned.
886
% o filename: the filename.
888
% o extent: The maximum length of the blob.
890
% o length: On return, this reflects the actual length of the blob.
892
% o exception: return any errors or warnings in this structure.
895
MagickExport unsigned char *FileToBlob(const char *filename,const size_t extent,
896
size_t *length,ExceptionInfo *exception)
916
assert(filename != (const char *) NULL);
917
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
918
assert(exception != (ExceptionInfo *) NULL);
921
if (LocaleCompare(filename,"-") != 0)
922
file=open(filename,O_RDONLY | O_BINARY);
925
ThrowFileException(exception,BlobError,"UnableToOpenFile",filename);
926
return((unsigned char *) NULL);
928
offset=(MagickOffsetType) lseek(file,0,SEEK_END);
930
if ((offset < 0) || (offset != (MagickOffsetType) ((ssize_t) offset)))
939
Stream is not seekable.
941
quantum=(size_t) MagickMaxBufferExtent;
942
if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
943
quantum=(size_t) MagickMin((MagickSizeType) file_info.st_size,
944
MagickMaxBufferExtent);
945
blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
946
for (i=0; blob != (unsigned char *) NULL; i+=count)
948
count=(ssize_t) read(file,blob+i,quantum);
955
if (~(1UL*i) < (quantum+1))
957
blob=(unsigned char *) RelinquishMagickMemory(blob);
960
blob=(unsigned char *) ResizeQuantumMemory(blob,i+quantum+1,
962
if ((size_t) (i+count) >= extent)
965
if (LocaleCompare(filename,"-") != 0)
967
if (blob == (unsigned char *) NULL)
969
(void) ThrowMagickException(exception,GetMagickModule(),
970
ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
971
return((unsigned char *) NULL);
975
blob=(unsigned char *) RelinquishMagickMemory(blob);
976
ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
977
return((unsigned char *) NULL);
979
*length=(size_t) MagickMin(i+count,extent);
983
*length=(size_t) MagickMin((MagickSizeType) offset,extent);
984
blob=(unsigned char *) NULL;
985
if (~(*length) >= MaxTextExtent)
986
blob=(unsigned char *) AcquireQuantumMemory(*length+MaxTextExtent,
988
if (blob == (unsigned char *) NULL)
991
(void) ThrowMagickException(exception,GetMagickModule(),
992
ResourceLimitError,"MemoryAllocationFailed","`%s'",filename);
993
return((unsigned char *) NULL);
995
map=MapBlob(file,ReadMode,0,*length);
996
if (map != (unsigned char *) NULL)
998
(void) memcpy(blob,map,*length);
999
(void) UnmapBlob(map,*length);
1003
(void) lseek(file,0,SEEK_SET);
1004
for (i=0; i < *length; i+=count)
1006
count=(ssize_t) read(file,blob+i,(size_t) MagickMin(*length-i,
1007
(MagickSizeType) SSIZE_MAX));
1018
blob=(unsigned char *) RelinquishMagickMemory(blob);
1019
ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1020
return((unsigned char *) NULL);
1024
if (LocaleCompare(filename,"-") != 0)
1028
blob=(unsigned char *) RelinquishMagickMemory(blob);
1029
ThrowFileException(exception,BlobError,"UnableToReadBlob",filename);
1035
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1039
% F i l e T o I m a g e %
1043
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1045
% FileToImage() write the contents of a file to an image.
1047
% The format of the FileToImage method is:
1049
% MagickBooleanType FileToImage(Image *,const char *filename)
1051
% A description of each parameter follows:
1053
% o image: the image.
1055
% o filename: the filename.
1059
static inline ssize_t WriteBlobStream(Image *image,const size_t length,
1060
const unsigned char *data)
1065
register unsigned char
1068
assert(image->blob != (BlobInfo *) NULL);
1069
if (image->blob->type != BlobStream)
1070
return(WriteBlob(image,length,data));
1071
assert(image->blob->type != UndefinedStream);
1072
assert(data != (void *) NULL);
1073
extent=(MagickSizeType) (image->blob->offset+(MagickOffsetType) length);
1074
if (extent >= image->blob->extent)
1076
image->blob->quantum<<=1;
1077
extent=image->blob->extent+image->blob->quantum+length;
1078
if (SetBlobExtent(image,extent) == MagickFalse)
1081
q=image->blob->data+image->blob->offset;
1082
(void) memcpy(q,data,length);
1083
image->blob->offset+=length;
1084
if (image->blob->offset >= (MagickOffsetType) image->blob->length)
1085
image->blob->length=(size_t) image->blob->offset;
1086
return((ssize_t) length);
1089
MagickExport MagickBooleanType FileToImage(Image *image,const char *filename)
1107
assert(image != (const Image *) NULL);
1108
assert(image->signature == MagickSignature);
1109
assert(filename != (const char *) NULL);
1110
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1111
file=open(filename,O_RDONLY | O_BINARY);
1114
ThrowFileException(&image->exception,BlobError,"UnableToOpenBlob",
1116
return(MagickFalse);
1118
quantum=(size_t) MagickMaxBufferExtent;
1119
if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1120
quantum=(size_t) MagickMin(file_info.st_size,MagickMaxBufferExtent);
1121
blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
1122
if (blob == (unsigned char *) NULL)
1124
ThrowFileException(&image->exception,ResourceLimitError,
1125
"MemoryAllocationFailed",filename);
1126
return(MagickFalse);
1130
count=(ssize_t) read(file,blob,quantum);
1137
length=(size_t) count;
1138
count=WriteBlobStream(image,length,blob);
1139
if (count != (ssize_t) length)
1141
ThrowFileException(&image->exception,BlobError,"UnableToWriteBlob",
1148
ThrowFileException(&image->exception,BlobError,"UnableToWriteBlob",
1150
blob=(unsigned char *) RelinquishMagickMemory(blob);
1155
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1159
+ G e t B l o b E r r o r %
1163
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1165
% GetBlobError() returns MagickTrue if the blob associated with the specified
1166
% image encountered an error.
1168
% The format of the GetBlobError method is:
1170
% MagickBooleanType GetBlobError(const Image *image)
1172
% A description of each parameter follows:
1174
% o image: the image.
1177
MagickExport MagickBooleanType GetBlobError(const Image *image)
1179
assert(image != (const Image *) NULL);
1180
assert(image->signature == MagickSignature);
1181
if (image->debug != MagickFalse)
1182
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1183
return(image->blob->status);
1187
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1191
+ G e t B l o b F i l e H a n d l e %
1195
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1197
% GetBlobFileHandle() returns the file handle associated with the image blob.
1199
% The format of the GetBlobFile method is:
1201
% FILE *GetBlobFileHandle(const Image *image)
1203
% A description of each parameter follows:
1205
% o image: the image.
1208
MagickExport FILE *GetBlobFileHandle(const Image *image)
1210
assert(image != (const Image *) NULL);
1211
assert(image->signature == MagickSignature);
1212
return(image->blob->file);
1216
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1220
+ G e t B l o b I n f o %
1224
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1226
% GetBlobInfo() initializes the BlobInfo structure.
1228
% The format of the GetBlobInfo method is:
1230
% void GetBlobInfo(BlobInfo *blob_info)
1232
% A description of each parameter follows:
1234
% o blob_info: Specifies a pointer to a BlobInfo structure.
1237
MagickExport void GetBlobInfo(BlobInfo *blob_info)
1239
assert(blob_info != (BlobInfo *) NULL);
1240
(void) ResetMagickMemory(blob_info,0,sizeof(*blob_info));
1241
blob_info->type=UndefinedStream;
1242
blob_info->quantum=(size_t) MagickMaxBlobExtent;
1243
blob_info->properties.st_mtime=time((time_t *) NULL);
1244
blob_info->properties.st_ctime=time((time_t *) NULL);
1245
blob_info->debug=IsEventLogging();
1246
blob_info->reference_count=1;
1247
blob_info->semaphore=AllocateSemaphoreInfo();
1248
blob_info->signature=MagickSignature;
1252
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1256
% G e t B l o b P r o p e r t i e s %
1260
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1262
% GetBlobProperties() returns information about an image blob.
1264
% The format of the GetBlobProperties method is:
1266
% const struct stat *GetBlobProperties(const Image *image)
1268
% A description of each parameter follows:
1270
% o image: the image.
1273
MagickExport const struct stat *GetBlobProperties(const Image *image)
1275
assert(image != (Image *) NULL);
1276
assert(image->signature == MagickSignature);
1277
if (image->debug != MagickFalse)
1278
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1279
return(&image->blob->properties);
1283
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1287
+ G e t B l o b S i z e %
1291
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1293
% GetBlobSize() returns the current length of the image file or blob; zero is
1294
% returned if the size cannot be determined.
1296
% The format of the GetBlobSize method is:
1298
% MagickSizeType GetBlobSize(const Image *image)
1300
% A description of each parameter follows:
1302
% o image: the image.
1305
MagickExport MagickSizeType GetBlobSize(const Image *image)
1310
assert(image != (Image *) NULL);
1311
assert(image->signature == MagickSignature);
1312
if (image->debug != MagickFalse)
1313
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1314
assert(image->blob != (BlobInfo *) NULL);
1316
switch (image->blob->type)
1318
case UndefinedStream:
1320
extent=image->blob->size;
1325
if (fstat(fileno(image->blob->file),&image->blob->properties) == 0)
1326
extent=(MagickSizeType) image->blob->properties.st_size;
1329
case StandardStream:
1332
extent=image->blob->size;
1341
status=GetPathAttributes(image->filename,&image->blob->properties);
1342
if (status != MagickFalse)
1343
extent=(MagickSizeType) image->blob->properties.st_size;
1350
extent=(MagickSizeType) image->blob->length;
1358
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1362
+ G e t B l o b S t r e a m D a t a %
1366
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1368
% GetBlobStreamData() returns the stream data for the image.
1370
% The format of the GetBlobStreamData method is:
1372
% unsigned char *GetBlobStreamData(const Image *image)
1374
% A description of each parameter follows:
1376
% o image: the image.
1379
MagickExport unsigned char *GetBlobStreamData(const Image *image)
1381
assert(image != (const Image *) NULL);
1382
assert(image->signature == MagickSignature);
1383
return(image->blob->data);
1387
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1391
+ G e t B l o b S t r e a m H a n d l e r %
1395
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1397
% GetBlobStreamHandler() returns the stream handler for the image.
1399
% The format of the GetBlobStreamHandler method is:
1401
% StreamHandler GetBlobStreamHandler(const Image *image)
1403
% A description of each parameter follows:
1405
% o image: the image.
1408
MagickExport StreamHandler GetBlobStreamHandler(const Image *image)
1410
assert(image != (const Image *) NULL);
1411
assert(image->signature == MagickSignature);
1412
if (image->debug != MagickFalse)
1413
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1414
return(image->blob->stream);
1418
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1422
% I m a g e T o B l o b %
1426
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1428
% ImageToBlob() implements direct to memory image formats. It returns the
1429
% image as a formatted blob and its length. The magick member of the Image
1430
% structure determines the format of the returned blob (GIF, JPEG, PNG,
1431
% etc.). This method is the equivalent of WriteImage(), but writes the
1432
% formatted "file" to a memory buffer rather than to an actual file.
1434
% The format of the ImageToBlob method is:
1436
% unsigned char *ImageToBlob(const ImageInfo *image_info,Image *image,
1437
% size_t *length,ExceptionInfo *exception)
1439
% A description of each parameter follows:
1441
% o image_info: the image info.
1443
% o image: the image.
1445
% o length: This pointer to a size_t integer sets the initial length of the
1446
% blob. On return, it reflects the actual length of the blob.
1448
% o exception: return any errors or warnings in this structure.
1451
MagickExport unsigned char *ImageToBlob(const ImageInfo *image_info,
1452
Image *image,size_t *length,ExceptionInfo *exception)
1466
assert(image_info != (const ImageInfo *) NULL);
1467
assert(image_info->signature == MagickSignature);
1468
if (image_info->debug != MagickFalse)
1469
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1470
image_info->filename);
1471
assert(image != (Image *) NULL);
1472
assert(image->signature == MagickSignature);
1473
assert(exception != (ExceptionInfo *) NULL);
1475
blob=(unsigned char *) NULL;
1476
blob_info=CloneImageInfo(image_info);
1477
blob_info->adjoin=MagickFalse;
1478
(void) SetImageInfo(blob_info,1,exception);
1479
if (*blob_info->magick != '\0')
1480
(void) CopyMagickString(image->magick,blob_info->magick,MaxTextExtent);
1481
magick_info=GetMagickInfo(image->magick,exception);
1482
if (magick_info == (const MagickInfo *) NULL)
1484
(void) ThrowMagickException(exception,GetMagickModule(),
1485
MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1489
(void) CopyMagickString(blob_info->magick,image->magick,MaxTextExtent);
1490
if (GetMagickBlobSupport(magick_info) != MagickFalse)
1493
Native blob support for this image format.
1495
blob_info->length=0;
1496
blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1497
sizeof(unsigned char));
1498
if (blob_info->blob == (void *) NULL)
1499
(void) ThrowMagickException(exception,GetMagickModule(),
1500
ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
1503
(void) CloseBlob(image);
1504
image->blob->exempt=MagickTrue;
1505
*image->filename='\0';
1506
status=WriteImage(blob_info,image);
1507
if ((status == MagickFalse) || (image->blob->length == 0))
1508
InheritException(exception,&image->exception);
1511
*length=image->blob->length;
1512
blob=DetachBlob(image->blob);
1513
blob=(unsigned char *) ResizeQuantumMemory(blob,*length,
1521
unique[MaxTextExtent];
1527
Write file to disk in blob image format.
1529
file=AcquireUniqueFileResource(unique);
1532
ThrowFileException(exception,BlobError,"UnableToWriteBlob",
1533
image_info->filename);
1537
blob_info->file=fdopen(file,"wb");
1538
if (blob_info->file != (FILE *) NULL)
1540
(void) FormatMagickString(image->filename,MaxTextExtent,"%s:%s",
1541
image->magick,unique);
1542
status=WriteImage(blob_info,image);
1543
(void) fclose(blob_info->file);
1544
if (status == MagickFalse)
1545
InheritException(exception,&image->exception);
1547
blob=FileToBlob(image->filename,~0UL,length,exception);
1549
(void) RelinquishUniqueFileResource(unique);
1552
blob_info=DestroyImageInfo(blob_info);
1557
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1561
% I m a g e T o F i l e %
1565
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1567
% ImageToFile() writes an image to a file. It returns MagickFalse if an error
1568
% occurs otherwise MagickTrue.
1570
% The format of the ImageToFile method is:
1572
% MagickBooleanType ImageToFile(Image *image,char *filename,
1573
% ExceptionInfo *exception)
1575
% A description of each parameter follows:
1577
% o image: the image.
1579
% o filename: Write the image to this file.
1581
% o exception: return any errors or warnings in this structure.
1584
MagickExport MagickBooleanType ImageToFile(Image *image,char *filename,
1585
ExceptionInfo *exception)
1590
register const unsigned char
1609
assert(image != (Image *) NULL);
1610
assert(image->signature == MagickSignature);
1611
assert(image->blob != (BlobInfo *) NULL);
1612
assert(image->blob->type != UndefinedStream);
1613
if (image->debug != MagickFalse)
1614
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1615
assert(filename != (const char *) NULL);
1616
if (*filename == '\0')
1617
file=AcquireUniqueFileResource(filename);
1619
if (LocaleCompare(filename,"-") == 0)
1620
file=fileno(stdout);
1622
file=open(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE);
1625
ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1626
return(MagickFalse);
1628
quantum=(size_t) MagickMaxBufferExtent;
1629
if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1630
quantum=(size_t) MagickMin((MagickSizeType) file_info.st_size,
1631
MagickMaxBufferExtent);
1632
buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1633
if (buffer == (unsigned char *) NULL)
1636
(void) ThrowMagickException(exception,GetMagickModule(),
1637
ResourceLimitError,"MemoryAllocationError","`%s'",filename);
1638
return(MagickFalse);
1641
p=ReadBlobStream(image,quantum,buffer,&count);
1642
for (i=0; count > 0; p=ReadBlobStream(image,quantum,buffer,&count))
1644
length=(size_t) count;
1645
for (i=0; i < length; i+=count)
1647
count=write(file,p+i,(size_t) (length-i));
1658
if (LocaleCompare(filename,"-") != 0)
1660
buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1661
if ((file == -1) || (i < length))
1663
ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename);
1664
return(MagickFalse);
1670
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1674
% I m a g e s T o B l o b %
1678
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1680
% ImagesToBlob() implements direct to memory image formats. It returns the
1681
% image sequence as a blob and its length. The magick member of the ImageInfo
1682
% structure determines the format of the returned blob (GIF, JPEG, PNG, etc.)
1684
% Note, some image formats do not permit multiple images to the same image
1685
% stream (e.g. JPEG). in this instance, just the first image of the
1686
% sequence is returned as a blob.
1688
% The format of the ImagesToBlob method is:
1690
% unsigned char *ImagesToBlob(const ImageInfo *image_info,Image *images,
1691
% size_t *length,ExceptionInfo *exception)
1693
% A description of each parameter follows:
1695
% o image_info: the image info.
1697
% o images: the image list.
1699
% o length: This pointer to a size_t integer sets the initial length of the
1700
% blob. On return, it reflects the actual length of the blob.
1702
% o exception: return any errors or warnings in this structure.
1705
MagickExport unsigned char *ImagesToBlob(const ImageInfo *image_info,
1706
Image *images,size_t *length,ExceptionInfo *exception)
1720
assert(image_info != (const ImageInfo *) NULL);
1721
assert(image_info->signature == MagickSignature);
1722
if (image_info->debug != MagickFalse)
1723
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
1724
image_info->filename);
1725
assert(images != (Image *) NULL);
1726
assert(images->signature == MagickSignature);
1727
assert(exception != (ExceptionInfo *) NULL);
1729
blob=(unsigned char *) NULL;
1730
blob_info=CloneImageInfo(image_info);
1731
(void) SetImageInfo(blob_info,(unsigned int) GetImageListLength(images),
1733
if (*blob_info->magick != '\0')
1734
(void) CopyMagickString(images->magick,blob_info->magick,MaxTextExtent);
1735
if (blob_info->adjoin == MagickFalse)
1737
blob_info=DestroyImageInfo(blob_info);
1738
return(ImageToBlob(image_info,images,length,exception));
1740
magick_info=GetMagickInfo(images->magick,exception);
1741
if (magick_info == (const MagickInfo *) NULL)
1743
(void) ThrowMagickException(exception,GetMagickModule(),
1744
MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'",
1748
(void) CopyMagickString(blob_info->magick,images->magick,MaxTextExtent);
1749
if (GetMagickBlobSupport(magick_info) != MagickFalse)
1752
Native blob support for this images format.
1754
blob_info->length=0;
1755
blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent,
1756
sizeof(unsigned char));
1757
if (blob_info->blob == (void *) NULL)
1758
(void) ThrowMagickException(exception,GetMagickModule(),
1759
ResourceLimitError,"MemoryAllocationFailed","`%s'",images->filename);
1762
images->blob->exempt=MagickTrue;
1763
*images->filename='\0';
1764
status=WriteImages(blob_info,images,images->filename,exception);
1765
if ((status == MagickFalse) || (images->blob->length == 0))
1766
InheritException(exception,&images->exception);
1769
*length=images->blob->length;
1770
blob=DetachBlob(images->blob);
1771
blob=(unsigned char *) ResizeQuantumMemory(blob,*length,
1779
filename[MaxTextExtent],
1780
unique[MaxTextExtent];
1786
Write file to disk in blob images format.
1788
file=AcquireUniqueFileResource(unique);
1791
ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",
1792
image_info->filename);
1796
blob_info->file=fdopen(file,"wb");
1797
if (blob_info->file != (FILE *) NULL)
1799
(void) FormatMagickString(filename,MaxTextExtent,"%s:%s",
1800
images->magick,unique);
1801
status=WriteImages(blob_info,images,filename,exception);
1802
(void) fclose(blob_info->file);
1803
if (status == MagickFalse)
1804
InheritException(exception,&images->exception);
1806
blob=FileToBlob(images->filename,~0UL,length,exception);
1808
(void) RelinquishUniqueFileResource(unique);
1811
blob_info=DestroyImageInfo(blob_info);
1815
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1819
% I n j e c t I m a g e B l o b %
1823
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1825
% InjectImageBlob() injects the image with a copy of itself in the specified
1826
% format (e.g. inject JPEG into a PDF image).
1828
% The format of the InjectImageBlob method is:
1830
% MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1831
% Image *image,Image *inject_image,const char *format,
1832
% ExceptionInfo *exception)
1834
% A description of each parameter follows:
1836
% o image_info: the image info..
1838
% o image: the image.
1840
% o inject_image: inject into the image stream.
1842
% o format: the image format.
1844
% o exception: return any errors or warnings in this structure.
1847
MagickExport MagickBooleanType InjectImageBlob(const ImageInfo *image_info,
1848
Image *image,Image *inject_image,const char *format,ExceptionInfo *exception)
1851
filename[MaxTextExtent];
1884
Write inject image to a temporary file.
1886
assert(image_info != (ImageInfo *) NULL);
1887
assert(image_info->signature == MagickSignature);
1888
assert(image != (Image *) NULL);
1889
assert(image->signature == MagickSignature);
1890
if (image->debug != MagickFalse)
1891
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1892
assert(inject_image != (Image *) NULL);
1893
assert(inject_image->signature == MagickSignature);
1894
assert(exception != (ExceptionInfo *) NULL);
1895
unique_file=(FILE *) NULL;
1896
file=AcquireUniqueFileResource(filename);
1898
unique_file=fdopen(file,"wb");
1899
if ((file == -1) || (unique_file == (FILE *) NULL))
1901
(void) CopyMagickString(image->filename,filename,MaxTextExtent);
1902
ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
1904
return(MagickFalse);
1906
byte_image=CloneImage(inject_image,0,0,MagickFalse,exception);
1907
if (byte_image == (Image *) NULL)
1909
(void) fclose(unique_file);
1910
(void) RelinquishUniqueFileResource(filename);
1911
return(MagickFalse);
1913
(void) FormatMagickString(byte_image->filename,MaxTextExtent,"%s:%s",format,
1915
DestroyBlob(byte_image);
1916
byte_image->blob=CloneBlobInfo((BlobInfo *) NULL);
1917
write_info=CloneImageInfo(image_info);
1918
SetImageInfoFile(write_info,unique_file);
1919
status=WriteImage(write_info,byte_image);
1920
write_info=DestroyImageInfo(write_info);
1921
byte_image=DestroyImage(byte_image);
1922
(void) fclose(unique_file);
1923
if (status == MagickFalse)
1925
(void) RelinquishUniqueFileResource(filename);
1926
return(MagickFalse);
1929
Inject into image stream.
1931
file=open(filename,O_RDONLY | O_BINARY);
1934
(void) RelinquishUniqueFileResource(filename);
1935
ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
1936
image_info->filename);
1937
return(MagickFalse);
1939
quantum=(size_t) MagickMaxBufferExtent;
1940
if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0))
1941
quantum=(size_t) MagickMin(file_info.st_size,MagickMaxBufferExtent);
1942
buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer));
1943
if (buffer == (unsigned char *) NULL)
1945
(void) RelinquishUniqueFileResource(filename);
1946
ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
1949
for (i=0; ; i+=count)
1951
count=(ssize_t) read(file,buffer,quantum);
1958
status=WriteBlobStream(image,(size_t) count,buffer) == count ? MagickTrue :
1963
ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",filename);
1964
(void) RelinquishUniqueFileResource(filename);
1965
buffer=(unsigned char *) RelinquishMagickMemory(buffer);
1970
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1974
+ I s B l o b E x e m p t %
1978
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1980
% IsBlobExempt() returns true if the blob is exempt.
1982
% The format of the IsBlobExempt method is:
1984
% MagickBooleanType IsBlobExempt(const Image *image)
1986
% A description of each parameter follows:
1988
% o image: the image.
1991
MagickExport MagickBooleanType IsBlobExempt(const Image *image)
1993
assert(image != (const Image *) NULL);
1994
assert(image->signature == MagickSignature);
1995
if (image->debug != MagickFalse)
1996
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1997
return(image->blob->exempt);
2001
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2005
+ I s B l o b S e e k a b l e %
2009
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2011
% IsBlobSeekable() returns true if the blob is seekable.
2013
% The format of the IsBlobSeekable method is:
2015
% MagickBooleanType IsBlobSeekable(const Image *image)
2017
% A description of each parameter follows:
2019
% o image: the image.
2022
MagickExport MagickBooleanType IsBlobSeekable(const Image *image)
2027
assert(image != (const Image *) NULL);
2028
assert(image->signature == MagickSignature);
2029
if (image->debug != MagickFalse)
2030
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2031
seekable=(image->blob->type == FileStream) ||
2032
(image->blob->type == BlobStream) ? MagickTrue : MagickFalse;
2037
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2041
+ I s B l o b T e m p o r a r y %
2045
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2047
% IsBlobTemporary() returns true if the blob is temporary.
2049
% The format of the IsBlobTemporary method is:
2051
% MagickBooleanType IsBlobTemporary(const Image *image)
2053
% A description of each parameter follows:
2055
% o image: the image.
2058
MagickExport MagickBooleanType IsBlobTemporary(const Image *image)
2060
assert(image != (const Image *) NULL);
2061
assert(image->signature == MagickSignature);
2062
if (image->debug != MagickFalse)
2063
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
2064
return(image->blob->temporary);
2068
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2076
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2078
% MapBlob() creates a mapping from a file to a binary large object.
2080
% The format of the MapBlob method is:
2082
% unsigned char *MapBlob(int file,const MapMode mode,
2083
% const MagickOffsetType offset,const size_t length)
2085
% A description of each parameter follows:
2087
% o file: map this file descriptor.
2089
% o mode: ReadMode, WriteMode, or IOMode.
2091
% o offset: starting at this offset within the file.
2093
% o length: the length of the mapping is returned in this pointer.
2096
MagickExport unsigned char *MapBlob(int file,const MapMode mode,
2097
const MagickOffsetType offset,const size_t length)
2099
#if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
2112
#if defined(MAP_ANONYMOUS)
2113
flags|=MAP_ANONYMOUS;
2115
return((unsigned char *) NULL);
2122
protection=PROT_READ;
2124
map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2130
protection=PROT_WRITE;
2132
map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2134
#if defined(MAGICKCORE_HAVE_POSIX_MADVISE)
2135
(void) posix_madvise(map,length,POSIX_MADV_SEQUENTIAL |
2136
POSIX_MADV_WILLNEED);
2142
protection=PROT_READ | PROT_WRITE;
2144
map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
2149
if (map == (unsigned char *) MAP_FAILED)
2150
return((unsigned char *) NULL);
2157
return((unsigned char *) NULL);
2162
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2166
+ M S B O r d e r L o n g %
2170
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2172
% MSBOrderLong() converts a least-significant byte first buffer of integers to
2173
% most-significant byte first.
2175
% The format of the MSBOrderLong method is:
2177
% void MSBOrderLong(unsigned char *buffer,const size_t length)
2179
% A description of each parameter follows.
2181
% o buffer: Specifies a pointer to a buffer of integers.
2183
% o length: Specifies the length of the buffer.
2186
MagickExport void MSBOrderLong(unsigned char *buffer,const size_t length)
2191
register unsigned char
2195
assert(buffer != (unsigned char *) NULL);
2202
*buffer++=(unsigned char) c;
2206
*buffer++=(unsigned char) c;
2212
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2216
+ M S B O r d e r S h o r t %
2220
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2222
% MSBOrderShort() converts a least-significant byte first buffer of integers
2223
% to most-significant byte first.
2225
% The format of the MSBOrderShort method is:
2227
% void MSBOrderShort(unsigned char *p,const size_t length)
2229
% A description of each parameter follows.
2231
% o p: Specifies a pointer to a buffer of integers.
2233
% o length: Specifies the length of the buffer.
2236
MagickExport void MSBOrderShort(unsigned char *p,const size_t length)
2241
register unsigned char
2244
assert(p != (unsigned char *) NULL);
2251
*p++=(unsigned char) c;
2256
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2264
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2266
% OpenBlob() opens a file associated with the image. A file name of '-' sets
2267
% the file to stdin for type 'r' and stdout for type 'w'. If the filename
2268
% suffix is '.gz' or '.Z', the image is decompressed for type 'r' and
2269
% compressed for type 'w'. If the filename prefix is '|', it is piped to or
2270
% from a system command.
2272
% The format of the OpenBlob method is:
2274
% MagickBooleanType OpenBlob(const ImageInfo *image_info,Image *image,
2275
% const BlobMode mode,ExceptionInfo *exception)
2277
% A description of each parameter follows:
2279
% o image_info: the image info.
2281
% o image: the image.
2283
% o mode: the mode for opening the file.
2286
MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info,
2287
Image *image,const BlobMode mode,ExceptionInfo *exception)
2290
extension[MaxTextExtent],
2291
filename[MaxTextExtent];
2302
assert(image_info != (ImageInfo *) NULL);
2303
assert(image_info->signature == MagickSignature);
2304
if (image_info->debug != MagickFalse)
2305
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2306
image_info->filename);
2307
assert(image != (Image *) NULL);
2308
assert(image->signature == MagickSignature);
2309
if (image_info->blob != (void *) NULL)
2311
if (image_info->stream != (StreamHandler) NULL)
2312
image->blob->stream=(StreamHandler) image_info->stream;
2313
AttachBlob(image->blob,image_info->blob,image_info->length);
2316
(void) DetachBlob(image->blob);
2319
default: type="r"; break;
2320
case ReadBlobMode: type="r"; break;
2321
case ReadBinaryBlobMode: type="rb"; break;
2322
case WriteBlobMode: type="w"; break;
2323
case WriteBinaryBlobMode: type="w+b"; break;
2324
case AppendBlobMode: type="a"; break;
2325
case AppendBinaryBlobMode: type="a+b"; break;
2328
image->blob->synchronize=image_info->synchronize;
2329
if (image_info->stream != (StreamHandler) NULL)
2331
image->blob->stream=(StreamHandler) image_info->stream;
2334
image->blob->type=FifoStream;
2342
(void) CopyMagickString(filename,image->filename,MaxTextExtent);
2343
rights=ReadPolicyRights;
2345
rights=WritePolicyRights;
2346
if (IsRightsAuthorized(PathPolicyDomain,rights,filename) == MagickFalse)
2349
(void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
2350
"NotAuthorized","`%s'",filename);
2351
return(MagickFalse);
2353
if ((LocaleCompare(filename,"-") == 0) ||
2354
((*filename == '\0') && (image_info->file == (FILE *) NULL)))
2356
image->blob->file=(*type == 'r') ? stdin : stdout;
2357
#if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2358
if (strchr(type,'b') != (char *) NULL)
2359
setmode(_fileno(image->blob->file),_O_BINARY);
2361
image->blob->type=StandardStream;
2362
image->blob->exempt=MagickTrue;
2365
if (LocaleNCompare(filename,"fd:",3) == 0)
2368
mode[MaxTextExtent];
2372
image->blob->file=fdopen(StringToLong(filename+3),mode);
2373
#if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__)
2374
if (strchr(type,'b') != (char *) NULL)
2375
setmode(_fileno(image->blob->file),_O_BINARY);
2377
image->blob->type=StandardStream;
2378
image->blob->exempt=MagickTrue;
2381
#if defined(MAGICKCORE_HAVE_POPEN)
2382
if (*filename == '|')
2385
mode[MaxTextExtent];
2388
Pipe image to or from a system command.
2390
#if defined(SIGPIPE)
2392
(void) signal(SIGPIPE,SIG_IGN);
2396
image->blob->file=(FILE *) popen(filename+1,mode);
2397
if (image->blob->file == (FILE *) NULL)
2399
ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2400
return(MagickFalse);
2402
image->blob->type=PipeStream;
2403
image->blob->exempt=MagickTrue;
2407
status=GetPathAttributes(filename,&image->blob->properties);
2408
#if defined(S_ISFIFO)
2409
if ((status == MagickTrue) && S_ISFIFO(image->blob->properties.st_mode))
2411
image->blob->file=(FILE *) OpenMagickStream(filename,type);
2412
if (image->blob->file == (FILE *) NULL)
2414
ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2415
return(MagickFalse);
2417
image->blob->type=FileStream;
2418
image->blob->exempt=MagickTrue;
2422
GetPathComponent(image->filename,ExtensionPath,extension);
2425
(void) CopyMagickString(filename,image->filename,MaxTextExtent);
2426
if ((image_info->adjoin == MagickFalse) ||
2427
(strchr(filename,'%') != (char *) NULL))
2430
Form filename for multi-part images.
2432
(void) InterpretImageFilename(image_info,image,image->filename,(int)
2433
image->scene,filename);
2434
if ((LocaleCompare(filename,image->filename) == 0) &&
2435
((GetPreviousImageInList(image) != (Image *) NULL) ||
2436
(GetNextImageInList(image) != (Image *) NULL)))
2439
path[MaxTextExtent];
2441
GetPathComponent(image->filename,RootPath,path);
2442
if (*extension == '\0')
2443
(void) FormatMagickString(filename,MaxTextExtent,"%s-%.20g",
2444
path,(double) image->scene);
2446
(void) FormatMagickString(filename,MaxTextExtent,"%s-%.20g.%s",
2447
path,(double) image->scene,extension);
2449
(void) CopyMagickString(image->filename,filename,MaxTextExtent);
2450
#if defined(macintosh)
2451
SetApplicationType(filename,image_info->magick,'8BIM');
2455
if (image_info->file != (FILE *) NULL)
2457
image->blob->file=image_info->file;
2458
image->blob->type=FileStream;
2459
image->blob->exempt=MagickTrue;
2464
image->blob->file=(FILE *) OpenMagickStream(filename,type);
2465
if (image->blob->file != (FILE *) NULL)
2473
image->blob->type=FileStream;
2474
#if defined(MAGICKCORE_HAVE_SETVBUF)
2475
(void) setvbuf(image->blob->file,(char *) NULL,(int) _IOFBF,16384);
2477
(void) ResetMagickMemory(magick,0,sizeof(magick));
2478
count=fread(magick,1,sizeof(magick),image->blob->file);
2479
(void) rewind(image->blob->file);
2480
(void) LogMagickEvent(BlobEvent,GetMagickModule(),
2481
" read %.20g magic header bytes",(double) count);
2482
#if defined(MAGICKCORE_ZLIB_DELEGATE)
2483
if (((int) magick[0] == 0x1F) && ((int) magick[1] == 0x8B) &&
2484
((int) magick[2] == 0x08))
2486
(void) fclose(image->blob->file);
2487
image->blob->file=(FILE *) gzopen(filename,type);
2488
if (image->blob->file != (FILE *) NULL)
2489
image->blob->type=ZipStream;
2492
#if defined(MAGICKCORE_BZLIB_DELEGATE)
2493
if (strncmp((char *) magick,"BZh",3) == 0)
2495
(void) fclose(image->blob->file);
2496
image->blob->file=(FILE *) BZ2_bzopen(filename,type);
2497
if (image->blob->file != (FILE *) NULL)
2498
image->blob->type=BZipStream;
2501
if (image->blob->type == FileStream)
2512
sans_exception=AcquireExceptionInfo();
2513
magick_info=GetMagickInfo(image_info->magick,sans_exception);
2514
sans_exception=DestroyExceptionInfo(sans_exception);
2515
properties=(&image->blob->properties);
2516
if ((magick_info != (const MagickInfo *) NULL) &&
2517
(GetMagickBlobSupport(magick_info) != MagickFalse) &&
2518
(properties->st_size <= MagickMaxBufferExtent))
2526
length=(size_t) properties->st_size;
2527
blob=MapBlob(fileno(image->blob->file),ReadMode,0,length);
2528
if (blob != (void *) NULL)
2531
Format supports blobs-- use memory-mapped I/O.
2533
if (image_info->file != (FILE *) NULL)
2534
image->blob->exempt=MagickFalse;
2537
(void) fclose(image->blob->file);
2538
image->blob->file=(FILE *) NULL;
2540
AttachBlob(image->blob,blob,length);
2541
image->blob->mapped=MagickTrue;
2548
#if defined(MAGICKCORE_ZLIB_DELEGATE)
2549
if ((LocaleCompare(extension,"Z") == 0) ||
2550
(LocaleCompare(extension,"gz") == 0) ||
2551
(LocaleCompare(extension,"wmz") == 0) ||
2552
(LocaleCompare(extension,"svgz") == 0))
2554
if (mode == WriteBinaryBlobMode)
2556
image->blob->file=(FILE *) gzopen(filename,type);
2557
if (image->blob->file != (FILE *) NULL)
2558
image->blob->type=ZipStream;
2562
#if defined(MAGICKCORE_BZLIB_DELEGATE)
2563
if (LocaleCompare(extension,".bz2") == 0)
2565
image->blob->file=(FILE *) BZ2_bzopen(filename,type);
2566
if (image->blob->file != (FILE *) NULL)
2567
image->blob->type=BZipStream;
2572
image->blob->file=(FILE *) OpenMagickStream(filename,type);
2573
if (image->blob->file != (FILE *) NULL)
2575
image->blob->type=FileStream;
2576
#if defined(MAGICKCORE_HAVE_SETVBUF)
2577
(void) setvbuf(image->blob->file,(char *) NULL,(int) _IOFBF,
2582
image->blob->status=MagickFalse;
2583
if (image->blob->type != UndefinedStream)
2584
image->blob->size=GetBlobSize(image);
2587
ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename);
2588
return(MagickFalse);
2594
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2602
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2604
% PingBlob() returns all the attributes of an image or image sequence except
2605
% for the pixels. It is much faster and consumes far less memory than
2606
% BlobToImage(). On failure, a NULL image is returned and exception
2607
% describes the reason for the failure.
2609
% The format of the PingBlob method is:
2611
% Image *PingBlob(const ImageInfo *image_info,const void *blob,
2612
% const size_t length,ExceptionInfo *exception)
2614
% A description of each parameter follows:
2616
% o image_info: the image info.
2618
% o blob: the address of a character stream in one of the image formats
2619
% understood by ImageMagick.
2621
% o length: This size_t integer reflects the length in bytes of the blob.
2623
% o exception: return any errors or warnings in this structure.
2627
#if defined(__cplusplus) || defined(c_plusplus)
2631
static size_t PingStream(const Image *magick_unused(image),
2632
const void *magick_unused(pixels),const size_t columns)
2637
#if defined(__cplusplus) || defined(c_plusplus)
2641
MagickExport Image *PingBlob(const ImageInfo *image_info,const void *blob,
2642
const size_t length,ExceptionInfo *exception)
2650
assert(image_info != (ImageInfo *) NULL);
2651
assert(image_info->signature == MagickSignature);
2652
if (image_info->debug != MagickFalse)
2653
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2654
image_info->filename);
2655
assert(exception != (ExceptionInfo *) NULL);
2656
if ((blob == (const void *) NULL) || (length == 0))
2658
(void) ThrowMagickException(exception,GetMagickModule(),BlobError,
2659
"UnrecognizedImageFormat","`%s'",image_info->magick);
2660
return((Image *) NULL);
2662
ping_info=CloneImageInfo(image_info);
2663
ping_info->blob=(void *) AcquireQuantumMemory(length,sizeof(unsigned char));
2664
if (ping_info->blob == (const void *) NULL)
2666
(void) ThrowMagickException(exception,GetMagickModule(),
2667
ResourceLimitFatalError,"MemoryAllocationFailed","`%s'","");
2668
return((Image *) NULL);
2670
(void) memcpy(ping_info->blob,blob,length);
2671
ping_info->length=length;
2672
ping_info->ping=MagickTrue;
2673
image=ReadStream(ping_info,&PingStream,exception);
2674
ping_info->blob=(void *) RelinquishMagickMemory(ping_info->blob);
2675
ping_info=DestroyImageInfo(ping_info);
2680
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2688
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2690
% ReadBlob() reads data from the blob or image file and returns it. It
2691
% returns the number of bytes read.
2693
% The format of the ReadBlob method is:
2695
% ssize_t ReadBlob(Image *image,const size_t length,unsigned char *data)
2697
% A description of each parameter follows:
2699
% o image: the image.
2701
% o length: Specifies an integer representing the number of bytes to read
2704
% o data: Specifies an area to place the information requested from the
2708
MagickExport ssize_t ReadBlob(Image *image,const size_t length,
2709
unsigned char *data)
2714
register unsigned char
2720
assert(image != (Image *) NULL);
2721
assert(image->signature == MagickSignature);
2722
assert(image->blob != (BlobInfo *) NULL);
2723
assert(image->blob->type != UndefinedStream);
2726
assert(data != (void *) NULL);
2729
switch (image->blob->type)
2731
case UndefinedStream:
2734
case StandardStream:
2741
count=(ssize_t) fread(q,1,length,image->blob->file);
2746
c=getc(image->blob->file);
2749
*q++=(unsigned char) c;
2754
c=getc(image->blob->file);
2757
*q++=(unsigned char) c;
2767
#if defined(MAGICKCORE_ZLIB_DELEGATE)
2772
count=(ssize_t) gzread(image->blob->file,q,(unsigned int) length);
2777
c=gzgetc(image->blob->file);
2780
*q++=(unsigned char) c;
2785
c=gzgetc(image->blob->file);
2788
*q++=(unsigned char) c;
2799
#if defined(MAGICKCORE_BZLIB_DELEGATE)
2800
count=(ssize_t) BZ2_bzread((BZFILE *) image->blob->file,q,(int) length);
2808
register const unsigned char
2811
if (image->blob->offset >= (MagickOffsetType) image->blob->length)
2813
image->blob->eof=MagickTrue;
2816
p=image->blob->data+image->blob->offset;
2817
count=(ssize_t) MagickMin(length,image->blob->length-image->blob->offset);
2818
image->blob->offset+=count;
2819
if (count != (ssize_t) length)
2820
image->blob->eof=MagickTrue;
2821
(void) memcpy(q,p,(size_t) count);
2829
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2833
+ R e a d B l o b B y t e %
2837
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2839
% ReadBlobByte() reads a single byte from the image file and returns it.
2841
% The format of the ReadBlobByte method is:
2843
% int ReadBlobByte(Image *image)
2845
% A description of each parameter follows.
2847
% o image: the image.
2850
MagickExport int ReadBlobByte(Image *image)
2852
register const unsigned char
2861
assert(image != (Image *) NULL);
2862
assert(image->signature == MagickSignature);
2863
p=ReadBlobStream(image,1,buffer,&count);
2870
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2874
+ R e a d B l o b D o u b l e %
2878
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2880
% ReadBlobDouble() reads a double value as a 64-bit quantity in the byte-order
2881
% specified by the endian member of the image structure.
2883
% The format of the ReadBlobDouble method is:
2885
% double ReadBlobDouble(Image *image)
2887
% A description of each parameter follows.
2889
% o image: the image.
2892
MagickExport double ReadBlobDouble(Image *image)
2903
quantum.double_value=0.0;
2904
quantum.unsigned_value=ReadBlobLongLong(image);
2905
return(quantum.double_value);
2909
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2913
+ R e a d B l o b F l o a t %
2917
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2919
% ReadBlobFloat() reads a float value as a 32-bit quantity in the byte-order
2920
% specified by the endian member of the image structure.
2922
% The format of the ReadBlobFloat method is:
2924
% float ReadBlobFloat(Image *image)
2926
% A description of each parameter follows.
2928
% o image: the image.
2931
MagickExport float ReadBlobFloat(Image *image)
2942
quantum.float_value=0.0;
2943
quantum.unsigned_value=ReadBlobLong(image);
2944
return(quantum.float_value);
2948
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2952
+ R e a d B l o b L o n g %
2956
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2958
% ReadBlobLong() reads a ssize_t value as a 32-bit quantity in the byte-order
2959
% specified by the endian member of the image structure.
2961
% The format of the ReadBlobLong method is:
2963
% unsigned int ReadBlobLong(Image *image)
2965
% A description of each parameter follows.
2967
% o image: the image.
2970
MagickExport unsigned int ReadBlobLong(Image *image)
2972
register const unsigned char
2984
assert(image != (Image *) NULL);
2985
assert(image->signature == MagickSignature);
2987
p=ReadBlobStream(image,4,buffer,&count);
2990
if (image->endian == LSBEndian)
2992
value=(unsigned int) (*p++);
2993
value|=((unsigned int) (*p++)) << 8;
2994
value|=((unsigned int) (*p++)) << 16;
2995
value|=((unsigned int) (*p++)) << 24;
2998
value=((unsigned int) (*p++)) << 24;
2999
value|=((unsigned int) (*p++)) << 16;
3000
value|=((unsigned int) (*p++)) << 8;
3001
value|=((unsigned int) (*p++));
3006
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3010
+ R e a d B l o b L o n g L o n g %
3014
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3016
% ReadBlobLongLong() reads a long long value as a 64-bit quantity in the
3017
% byte-order specified by the endian member of the image structure.
3019
% The format of the ReadBlobLongLong method is:
3021
% MagickSizeType ReadBlobLongLong(Image *image)
3023
% A description of each parameter follows.
3025
% o image: the image.
3028
MagickExport MagickSizeType ReadBlobLongLong(Image *image)
3033
register const unsigned char
3042
assert(image != (Image *) NULL);
3043
assert(image->signature == MagickSignature);
3045
p=ReadBlobStream(image,8,buffer,&count);
3047
return(MagickULLConstant(0));
3048
if (image->endian == LSBEndian)
3050
value=(MagickSizeType) (*p++);
3051
value|=((MagickSizeType) (*p++)) << 8;
3052
value|=((MagickSizeType) (*p++)) << 16;
3053
value|=((MagickSizeType) (*p++)) << 24;
3054
value|=((MagickSizeType) (*p++)) << 32;
3055
value|=((MagickSizeType) (*p++)) << 40;
3056
value|=((MagickSizeType) (*p++)) << 48;
3057
value|=((MagickSizeType) (*p++)) << 56;
3058
return(value & MagickULLConstant(0xffffffffffffffff));
3060
value=((MagickSizeType) (*p++)) << 56;
3061
value|=((MagickSizeType) (*p++)) << 48;
3062
value|=((MagickSizeType) (*p++)) << 40;
3063
value|=((MagickSizeType) (*p++)) << 32;
3064
value|=((MagickSizeType) (*p++)) << 24;
3065
value|=((MagickSizeType) (*p++)) << 16;
3066
value|=((MagickSizeType) (*p++)) << 8;
3067
value|=((MagickSizeType) (*p++));
3068
return(value & MagickULLConstant(0xffffffffffffffff));
3072
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3076
+ R e a d B l o b S h o r t %
3080
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3082
% ReadBlobShort() reads a short value as a 16-bit quantity in the byte-order
3083
% specified by the endian member of the image structure.
3085
% The format of the ReadBlobShort method is:
3087
% unsigned short ReadBlobShort(Image *image)
3089
% A description of each parameter follows.
3091
% o image: the image.
3094
MagickExport unsigned short ReadBlobShort(Image *image)
3096
register const unsigned char
3099
register unsigned int
3108
assert(image != (Image *) NULL);
3109
assert(image->signature == MagickSignature);
3111
p=ReadBlobStream(image,2,buffer,&count);
3113
return((unsigned short) 0U);
3114
if (image->endian == LSBEndian)
3116
value=(unsigned int) (*p++);
3117
value|=((unsigned int) (*p++)) << 8;
3118
return((unsigned short) (value & 0xffff));
3120
value=(unsigned int) ((*p++) << 8);
3121
value|=(unsigned int) (*p++);
3122
return((unsigned short) (value & 0xffff));
3126
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3130
+ R e a d B l o b L S B L o n g %
3134
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3136
% ReadBlobLSBLong() reads a ssize_t value as a 32-bit quantity in
3137
% least-significant byte first order.
3139
% The format of the ReadBlobLSBLong method is:
3141
% unsigned int ReadBlobLSBLong(Image *image)
3143
% A description of each parameter follows.
3145
% o image: the image.
3148
MagickExport unsigned int ReadBlobLSBLong(Image *image)
3150
register const unsigned char
3153
register unsigned int
3162
assert(image != (Image *) NULL);
3163
assert(image->signature == MagickSignature);
3165
p=ReadBlobStream(image,4,buffer,&count);
3168
value=(unsigned int) (*p++);
3169
value|=((unsigned int) (*p++)) << 8;
3170
value|=((unsigned int) (*p++)) << 16;
3171
value|=((unsigned int) (*p++)) << 24;
3176
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3180
+ R e a d B l o b L S B S h o r t %
3184
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3186
% ReadBlobLSBShort() reads a short value as a 16-bit quantity in
3187
% least-significant byte first order.
3189
% The format of the ReadBlobLSBShort method is:
3191
% unsigned short ReadBlobLSBShort(Image *image)
3193
% A description of each parameter follows.
3195
% o image: the image.
3198
MagickExport unsigned short ReadBlobLSBShort(Image *image)
3200
register const unsigned char
3203
register unsigned int
3212
assert(image != (Image *) NULL);
3213
assert(image->signature == MagickSignature);
3215
p=ReadBlobStream(image,2,buffer,&count);
3217
return((unsigned short) 0U);
3218
value=(unsigned int) (*p++);
3219
value|=((unsigned int) ((*p++)) << 8);
3220
return((unsigned short) (value & 0xffff));
3224
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3228
+ R e a d B l o b M S B L o n g %
3232
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3234
% ReadBlobMSBLong() reads a ssize_t value as a 32-bit quantity in
3235
% most-significant byte first order.
3237
% The format of the ReadBlobMSBLong method is:
3239
% unsigned int ReadBlobMSBLong(Image *image)
3241
% A description of each parameter follows.
3243
% o image: the image.
3246
MagickExport unsigned int ReadBlobMSBLong(Image *image)
3248
register const unsigned char
3251
register unsigned int
3260
assert(image != (Image *) NULL);
3261
assert(image->signature == MagickSignature);
3263
p=ReadBlobStream(image,4,buffer,&count);
3266
value=((unsigned int) (*p++) << 24);
3267
value|=((unsigned int) (*p++) << 16);
3268
value|=((unsigned int) (*p++) << 8);
3269
value|=(unsigned int) (*p++);
3274
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3278
+ R e a d B l o b M S B L o n g L o n g %
3282
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3284
% ReadBlobMSBLongLong() reads a ssize_t value as a 64-bit quantity in
3285
% most-significant byte first order.
3287
% The format of the ReadBlobMSBLongLong method is:
3289
% unsigned int ReadBlobMSBLongLong(Image *image)
3291
% A description of each parameter follows.
3293
% o image: the image.
3296
MagickExport MagickSizeType ReadBlobMSBLongLong(Image *image)
3298
register const unsigned char
3301
register MagickSizeType
3310
assert(image != (Image *) NULL);
3311
assert(image->signature == MagickSignature);
3313
p=ReadBlobStream(image,8,buffer,&count);
3315
return(MagickULLConstant(0));
3316
value=((MagickSizeType) (*p++)) << 56;
3317
value|=((MagickSizeType) (*p++)) << 48;
3318
value|=((MagickSizeType) (*p++)) << 40;
3319
value|=((MagickSizeType) (*p++)) << 32;
3320
value|=((MagickSizeType) (*p++)) << 24;
3321
value|=((MagickSizeType) (*p++)) << 16;
3322
value|=((MagickSizeType) (*p++)) << 8;
3323
value|=((MagickSizeType) (*p++));
3324
return(value & MagickULLConstant(0xffffffffffffffff));
3328
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3332
+ R e a d B l o b M S B S h o r t %
3336
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3338
% ReadBlobMSBShort() reads a short value as a 16-bit quantity in
3339
% most-significant byte first order.
3341
% The format of the ReadBlobMSBShort method is:
3343
% unsigned short ReadBlobMSBShort(Image *image)
3345
% A description of each parameter follows.
3347
% o image: the image.
3350
MagickExport unsigned short ReadBlobMSBShort(Image *image)
3352
register const unsigned char
3355
register unsigned int
3364
assert(image != (Image *) NULL);
3365
assert(image->signature == MagickSignature);
3367
p=ReadBlobStream(image,2,buffer,&count);
3369
return((unsigned short) 0U);
3370
value=(unsigned int) ((*p++) << 8);
3371
value|=(unsigned int) (*p++);
3372
return((unsigned short) (value & 0xffff));
3376
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3380
+ R e a d B l o b S t r i n g %
3384
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3386
% ReadBlobString() reads characters from a blob or file until a newline
3387
% character is read or an end-of-file condition is encountered.
3389
% The format of the ReadBlobString method is:
3391
% char *ReadBlobString(Image *image,char *string)
3393
% A description of each parameter follows:
3395
% o image: the image.
3397
% o string: the address of a character buffer.
3400
MagickExport char *ReadBlobString(Image *image,char *string)
3402
register const unsigned char
3414
assert(image != (Image *) NULL);
3415
assert(image->signature == MagickSignature);
3416
for (i=0; i < (MaxTextExtent-1L); i++)
3418
p=ReadBlobStream(image,1,buffer,&count);
3422
return((char *) NULL);
3425
string[i]=(char) (*p);
3426
if ((string[i] == '\r') || (string[i] == '\n'))
3429
if (string[i] == '\r')
3430
(void) ReadBlobStream(image,1,buffer,&count);
3436
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3440
+ R e f e r e n c e B l o b %
3444
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3446
% ReferenceBlob() increments the reference count associated with the pixel
3447
% blob returning a pointer to the blob.
3449
% The format of the ReferenceBlob method is:
3451
% BlobInfo ReferenceBlob(BlobInfo *blob_info)
3453
% A description of each parameter follows:
3455
% o blob_info: the blob_info.
3458
MagickExport BlobInfo *ReferenceBlob(BlobInfo *blob)
3460
assert(blob != (BlobInfo *) NULL);
3461
assert(blob->signature == MagickSignature);
3462
if (blob->debug != MagickFalse)
3463
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
3464
LockSemaphoreInfo(blob->semaphore);
3465
blob->reference_count++;
3466
UnlockSemaphoreInfo(blob->semaphore);
3471
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3479
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3481
% SeekBlob() sets the offset in bytes from the beginning of a blob or file
3482
% and returns the resulting offset.
3484
% The format of the SeekBlob method is:
3486
% MagickOffsetType SeekBlob(Image *image,const MagickOffsetType offset,
3489
% A description of each parameter follows:
3491
% o image: the image.
3493
% o offset: Specifies an integer representing the offset in bytes.
3495
% o whence: Specifies an integer representing how the offset is
3496
% treated relative to the beginning of the blob as follows:
3498
% SEEK_SET Set position equal to offset bytes.
3499
% SEEK_CUR Set position to current location plus offset.
3500
% SEEK_END Set position to EOF plus offset.
3503
MagickExport MagickOffsetType SeekBlob(Image *image,
3504
const MagickOffsetType offset,const int whence)
3506
assert(image != (Image *) NULL);
3507
assert(image->signature == MagickSignature);
3508
if (image->debug != MagickFalse)
3509
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3510
assert(image->blob != (BlobInfo *) NULL);
3511
assert(image->blob->type != UndefinedStream);
3512
switch (image->blob->type)
3514
case UndefinedStream:
3518
if (fseek(image->blob->file,offset,whence) < 0)
3520
image->blob->offset=TellBlob(image);
3523
case StandardStream:
3527
#if defined(MAGICKCORE_ZLIB_DELEGATE)
3528
if (gzseek(image->blob->file,(off_t) offset,whence) < 0)
3531
image->blob->offset=TellBlob(image);
3547
image->blob->offset=offset;
3552
if ((image->blob->offset+offset) < 0)
3554
image->blob->offset+=offset;
3559
if (((MagickOffsetType) image->blob->length+offset) < 0)
3561
image->blob->offset=image->blob->length+offset;
3565
if (image->blob->offset <= (MagickOffsetType)
3566
((off_t) image->blob->length))
3567
image->blob->eof=MagickFalse;
3569
if (image->blob->mapped != MagickFalse)
3573
image->blob->extent=(size_t) (image->blob->offset+
3574
image->blob->quantum);
3575
image->blob->data=(unsigned char *) ResizeQuantumMemory(
3576
image->blob->data,image->blob->extent+1,
3577
sizeof(*image->blob->data));
3578
(void) SyncBlob(image);
3579
if (image->blob->data == (unsigned char *) NULL)
3581
(void) DetachBlob(image->blob);
3588
return(image->blob->offset);
3592
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3596
+ S e t B l o b E x e m p t %
3600
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3602
% SetBlobExempt() sets the blob exempt status.
3604
% The format of the SetBlobExempt method is:
3606
% MagickBooleanType SetBlobExempt(const Image *image,
3607
% const MagickBooleanType exempt)
3609
% A description of each parameter follows:
3611
% o image: the image.
3613
% o exempt: Set to true if this blob is exempt from being closed.
3616
MagickExport void SetBlobExempt(Image *image,const MagickBooleanType exempt)
3618
assert(image != (const Image *) NULL);
3619
assert(image->signature == MagickSignature);
3620
if (image->debug != MagickFalse)
3621
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3622
image->blob->exempt=exempt;
3626
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3630
+ S e t B l o b E x t e n t %
3634
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3636
% SetBlobExtent() ensures enough space is allocated for the blob. If the
3637
% method is successful, subsequent writes to bytes in the specified range are
3638
% guaranteed not to fail.
3640
% The format of the SetBlobExtent method is:
3642
% MagickBooleanType SetBlobExtent(Image *image,const MagickSizeType extent)
3644
% A description of each parameter follows:
3646
% o image: the image.
3648
% o extent: the blob maximum extent.
3651
MagickExport MagickBooleanType SetBlobExtent(Image *image,
3652
const MagickSizeType extent)
3654
assert(image != (Image *) NULL);
3655
assert(image->signature == MagickSignature);
3656
if (image->debug != MagickFalse)
3657
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3658
assert(image->blob != (BlobInfo *) NULL);
3659
assert(image->blob->type != UndefinedStream);
3660
switch (image->blob->type)
3662
case UndefinedStream:
3666
if (extent != (MagickSizeType) ((off_t) extent))
3667
return(MagickFalse);
3668
#if !defined(MAGICKCORE_POSIX_FALLOCATE)
3669
return(MagickFalse);
3678
offset=TellBlob(image);
3679
status=posix_fallocate(fileno(image->blob->file),(off_t) offset,
3680
(off_t) (extent-offset));
3682
return(MagickFalse);
3687
case StandardStream:
3690
return(MagickFalse);
3692
return(MagickFalse);
3694
return(MagickFalse);
3697
if (image->blob->mapped != MagickFalse)
3699
if (image->blob->file == (FILE *) NULL)
3700
return(MagickFalse);
3701
(void) UnmapBlob(image->blob->data,image->blob->length);
3702
#if !defined(MAGICKCORE_POSIX_FALLOCATE)
3703
return(MagickFalse);
3712
offset=TellBlob(image);
3713
status=posix_fallocate(fileno(image->blob->file),(off_t) offset,
3714
(off_t) (extent-offset));
3716
return(MagickFalse);
3718
image->blob->data=(unsigned char*) MapBlob(fileno(image->blob->file),
3719
WriteMode,0,(size_t) extent);
3720
image->blob->extent=(size_t) extent;
3721
image->blob->length=(size_t) extent;
3722
(void) SyncBlob(image);
3726
if (extent != (MagickSizeType) ((size_t) extent))
3727
return(MagickFalse);
3728
image->blob->extent=(size_t) extent;
3729
image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data,
3730
image->blob->extent+1,sizeof(*image->blob->data));
3731
(void) SyncBlob(image);
3732
if (image->blob->data == (unsigned char *) NULL)
3734
(void) DetachBlob(image->blob);
3735
return(MagickFalse);
3744
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3752
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3754
% SyncBlob() flushes the datastream if it is a file or synchronizes the data
3755
% attributes if it is an blob.
3757
% The format of the SyncBlob method is:
3759
% int SyncBlob(Image *image)
3761
% A description of each parameter follows:
3763
% o image: the image.
3766
static int SyncBlob(Image *image)
3771
assert(image != (Image *) NULL);
3772
assert(image->signature == MagickSignature);
3773
if (image->debug != MagickFalse)
3774
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3775
assert(image->blob != (BlobInfo *) NULL);
3776
assert(image->blob->type != UndefinedStream);
3778
switch (image->blob->type)
3780
case UndefinedStream:
3783
case StandardStream:
3786
status=fflush(image->blob->file);
3791
#if defined(MAGICKCORE_ZLIB_DELEGATE)
3792
status=gzflush(image->blob->file,Z_SYNC_FLUSH);
3798
#if defined(MAGICKCORE_BZLIB_DELEGATE)
3799
status=BZ2_bzflush((BZFILE *) image->blob->file);
3807
#if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
3808
if (image->blob->mapped != MagickFalse)
3809
status=msync(image->blob->data,image->blob->length,MS_SYNC);
3818
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3826
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3828
% TellBlob() obtains the current value of the blob or file position.
3830
% The format of the TellBlob method is:
3832
% MagickOffsetType TellBlob(const Image *image)
3834
% A description of each parameter follows:
3836
% o image: the image.
3839
MagickExport MagickOffsetType TellBlob(const Image *image)
3844
assert(image != (Image *) NULL);
3845
assert(image->signature == MagickSignature);
3846
if (image->debug != MagickFalse)
3847
(void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
3848
assert(image->blob != (BlobInfo *) NULL);
3849
assert(image->blob->type != UndefinedStream);
3851
switch (image->blob->type)
3853
case UndefinedStream:
3857
offset=ftell(image->blob->file);
3860
case StandardStream:
3865
#if defined(MAGICKCORE_ZLIB_DELEGATE)
3866
offset=(MagickOffsetType) gztell(image->blob->file);
3876
offset=image->blob->offset;
3884
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3888
+ U n m a p B l o b %
3892
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3894
% UnmapBlob() deallocates the binary large object previously allocated with
3895
% the MapBlob method.
3897
% The format of the UnmapBlob method is:
3899
% MagickBooleanType UnmapBlob(void *map,const size_t length)
3901
% A description of each parameter follows:
3903
% o map: the address of the binary large object.
3905
% o length: the length of the binary large object.
3908
MagickExport MagickBooleanType UnmapBlob(void *map,const size_t length)
3910
#if defined(MAGICKCORE_HAVE_MMAP_FILEIO)
3914
status=munmap(map,length);
3915
return(status == -1 ? MagickFalse : MagickTrue);
3919
return(MagickFalse);
3924
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3928
+ W r i t e B l o b %
3932
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3934
% WriteBlob() writes data to a blob or image file. It returns the number of
3937
% The format of the WriteBlob method is:
3939
% ssize_t WriteBlob(Image *image,const size_t length,
3940
% const unsigned char *data)
3942
% A description of each parameter follows:
3944
% o image: the image.
3946
% o length: Specifies an integer representing the number of bytes to
3947
% write to the file.
3949
% o data: The address of the data to write to the blob or file.
3952
MagickExport ssize_t WriteBlob(Image *image,const size_t length,
3953
const unsigned char *data)
3958
register const unsigned char
3964
assert(image != (Image *) NULL);
3965
assert(image->signature == MagickSignature);
3966
assert(data != (const unsigned char *) NULL);
3967
assert(image->blob != (BlobInfo *) NULL);
3968
assert(image->blob->type != UndefinedStream);
3973
switch (image->blob->type)
3975
case UndefinedStream:
3978
case StandardStream:
3985
count=(ssize_t) fwrite((const char *) data,1,length,
3991
c=putc((int) *p++,image->blob->file);
3998
c=putc((int) *p++,image->blob->file);
4010
#if defined(MAGICKCORE_ZLIB_DELEGATE)
4015
count=(ssize_t) gzwrite(image->blob->file,(void *) data,
4016
(unsigned int) length);
4021
c=gzputc(image->blob->file,(int) *p++);
4028
c=gzputc(image->blob->file,(int) *p++);
4041
#if defined(MAGICKCORE_BZLIB_DELEGATE)
4042
count=(ssize_t) BZ2_bzwrite((BZFILE *) image->blob->file,(void *) data,
4049
count=(ssize_t) image->blob->stream(image,data,length);
4054
register unsigned char
4057
if ((image->blob->offset+(MagickOffsetType) length) >=
4058
(MagickOffsetType) image->blob->extent)
4060
if (image->blob->mapped != MagickFalse)
4062
image->blob->quantum<<=1;
4063
image->blob->extent+=length+image->blob->quantum;
4064
image->blob->data=(unsigned char *) ResizeQuantumMemory(
4065
image->blob->data,image->blob->extent+1,sizeof(*image->blob->data));
4066
(void) SyncBlob(image);
4067
if (image->blob->data == (unsigned char *) NULL)
4069
(void) DetachBlob(image->blob);
4073
q=image->blob->data+image->blob->offset;
4074
(void) memcpy(q,p,length);
4075
image->blob->offset+=length;
4076
if (image->blob->offset >= (MagickOffsetType) image->blob->length)
4077
image->blob->length=(size_t) image->blob->offset;
4078
count=(ssize_t) length;
4085
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4089
+ W r i t e B l o b B y t e %
4093
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4095
% WriteBlobByte() write an integer to a blob. It returns the number of bytes
4096
% written (either 0 or 1);
4098
% The format of the WriteBlobByte method is:
4100
% ssize_t WriteBlobByte(Image *image,const unsigned char value)
4102
% A description of each parameter follows.
4104
% o image: the image.
4106
% o value: Specifies the value to write.
4109
MagickExport ssize_t WriteBlobByte(Image *image,const unsigned char value)
4111
assert(image != (Image *) NULL);
4112
assert(image->signature == MagickSignature);
4113
return(WriteBlobStream(image,1,&value));
4117
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4121
+ W r i t e B l o b F l o a t %
4125
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4127
% WriteBlobFloat() writes a float value as a 32-bit quantity in the byte-order
4128
% specified by the endian member of the image structure.
4130
% The format of the WriteBlobFloat method is:
4132
% ssize_t WriteBlobFloat(Image *image,const float value)
4134
% A description of each parameter follows.
4136
% o image: the image.
4138
% o value: Specifies the value to write.
4141
MagickExport ssize_t WriteBlobFloat(Image *image,const float value)
4152
quantum.unsigned_value=0U;
4153
quantum.float_value=value;
4154
return(WriteBlobLong(image,quantum.unsigned_value));
4158
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4162
+ W r i t e B l o b L o n g %
4166
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4168
% WriteBlobLong() writes a ssize_t value as a 32-bit quantity in the byte-order
4169
% specified by the endian member of the image structure.
4171
% The format of the WriteBlobLong method is:
4173
% ssize_t WriteBlobLong(Image *image,const unsigned int value)
4175
% A description of each parameter follows.
4177
% o image: the image.
4179
% o value: Specifies the value to write.
4182
MagickExport ssize_t WriteBlobLong(Image *image,const unsigned int value)
4187
assert(image != (Image *) NULL);
4188
assert(image->signature == MagickSignature);
4189
if (image->endian == LSBEndian)
4191
buffer[0]=(unsigned char) value;
4192
buffer[1]=(unsigned char) (value >> 8);
4193
buffer[2]=(unsigned char) (value >> 16);
4194
buffer[3]=(unsigned char) (value >> 24);
4195
return(WriteBlobStream(image,4,buffer));
4197
buffer[0]=(unsigned char) (value >> 24);
4198
buffer[1]=(unsigned char) (value >> 16);
4199
buffer[2]=(unsigned char) (value >> 8);
4200
buffer[3]=(unsigned char) value;
4201
return(WriteBlobStream(image,4,buffer));
4205
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4209
+ W r i t e B l o b S h o r t %
4213
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4215
% WriteBlobShort() writes a short value as a 16-bit quantity in the
4216
% byte-order specified by the endian member of the image structure.
4218
% The format of the WriteBlobShort method is:
4220
% ssize_t WriteBlobShort(Image *image,const unsigned short value)
4222
% A description of each parameter follows.
4224
% o image: the image.
4226
% o value: Specifies the value to write.
4229
MagickExport ssize_t WriteBlobShort(Image *image,const unsigned short value)
4234
assert(image != (Image *) NULL);
4235
assert(image->signature == MagickSignature);
4236
if (image->endian == LSBEndian)
4238
buffer[0]=(unsigned char) value;
4239
buffer[1]=(unsigned char) (value >> 8);
4240
return(WriteBlobStream(image,2,buffer));
4242
buffer[0]=(unsigned char) (value >> 8);
4243
buffer[1]=(unsigned char) value;
4244
return(WriteBlobStream(image,2,buffer));
4248
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4252
+ W r i t e B l o b L S B L o n g %
4256
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4258
% WriteBlobLSBLong() writes a ssize_t value as a 32-bit quantity in
4259
% least-significant byte first order.
4261
% The format of the WriteBlobLSBLong method is:
4263
% ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4265
% A description of each parameter follows.
4267
% o image: the image.
4269
% o value: Specifies the value to write.
4272
MagickExport ssize_t WriteBlobLSBLong(Image *image,const unsigned int value)
4277
assert(image != (Image *) NULL);
4278
assert(image->signature == MagickSignature);
4279
buffer[0]=(unsigned char) value;
4280
buffer[1]=(unsigned char) (value >> 8);
4281
buffer[2]=(unsigned char) (value >> 16);
4282
buffer[3]=(unsigned char) (value >> 24);
4283
return(WriteBlobStream(image,4,buffer));
4287
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4291
+ W r i t e B l o b L S B S h o r t %
4295
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4297
% WriteBlobLSBShort() writes a ssize_t value as a 16-bit quantity in
4298
% least-significant byte first order.
4300
% The format of the WriteBlobLSBShort method is:
4302
% ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4304
% A description of each parameter follows.
4306
% o image: the image.
4308
% o value: Specifies the value to write.
4311
MagickExport ssize_t WriteBlobLSBShort(Image *image,const unsigned short value)
4316
assert(image != (Image *) NULL);
4317
assert(image->signature == MagickSignature);
4318
buffer[0]=(unsigned char) value;
4319
buffer[1]=(unsigned char) (value >> 8);
4320
return(WriteBlobStream(image,2,buffer));
4324
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4328
+ W r i t e B l o b M S B L o n g %
4332
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4334
% WriteBlobMSBLong() writes a ssize_t value as a 32-bit quantity in
4335
% most-significant byte first order.
4337
% The format of the WriteBlobMSBLong method is:
4339
% ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4341
% A description of each parameter follows.
4343
% o value: Specifies the value to write.
4345
% o image: the image.
4348
MagickExport ssize_t WriteBlobMSBLong(Image *image,const unsigned int value)
4353
assert(image != (Image *) NULL);
4354
assert(image->signature == MagickSignature);
4355
buffer[0]=(unsigned char) (value >> 24);
4356
buffer[1]=(unsigned char) (value >> 16);
4357
buffer[2]=(unsigned char) (value >> 8);
4358
buffer[3]=(unsigned char) value;
4359
return(WriteBlobStream(image,4,buffer));
4363
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4367
+ W r i t e B l o b M S B L o n g L o n g %
4371
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4373
% WriteBlobMSBLongLong() writes a long long value as a 64-bit quantity in
4374
% most-significant byte first order.
4376
% The format of the WriteBlobMSBLongLong method is:
4378
% ssize_t WriteBlobMSBLongLong(Image *image,const MagickSizeType value)
4380
% A description of each parameter follows.
4382
% o value: Specifies the value to write.
4384
% o image: the image.
4387
MagickExport ssize_t WriteBlobMSBLongLong(Image *image,
4388
const MagickSizeType value)
4393
assert(image != (Image *) NULL);
4394
assert(image->signature == MagickSignature);
4395
buffer[0]=(unsigned char) (value >> 56);
4396
buffer[1]=(unsigned char) (value >> 48);
4397
buffer[2]=(unsigned char) (value >> 40);
4398
buffer[3]=(unsigned char) (value >> 32);
4399
buffer[4]=(unsigned char) (value >> 24);
4400
buffer[5]=(unsigned char) (value >> 16);
4401
buffer[6]=(unsigned char) (value >> 8);
4402
buffer[7]=(unsigned char) value;
4403
return(WriteBlobStream(image,8,buffer));
4407
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4411
+ W r i t e B l o b M S B S h o r t %
4415
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4417
% WriteBlobMSBShort() writes a ssize_t value as a 16-bit quantity in
4418
% most-significant byte first order.
4420
% The format of the WriteBlobMSBShort method is:
4422
% ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4424
% A description of each parameter follows.
4426
% o value: Specifies the value to write.
4428
% o file: Specifies the file to write the data to.
4431
MagickExport ssize_t WriteBlobMSBShort(Image *image,const unsigned short value)
4436
assert(image != (Image *) NULL);
4437
assert(image->signature == MagickSignature);
4438
buffer[0]=(unsigned char) (value >> 8);
4439
buffer[1]=(unsigned char) value;
4440
return(WriteBlobStream(image,2,buffer));
4444
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4448
+ W r i t e B l o b S t r i n g %
4452
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4454
% WriteBlobString() write a string to a blob. It returns the number of
4455
% characters written.
4457
% The format of the WriteBlobString method is:
4459
% ssize_t WriteBlobString(Image *image,const char *string)
4461
% A description of each parameter follows.
4463
% o image: the image.
4465
% o string: Specifies the string to write.
4468
MagickExport ssize_t WriteBlobString(Image *image,const char *string)
4470
assert(image != (Image *) NULL);
4471
assert(image->signature == MagickSignature);
4472
assert(string != (const char *) NULL);
4473
return(WriteBlobStream(image,strlen(string),(const unsigned char *) string));