|
MagickCore
6.7.5
|
00001 /* 00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00003 % % 00004 % % 00005 % % 00006 % BBBB L OOO BBBB % 00007 % B B L O O B B % 00008 % BBBB L O O BBBB % 00009 % B B L O O B B % 00010 % BBBB LLLLL OOO BBBB % 00011 % % 00012 % % 00013 % MagickCore Binary Large OBjectS Methods % 00014 % % 00015 % Software Design % 00016 % John Cristy % 00017 % July 1999 % 00018 % % 00019 % % 00020 % Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization % 00021 % dedicated to making software imaging solutions freely available. % 00022 % % 00023 % You may not use this file except in compliance with the License. You may % 00024 % obtain a copy of the License at % 00025 % % 00026 % http://www.imagemagick.org/script/license.php % 00027 % % 00028 % Unless required by applicable law or agreed to in writing, software % 00029 % distributed under the License is distributed on an "AS IS" BASIS, % 00030 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % 00031 % See the License for the specific language governing permissions and % 00032 % limitations under the License. % 00033 % % 00034 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00035 % 00036 % 00037 % 00038 */ 00039 00040 /* 00041 Include declarations. 00042 */ 00043 #include "MagickCore/studio.h" 00044 #include "MagickCore/blob.h" 00045 #include "MagickCore/blob-private.h" 00046 #include "MagickCore/cache.h" 00047 #include "MagickCore/client.h" 00048 #include "MagickCore/constitute.h" 00049 #include "MagickCore/delegate.h" 00050 #include "MagickCore/exception.h" 00051 #include "MagickCore/exception-private.h" 00052 #include "MagickCore/image-private.h" 00053 #include "MagickCore/list.h" 00054 #include "MagickCore/locale_.h" 00055 #include "MagickCore/log.h" 00056 #include "MagickCore/magick.h" 00057 #include "MagickCore/memory_.h" 00058 #include "MagickCore/policy.h" 00059 #include "MagickCore/resource_.h" 00060 #include "MagickCore/semaphore.h" 00061 #include "MagickCore/string_.h" 00062 #include "MagickCore/string-private.h" 00063 #include "MagickCore/token.h" 00064 #include "MagickCore/utility.h" 00065 #include "MagickCore/utility-private.h" 00066 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO) && !defined(MAGICKCORE_WINDOWS_SUPPORT) 00067 # include <sys/mman.h> 00068 #endif 00069 #if defined(MAGICKCORE_ZLIB_DELEGATE) 00070 #include "zlib.h" 00071 #endif 00072 #if defined(MAGICKCORE_BZLIB_DELEGATE) 00073 #include "bzlib.h" 00074 #endif 00075 00076 /* 00077 Define declarations. 00078 */ 00079 #define MagickMaxBlobExtent 65541 00080 #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON) 00081 # define MAP_ANONYMOUS MAP_ANON 00082 #endif 00083 #if !defined(MAP_FAILED) 00084 #define MAP_FAILED ((void *) -1) 00085 #endif 00086 #if !defined(MS_SYNC) 00087 #define MS_SYNC 0x04 00088 #endif 00089 #if defined(__OS2__) 00090 #include <io.h> 00091 #define _O_BINARY O_BINARY 00092 #endif 00093 00094 /* 00095 Typedef declarations. 00096 */ 00097 struct _BlobInfo 00098 { 00099 size_t 00100 length, 00101 extent, 00102 quantum; 00103 00104 MagickBooleanType 00105 mapped, 00106 eof; 00107 00108 MagickOffsetType 00109 offset; 00110 00111 MagickSizeType 00112 size; 00113 00114 MagickBooleanType 00115 exempt, 00116 synchronize, 00117 status, 00118 temporary; 00119 00120 StreamType 00121 type; 00122 00123 union { 00124 FILE 00125 *file; 00126 00127 #if defined(MAGICKCORE_ZLIB_DELEGATE) 00128 gzFile 00129 gzfile; 00130 #endif 00131 00132 #if defined(MAGICKCORE_BZLIB_DELEGATE) 00133 BZFILE 00134 *bzfile; 00135 #endif 00136 }; 00137 00138 struct stat 00139 properties; 00140 00141 StreamHandler 00142 stream; 00143 00144 unsigned char 00145 *data; 00146 00147 MagickBooleanType 00148 debug; 00149 00150 SemaphoreInfo 00151 *semaphore; 00152 00153 ssize_t 00154 reference_count; 00155 00156 size_t 00157 signature; 00158 }; 00159 00160 /* 00161 Forward declarations. 00162 */ 00163 static int 00164 SyncBlob(Image *); 00165 00166 /* 00167 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00168 % % 00169 % % 00170 % % 00171 + A t t a c h B l o b % 00172 % % 00173 % % 00174 % % 00175 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00176 % 00177 % AttachBlob() attaches a blob to the BlobInfo structure. 00178 % 00179 % The format of the AttachBlob method is: 00180 % 00181 % void AttachBlob(BlobInfo *blob_info,const void *blob,const size_t length) 00182 % 00183 % A description of each parameter follows: 00184 % 00185 % o blob_info: Specifies a pointer to a BlobInfo structure. 00186 % 00187 % o blob: the address of a character stream in one of the image formats 00188 % understood by ImageMagick. 00189 % 00190 % o length: This size_t integer reflects the length in bytes of the blob. 00191 % 00192 */ 00193 MagickExport void AttachBlob(BlobInfo *blob_info,const void *blob, 00194 const size_t length) 00195 { 00196 assert(blob_info != (BlobInfo *) NULL); 00197 if (blob_info->debug != MagickFalse) 00198 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 00199 blob_info->length=length; 00200 blob_info->extent=length; 00201 blob_info->quantum=(size_t) MagickMaxBlobExtent; 00202 blob_info->offset=0; 00203 blob_info->type=BlobStream; 00204 blob_info->file=(FILE *) NULL; 00205 blob_info->data=(unsigned char *) blob; 00206 blob_info->mapped=MagickFalse; 00207 } 00208 00209 /* 00210 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00211 % % 00212 % % 00213 % % 00214 + B l o b T o F i l e % 00215 % % 00216 % % 00217 % % 00218 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00219 % 00220 % BlobToFile() writes a blob to a file. It returns MagickFalse if an error 00221 % occurs otherwise MagickTrue. 00222 % 00223 % The format of the BlobToFile method is: 00224 % 00225 % MagickBooleanType BlobToFile(char *filename,const void *blob, 00226 % const size_t length,ExceptionInfo *exception) 00227 % 00228 % A description of each parameter follows: 00229 % 00230 % o filename: Write the blob to this file. 00231 % 00232 % o blob: the address of a blob. 00233 % 00234 % o length: This length in bytes of the blob. 00235 % 00236 % o exception: return any errors or warnings in this structure. 00237 % 00238 */ 00239 00240 static inline MagickSizeType MagickMin(const MagickSizeType x, 00241 const MagickSizeType y) 00242 { 00243 if (x < y) 00244 return(x); 00245 return(y); 00246 } 00247 00248 MagickExport MagickBooleanType BlobToFile(char *filename,const void *blob, 00249 const size_t length,ExceptionInfo *exception) 00250 { 00251 int 00252 file; 00253 00254 register size_t 00255 i; 00256 00257 ssize_t 00258 count; 00259 00260 assert(filename != (const char *) NULL); 00261 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename); 00262 assert(blob != (const void *) NULL); 00263 if (*filename == '\0') 00264 file=AcquireUniqueFileResource(filename); 00265 else 00266 file=open_utf8(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE); 00267 if (file == -1) 00268 { 00269 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename); 00270 return(MagickFalse); 00271 } 00272 for (i=0; i < length; i+=count) 00273 { 00274 count=(ssize_t) write(file,(const char *) blob+i,(size_t) MagickMin(length- 00275 i,(MagickSizeType) SSIZE_MAX)); 00276 if (count <= 0) 00277 { 00278 count=0; 00279 if (errno != EINTR) 00280 break; 00281 } 00282 } 00283 file=close(file); 00284 if ((file == -1) || (i < length)) 00285 { 00286 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename); 00287 return(MagickFalse); 00288 } 00289 return(MagickTrue); 00290 } 00291 00292 /* 00293 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00294 % % 00295 % % 00296 % % 00297 % B l o b T o I m a g e % 00298 % % 00299 % % 00300 % % 00301 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00302 % 00303 % BlobToImage() implements direct to memory image formats. It returns the 00304 % blob as an image. 00305 % 00306 % The format of the BlobToImage method is: 00307 % 00308 % Image *BlobToImage(const ImageInfo *image_info,const void *blob, 00309 % const size_t length,ExceptionInfo *exception) 00310 % 00311 % A description of each parameter follows: 00312 % 00313 % o image_info: the image info. 00314 % 00315 % o blob: the address of a character stream in one of the image formats 00316 % understood by ImageMagick. 00317 % 00318 % o length: This size_t integer reflects the length in bytes of the blob. 00319 % 00320 % o exception: return any errors or warnings in this structure. 00321 % 00322 */ 00323 MagickExport Image *BlobToImage(const ImageInfo *image_info,const void *blob, 00324 const size_t length,ExceptionInfo *exception) 00325 { 00326 const MagickInfo 00327 *magick_info; 00328 00329 Image 00330 *image; 00331 00332 ImageInfo 00333 *blob_info, 00334 *clone_info; 00335 00336 MagickBooleanType 00337 status; 00338 00339 assert(image_info != (ImageInfo *) NULL); 00340 assert(image_info->signature == MagickSignature); 00341 if (image_info->debug != MagickFalse) 00342 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", 00343 image_info->filename); 00344 assert(exception != (ExceptionInfo *) NULL); 00345 if ((blob == (const void *) NULL) || (length == 0)) 00346 { 00347 (void) ThrowMagickException(exception,GetMagickModule(),BlobError, 00348 "ZeroLengthBlobNotPermitted","`%s'",image_info->filename); 00349 return((Image *) NULL); 00350 } 00351 blob_info=CloneImageInfo(image_info); 00352 blob_info->blob=(void *) blob; 00353 blob_info->length=length; 00354 if (*blob_info->magick == '\0') 00355 (void) SetImageInfo(blob_info,0,exception); 00356 magick_info=GetMagickInfo(blob_info->magick,exception); 00357 if (magick_info == (const MagickInfo *) NULL) 00358 { 00359 blob_info=DestroyImageInfo(blob_info); 00360 (void) ThrowMagickException(exception,GetMagickModule(), 00361 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'", 00362 image_info->filename); 00363 return((Image *) NULL); 00364 } 00365 if (GetMagickBlobSupport(magick_info) != MagickFalse) 00366 { 00367 /* 00368 Native blob support for this image format. 00369 */ 00370 (void) CopyMagickString(blob_info->filename,image_info->filename, 00371 MaxTextExtent); 00372 (void) CopyMagickString(blob_info->magick,image_info->magick, 00373 MaxTextExtent); 00374 image=ReadImage(blob_info,exception); 00375 if (image != (Image *) NULL) 00376 (void) DetachBlob(image->blob); 00377 blob_info=DestroyImageInfo(blob_info); 00378 return(image); 00379 } 00380 /* 00381 Write blob to a temporary file on disk. 00382 */ 00383 blob_info->blob=(void *) NULL; 00384 blob_info->length=0; 00385 *blob_info->filename='\0'; 00386 status=BlobToFile(blob_info->filename,blob,length,exception); 00387 if (status == MagickFalse) 00388 { 00389 (void) RelinquishUniqueFileResource(blob_info->filename); 00390 blob_info=DestroyImageInfo(blob_info); 00391 return((Image *) NULL); 00392 } 00393 clone_info=CloneImageInfo(blob_info); 00394 (void) FormatLocaleString(clone_info->filename,MaxTextExtent,"%s:%s", 00395 blob_info->magick,blob_info->filename); 00396 image=ReadImage(clone_info,exception); 00397 clone_info=DestroyImageInfo(clone_info); 00398 (void) RelinquishUniqueFileResource(blob_info->filename); 00399 blob_info=DestroyImageInfo(blob_info); 00400 return(image); 00401 } 00402 00403 /* 00404 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00405 % % 00406 % % 00407 % % 00408 + C l o n e B l o b I n f o % 00409 % % 00410 % % 00411 % % 00412 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00413 % 00414 % CloneBlobInfo() makes a duplicate of the given blob info structure, or if 00415 % blob info is NULL, a new one. 00416 % 00417 % The format of the CloneBlobInfo method is: 00418 % 00419 % BlobInfo *CloneBlobInfo(const BlobInfo *blob_info) 00420 % 00421 % A description of each parameter follows: 00422 % 00423 % o blob_info: the blob info. 00424 % 00425 */ 00426 MagickExport BlobInfo *CloneBlobInfo(const BlobInfo *blob_info) 00427 { 00428 BlobInfo 00429 *clone_info; 00430 00431 clone_info=(BlobInfo *) AcquireMagickMemory(sizeof(*clone_info)); 00432 if (clone_info == (BlobInfo *) NULL) 00433 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); 00434 GetBlobInfo(clone_info); 00435 if (blob_info == (BlobInfo *) NULL) 00436 return(clone_info); 00437 clone_info->length=blob_info->length; 00438 clone_info->extent=blob_info->extent; 00439 clone_info->synchronize=blob_info->synchronize; 00440 clone_info->quantum=blob_info->quantum; 00441 clone_info->mapped=blob_info->mapped; 00442 clone_info->eof=blob_info->eof; 00443 clone_info->offset=blob_info->offset; 00444 clone_info->size=blob_info->size; 00445 clone_info->exempt=blob_info->exempt; 00446 clone_info->status=blob_info->status; 00447 clone_info->temporary=blob_info->temporary; 00448 clone_info->type=blob_info->type; 00449 clone_info->file=blob_info->file; 00450 clone_info->properties=blob_info->properties; 00451 clone_info->stream=blob_info->stream; 00452 clone_info->data=blob_info->data; 00453 clone_info->debug=IsEventLogging(); 00454 clone_info->reference_count=1; 00455 return(clone_info); 00456 } 00457 00458 /* 00459 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00460 % % 00461 % % 00462 % % 00463 + C l o s e B l o b % 00464 % % 00465 % % 00466 % % 00467 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00468 % 00469 % CloseBlob() closes a stream associated with the image. 00470 % 00471 % The format of the CloseBlob method is: 00472 % 00473 % MagickBooleanType CloseBlob(Image *image) 00474 % 00475 % A description of each parameter follows: 00476 % 00477 % o image: the image. 00478 % 00479 */ 00480 MagickExport MagickBooleanType CloseBlob(Image *image) 00481 { 00482 int 00483 status; 00484 00485 /* 00486 Close image file. 00487 */ 00488 assert(image != (Image *) NULL); 00489 assert(image->signature == MagickSignature); 00490 if (image->debug != MagickFalse) 00491 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 00492 assert(image->blob != (BlobInfo *) NULL); 00493 if (image->blob->type == UndefinedStream) 00494 return(MagickTrue); 00495 if (image->blob->synchronize != MagickFalse) 00496 SyncBlob(image); 00497 image->blob->size=GetBlobSize(image); 00498 image->extent=image->blob->size; 00499 image->blob->eof=MagickFalse; 00500 if (image->blob->exempt != MagickFalse) 00501 { 00502 image->blob->type=UndefinedStream; 00503 return(MagickTrue); 00504 } 00505 status=0; 00506 switch (image->blob->type) 00507 { 00508 case UndefinedStream: 00509 break; 00510 case FileStream: 00511 case StandardStream: 00512 case PipeStream: 00513 { 00514 status=ferror(image->blob->file); 00515 break; 00516 } 00517 case ZipStream: 00518 { 00519 #if defined(MAGICKCORE_ZLIB_DELEGATE) 00520 (void) gzerror(image->blob->gzfile,&status); 00521 #endif 00522 break; 00523 } 00524 case BZipStream: 00525 { 00526 #if defined(MAGICKCORE_BZLIB_DELEGATE) 00527 (void) BZ2_bzerror(image->blob->bzfile,&status); 00528 #endif 00529 break; 00530 } 00531 case FifoStream: 00532 case BlobStream: 00533 break; 00534 } 00535 image->blob->status=status < 0 ? MagickTrue : MagickFalse; 00536 switch (image->blob->type) 00537 { 00538 case UndefinedStream: 00539 break; 00540 case FileStream: 00541 case StandardStream: 00542 { 00543 if (image->blob->synchronize != MagickFalse) 00544 { 00545 status=fflush(image->blob->file); 00546 status=fsync(fileno(image->blob->file)); 00547 } 00548 status=fclose(image->blob->file); 00549 break; 00550 } 00551 case PipeStream: 00552 { 00553 #if defined(MAGICKCORE_HAVE_PCLOSE) 00554 status=pclose(image->blob->file); 00555 #endif 00556 break; 00557 } 00558 case ZipStream: 00559 { 00560 #if defined(MAGICKCORE_ZLIB_DELEGATE) 00561 status=gzclose(image->blob->gzfile); 00562 #endif 00563 break; 00564 } 00565 case BZipStream: 00566 { 00567 #if defined(MAGICKCORE_BZLIB_DELEGATE) 00568 BZ2_bzclose(image->blob->bzfile); 00569 #endif 00570 break; 00571 } 00572 case FifoStream: 00573 break; 00574 case BlobStream: 00575 { 00576 if (image->blob->file != (FILE *) NULL) 00577 { 00578 if (image->blob->synchronize != MagickFalse) 00579 (void) fsync(fileno(image->blob->file)); 00580 status=fclose(image->blob->file); 00581 } 00582 break; 00583 } 00584 } 00585 (void) DetachBlob(image->blob); 00586 image->blob->status=status < 0 ? MagickTrue : MagickFalse; 00587 return(image->blob->status); 00588 } 00589 00590 /* 00591 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00592 % % 00593 % % 00594 % % 00595 + D e s t r o y B l o b % 00596 % % 00597 % % 00598 % % 00599 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00600 % 00601 % DestroyBlob() deallocates memory associated with a blob. 00602 % 00603 % The format of the DestroyBlob method is: 00604 % 00605 % void DestroyBlob(Image *image) 00606 % 00607 % A description of each parameter follows: 00608 % 00609 % o image: the image. 00610 % 00611 */ 00612 MagickExport void DestroyBlob(Image *image) 00613 { 00614 MagickBooleanType 00615 destroy; 00616 00617 assert(image != (Image *) NULL); 00618 assert(image->signature == MagickSignature); 00619 if (image->debug != MagickFalse) 00620 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 00621 assert(image->blob != (BlobInfo *) NULL); 00622 assert(image->blob->signature == MagickSignature); 00623 destroy=MagickFalse; 00624 LockSemaphoreInfo(image->blob->semaphore); 00625 image->blob->reference_count--; 00626 assert(image->blob->reference_count >= 0); 00627 if (image->blob->reference_count == 0) 00628 destroy=MagickTrue; 00629 UnlockSemaphoreInfo(image->blob->semaphore); 00630 if (destroy == MagickFalse) 00631 return; 00632 (void) CloseBlob(image); 00633 if (image->blob->mapped != MagickFalse) 00634 (void) UnmapBlob(image->blob->data,image->blob->length); 00635 if (image->blob->semaphore != (SemaphoreInfo *) NULL) 00636 DestroySemaphoreInfo(&image->blob->semaphore); 00637 image->blob->signature=(~MagickSignature); 00638 image->blob=(BlobInfo *) RelinquishMagickMemory(image->blob); 00639 } 00640 00641 /* 00642 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00643 % % 00644 % % 00645 % % 00646 + D e t a c h B l o b % 00647 % % 00648 % % 00649 % % 00650 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00651 % 00652 % DetachBlob() detaches a blob from the BlobInfo structure. 00653 % 00654 % The format of the DetachBlob method is: 00655 % 00656 % unsigned char *DetachBlob(BlobInfo *blob_info) 00657 % 00658 % A description of each parameter follows: 00659 % 00660 % o blob_info: Specifies a pointer to a BlobInfo structure. 00661 % 00662 */ 00663 MagickExport unsigned char *DetachBlob(BlobInfo *blob_info) 00664 { 00665 unsigned char 00666 *data; 00667 00668 assert(blob_info != (BlobInfo *) NULL); 00669 if (blob_info->debug != MagickFalse) 00670 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 00671 if (blob_info->mapped != MagickFalse) 00672 (void) UnmapBlob(blob_info->data,blob_info->length); 00673 blob_info->mapped=MagickFalse; 00674 blob_info->length=0; 00675 blob_info->offset=0; 00676 blob_info->eof=MagickFalse; 00677 blob_info->exempt=MagickFalse; 00678 blob_info->type=UndefinedStream; 00679 blob_info->file=(FILE *) NULL; 00680 data=blob_info->data; 00681 blob_info->data=(unsigned char *) NULL; 00682 blob_info->stream=(StreamHandler) NULL; 00683 return(data); 00684 } 00685 00686 /* 00687 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00688 % % 00689 % % 00690 % % 00691 + D i s c a r d B l o b B y t e s % 00692 % % 00693 % % 00694 % % 00695 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00696 % 00697 % DiscardBlobBytes() discards bytes in a blob. 00698 % 00699 % The format of the DiscardBlobBytes method is: 00700 % 00701 % MagickBooleanType DiscardBlobBytes(Image *image,const size_t length) 00702 % 00703 % A description of each parameter follows. 00704 % 00705 % o image: the image. 00706 % 00707 % o length: the number of bytes to skip. 00708 % 00709 */ 00710 00711 static inline const unsigned char *ReadBlobStream(Image *image, 00712 const size_t length,unsigned char *data,ssize_t *count) 00713 { 00714 assert(count != (ssize_t *) NULL); 00715 assert(image->blob != (BlobInfo *) NULL); 00716 if (image->blob->type != BlobStream) 00717 { 00718 *count=ReadBlob(image,length,data); 00719 return(data); 00720 } 00721 if (image->blob->offset >= (MagickOffsetType) image->blob->length) 00722 { 00723 *count=0; 00724 image->blob->eof=MagickTrue; 00725 return(data); 00726 } 00727 data=image->blob->data+image->blob->offset; 00728 *count=(ssize_t) MagickMin(length,(MagickSizeType) (image->blob->length- 00729 image->blob->offset)); 00730 image->blob->offset+=(*count); 00731 if (*count != (ssize_t) length) 00732 image->blob->eof=MagickTrue; 00733 return(data); 00734 } 00735 00736 MagickExport MagickBooleanType DiscardBlobBytes(Image *image, 00737 const MagickSizeType length) 00738 { 00739 register MagickOffsetType 00740 i; 00741 00742 size_t 00743 quantum; 00744 00745 ssize_t 00746 count; 00747 00748 unsigned char 00749 buffer[16384]; 00750 00751 assert(image != (Image *) NULL); 00752 assert(image->signature == MagickSignature); 00753 count=0; 00754 for (i=0; i < (MagickOffsetType) length; i+=count) 00755 { 00756 quantum=(size_t) MagickMin(length-i,sizeof(buffer)); 00757 (void) ReadBlobStream(image,quantum,buffer,&count); 00758 if (count <= 0) 00759 { 00760 count=0; 00761 if (errno != EINTR) 00762 break; 00763 } 00764 } 00765 return(i < (MagickOffsetType) length ? MagickFalse : MagickTrue); 00766 } 00767 00768 /* 00769 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00770 % % 00771 % % 00772 % % 00773 + D u p l i c a t e s B l o b % 00774 % % 00775 % % 00776 % % 00777 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00778 % 00779 % DuplicateBlob() duplicates a blob descriptor. 00780 % 00781 % The format of the DuplicateBlob method is: 00782 % 00783 % void DuplicateBlob(Image *image,const Image *duplicate) 00784 % 00785 % A description of each parameter follows: 00786 % 00787 % o image: the image. 00788 % 00789 % o duplicate: the duplicate image. 00790 % 00791 */ 00792 MagickExport void DuplicateBlob(Image *image,const Image *duplicate) 00793 { 00794 assert(image != (Image *) NULL); 00795 assert(image->signature == MagickSignature); 00796 if (image->debug != MagickFalse) 00797 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 00798 assert(duplicate != (Image *) NULL); 00799 assert(duplicate->signature == MagickSignature); 00800 DestroyBlob(image); 00801 image->blob=ReferenceBlob(duplicate->blob); 00802 } 00803 00804 /* 00805 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00806 % % 00807 % % 00808 % % 00809 + E O F B l o b % 00810 % % 00811 % % 00812 % % 00813 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00814 % 00815 % EOFBlob() returns a non-zero value when EOF has been detected reading from 00816 % a blob or file. 00817 % 00818 % The format of the EOFBlob method is: 00819 % 00820 % int EOFBlob(const Image *image) 00821 % 00822 % A description of each parameter follows: 00823 % 00824 % o image: the image. 00825 % 00826 */ 00827 MagickExport int EOFBlob(const Image *image) 00828 { 00829 assert(image != (Image *) NULL); 00830 assert(image->signature == MagickSignature); 00831 if (image->debug != MagickFalse) 00832 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 00833 assert(image->blob != (BlobInfo *) NULL); 00834 assert(image->blob->type != UndefinedStream); 00835 switch (image->blob->type) 00836 { 00837 case UndefinedStream: 00838 break; 00839 case FileStream: 00840 case StandardStream: 00841 case PipeStream: 00842 { 00843 image->blob->eof=feof(image->blob->file) != 0 ? MagickTrue : MagickFalse; 00844 break; 00845 } 00846 case ZipStream: 00847 { 00848 image->blob->eof=MagickFalse; 00849 break; 00850 } 00851 case BZipStream: 00852 { 00853 #if defined(MAGICKCORE_BZLIB_DELEGATE) 00854 int 00855 status; 00856 00857 status=0; 00858 (void) BZ2_bzerror(image->blob->bzfile,&status); 00859 image->blob->eof=status == BZ_UNEXPECTED_EOF ? MagickTrue : MagickFalse; 00860 #endif 00861 break; 00862 } 00863 case FifoStream: 00864 { 00865 image->blob->eof=MagickFalse; 00866 break; 00867 } 00868 case BlobStream: 00869 break; 00870 } 00871 return((int) image->blob->eof); 00872 } 00873 00874 /* 00875 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00876 % % 00877 % % 00878 % % 00879 + F i l e T o B l o b % 00880 % % 00881 % % 00882 % % 00883 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00884 % 00885 % FileToBlob() returns the contents of a file as a buffer terminated with 00886 % the '\0' character. The length of the buffer (not including the extra 00887 % terminating '\0' character) is returned via the 'length' parameter. Free 00888 % the buffer with RelinquishMagickMemory(). 00889 % 00890 % The format of the FileToBlob method is: 00891 % 00892 % unsigned char *FileToBlob(const char *filename,const size_t extent, 00893 % size_t *length,ExceptionInfo *exception) 00894 % 00895 % A description of each parameter follows: 00896 % 00897 % o blob: FileToBlob() returns the contents of a file as a blob. If 00898 % an error occurs NULL is returned. 00899 % 00900 % o filename: the filename. 00901 % 00902 % o extent: The maximum length of the blob. 00903 % 00904 % o length: On return, this reflects the actual length of the blob. 00905 % 00906 % o exception: return any errors or warnings in this structure. 00907 % 00908 */ 00909 MagickExport unsigned char *FileToBlob(const char *filename,const size_t extent, 00910 size_t *length,ExceptionInfo *exception) 00911 { 00912 int 00913 file; 00914 00915 MagickOffsetType 00916 offset; 00917 00918 register size_t 00919 i; 00920 00921 ssize_t 00922 count; 00923 00924 unsigned char 00925 *blob; 00926 00927 void 00928 *map; 00929 00930 assert(filename != (const char *) NULL); 00931 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename); 00932 assert(exception != (ExceptionInfo *) NULL); 00933 *length=0; 00934 file=fileno(stdin); 00935 if (LocaleCompare(filename,"-") != 0) 00936 file=open_utf8(filename,O_RDONLY | O_BINARY,0); 00937 if (file == -1) 00938 { 00939 ThrowFileException(exception,BlobError,"UnableToOpenFile",filename); 00940 return((unsigned char *) NULL); 00941 } 00942 offset=(MagickOffsetType) lseek(file,0,SEEK_END); 00943 count=0; 00944 if ((offset < 0) || (offset != (MagickOffsetType) ((ssize_t) offset))) 00945 { 00946 size_t 00947 quantum; 00948 00949 struct stat 00950 file_info; 00951 00952 /* 00953 Stream is not seekable. 00954 */ 00955 quantum=(size_t) MagickMaxBufferExtent; 00956 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0)) 00957 quantum=(size_t) MagickMin((MagickSizeType) file_info.st_size, 00958 MagickMaxBufferExtent); 00959 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob)); 00960 for (i=0; blob != (unsigned char *) NULL; i+=count) 00961 { 00962 count=(ssize_t) read(file,blob+i,quantum); 00963 if (count <= 0) 00964 { 00965 count=0; 00966 if (errno != EINTR) 00967 break; 00968 } 00969 if (~(1UL*i) < (quantum+1)) 00970 { 00971 blob=(unsigned char *) RelinquishMagickMemory(blob); 00972 break; 00973 } 00974 blob=(unsigned char *) ResizeQuantumMemory(blob,i+quantum+1, 00975 sizeof(*blob)); 00976 if ((size_t) (i+count) >= extent) 00977 break; 00978 } 00979 if (LocaleCompare(filename,"-") != 0) 00980 file=close(file); 00981 if (blob == (unsigned char *) NULL) 00982 { 00983 (void) ThrowMagickException(exception,GetMagickModule(), 00984 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename); 00985 return((unsigned char *) NULL); 00986 } 00987 if (file == -1) 00988 { 00989 blob=(unsigned char *) RelinquishMagickMemory(blob); 00990 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename); 00991 return((unsigned char *) NULL); 00992 } 00993 *length=(size_t) MagickMin(i+count,extent); 00994 blob[*length]='\0'; 00995 return(blob); 00996 } 00997 *length=(size_t) MagickMin((MagickSizeType) offset,extent); 00998 blob=(unsigned char *) NULL; 00999 if (~(*length) >= (MaxTextExtent-1)) 01000 blob=(unsigned char *) AcquireQuantumMemory(*length+MaxTextExtent, 01001 sizeof(*blob)); 01002 if (blob == (unsigned char *) NULL) 01003 { 01004 file=close(file); 01005 (void) ThrowMagickException(exception,GetMagickModule(), 01006 ResourceLimitError,"MemoryAllocationFailed","`%s'",filename); 01007 return((unsigned char *) NULL); 01008 } 01009 map=MapBlob(file,ReadMode,0,*length); 01010 if (map != (unsigned char *) NULL) 01011 { 01012 (void) memcpy(blob,map,*length); 01013 (void) UnmapBlob(map,*length); 01014 } 01015 else 01016 { 01017 (void) lseek(file,0,SEEK_SET); 01018 for (i=0; i < *length; i+=count) 01019 { 01020 count=(ssize_t) read(file,blob+i,(size_t) MagickMin(*length-i, 01021 (MagickSizeType) SSIZE_MAX)); 01022 if (count <= 0) 01023 { 01024 count=0; 01025 if (errno != EINTR) 01026 break; 01027 } 01028 } 01029 if (i < *length) 01030 { 01031 file=close(file)-1; 01032 blob=(unsigned char *) RelinquishMagickMemory(blob); 01033 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename); 01034 return((unsigned char *) NULL); 01035 } 01036 } 01037 blob[*length]='\0'; 01038 if (LocaleCompare(filename,"-") != 0) 01039 file=close(file); 01040 if (file == -1) 01041 { 01042 blob=(unsigned char *) RelinquishMagickMemory(blob); 01043 ThrowFileException(exception,BlobError,"UnableToReadBlob",filename); 01044 } 01045 return(blob); 01046 } 01047 01048 /* 01049 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01050 % % 01051 % % 01052 % % 01053 % F i l e T o I m a g e % 01054 % % 01055 % % 01056 % % 01057 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01058 % 01059 % FileToImage() write the contents of a file to an image. 01060 % 01061 % The format of the FileToImage method is: 01062 % 01063 % MagickBooleanType FileToImage(Image *,const char *filename) 01064 % 01065 % A description of each parameter follows: 01066 % 01067 % o image: the image. 01068 % 01069 % o filename: the filename. 01070 % 01071 */ 01072 01073 static inline ssize_t WriteBlobStream(Image *image,const size_t length, 01074 const unsigned char *data) 01075 { 01076 MagickSizeType 01077 extent; 01078 01079 register unsigned char 01080 *q; 01081 01082 assert(image->blob != (BlobInfo *) NULL); 01083 if (image->blob->type != BlobStream) 01084 return(WriteBlob(image,length,data)); 01085 assert(image->blob->type != UndefinedStream); 01086 assert(data != (void *) NULL); 01087 extent=(MagickSizeType) (image->blob->offset+(MagickOffsetType) length); 01088 if (extent >= image->blob->extent) 01089 { 01090 image->blob->quantum<<=1; 01091 extent=image->blob->extent+image->blob->quantum+length; 01092 if (SetBlobExtent(image,extent) == MagickFalse) 01093 return(0); 01094 } 01095 q=image->blob->data+image->blob->offset; 01096 (void) memcpy(q,data,length); 01097 image->blob->offset+=length; 01098 if (image->blob->offset >= (MagickOffsetType) image->blob->length) 01099 image->blob->length=(size_t) image->blob->offset; 01100 return((ssize_t) length); 01101 } 01102 01103 MagickExport MagickBooleanType FileToImage(Image *image,const char *filename, 01104 ExceptionInfo *exception) 01105 { 01106 int 01107 file; 01108 01109 size_t 01110 length, 01111 quantum; 01112 01113 ssize_t 01114 count; 01115 01116 struct stat 01117 file_info; 01118 01119 unsigned char 01120 *blob; 01121 01122 assert(image != (const Image *) NULL); 01123 assert(image->signature == MagickSignature); 01124 assert(filename != (const char *) NULL); 01125 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename); 01126 file=open_utf8(filename,O_RDONLY | O_BINARY,0); 01127 if (file == -1) 01128 { 01129 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename); 01130 return(MagickFalse); 01131 } 01132 quantum=(size_t) MagickMaxBufferExtent; 01133 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0)) 01134 quantum=(size_t) MagickMin(file_info.st_size,MagickMaxBufferExtent); 01135 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob)); 01136 if (blob == (unsigned char *) NULL) 01137 { 01138 ThrowFileException(exception,ResourceLimitError,"MemoryAllocationFailed", 01139 filename); 01140 return(MagickFalse); 01141 } 01142 for ( ; ; ) 01143 { 01144 count=(ssize_t) read(file,blob,quantum); 01145 if (count <= 0) 01146 { 01147 count=0; 01148 if (errno != EINTR) 01149 break; 01150 } 01151 length=(size_t) count; 01152 count=WriteBlobStream(image,length,blob); 01153 if (count != (ssize_t) length) 01154 { 01155 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename); 01156 break; 01157 } 01158 } 01159 file=close(file); 01160 if (file == -1) 01161 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename); 01162 blob=(unsigned char *) RelinquishMagickMemory(blob); 01163 return(MagickTrue); 01164 } 01165 01166 /* 01167 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01168 % % 01169 % % 01170 % % 01171 + G e t B l o b E r r o r % 01172 % % 01173 % % 01174 % % 01175 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01176 % 01177 % GetBlobError() returns MagickTrue if the blob associated with the specified 01178 % image encountered an error. 01179 % 01180 % The format of the GetBlobError method is: 01181 % 01182 % MagickBooleanType GetBlobError(const Image *image) 01183 % 01184 % A description of each parameter follows: 01185 % 01186 % o image: the image. 01187 % 01188 */ 01189 MagickPrivate MagickBooleanType GetBlobError(const Image *image) 01190 { 01191 assert(image != (const Image *) NULL); 01192 assert(image->signature == MagickSignature); 01193 if (image->debug != MagickFalse) 01194 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 01195 return(image->blob->status); 01196 } 01197 01198 /* 01199 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01200 % % 01201 % % 01202 % % 01203 + G e t B l o b F i l e H a n d l e % 01204 % % 01205 % % 01206 % % 01207 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01208 % 01209 % GetBlobFileHandle() returns the file handle associated with the image blob. 01210 % 01211 % The format of the GetBlobFile method is: 01212 % 01213 % FILE *GetBlobFileHandle(const Image *image) 01214 % 01215 % A description of each parameter follows: 01216 % 01217 % o image: the image. 01218 % 01219 */ 01220 MagickExport FILE *GetBlobFileHandle(const Image *image) 01221 { 01222 assert(image != (const Image *) NULL); 01223 assert(image->signature == MagickSignature); 01224 return(image->blob->file); 01225 } 01226 01227 /* 01228 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01229 % % 01230 % % 01231 % % 01232 + G e t B l o b I n f o % 01233 % % 01234 % % 01235 % % 01236 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01237 % 01238 % GetBlobInfo() initializes the BlobInfo structure. 01239 % 01240 % The format of the GetBlobInfo method is: 01241 % 01242 % void GetBlobInfo(BlobInfo *blob_info) 01243 % 01244 % A description of each parameter follows: 01245 % 01246 % o blob_info: Specifies a pointer to a BlobInfo structure. 01247 % 01248 */ 01249 MagickPrivate void GetBlobInfo(BlobInfo *blob_info) 01250 { 01251 assert(blob_info != (BlobInfo *) NULL); 01252 (void) ResetMagickMemory(blob_info,0,sizeof(*blob_info)); 01253 blob_info->type=UndefinedStream; 01254 blob_info->quantum=(size_t) MagickMaxBlobExtent; 01255 blob_info->properties.st_mtime=time((time_t *) NULL); 01256 blob_info->properties.st_ctime=time((time_t *) NULL); 01257 blob_info->debug=IsEventLogging(); 01258 blob_info->reference_count=1; 01259 blob_info->semaphore=AllocateSemaphoreInfo(); 01260 blob_info->signature=MagickSignature; 01261 } 01262 01263 /* 01264 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01265 % % 01266 % % 01267 % % 01268 % G e t B l o b P r o p e r t i e s % 01269 % % 01270 % % 01271 % % 01272 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01273 % 01274 % GetBlobProperties() returns information about an image blob. 01275 % 01276 % The format of the GetBlobProperties method is: 01277 % 01278 % const struct stat *GetBlobProperties(const Image *image) 01279 % 01280 % A description of each parameter follows: 01281 % 01282 % o image: the image. 01283 % 01284 */ 01285 MagickPrivate const struct stat *GetBlobProperties(const Image *image) 01286 { 01287 assert(image != (Image *) NULL); 01288 assert(image->signature == MagickSignature); 01289 if (image->debug != MagickFalse) 01290 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 01291 return(&image->blob->properties); 01292 } 01293 01294 /* 01295 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01296 % % 01297 % % 01298 % % 01299 + G e t B l o b S i z e % 01300 % % 01301 % % 01302 % % 01303 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01304 % 01305 % GetBlobSize() returns the current length of the image file or blob; zero is 01306 % returned if the size cannot be determined. 01307 % 01308 % The format of the GetBlobSize method is: 01309 % 01310 % MagickSizeType GetBlobSize(const Image *image) 01311 % 01312 % A description of each parameter follows: 01313 % 01314 % o image: the image. 01315 % 01316 */ 01317 MagickExport MagickSizeType GetBlobSize(const Image *image) 01318 { 01319 MagickSizeType 01320 extent; 01321 01322 assert(image != (Image *) NULL); 01323 assert(image->signature == MagickSignature); 01324 if (image->debug != MagickFalse) 01325 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 01326 assert(image->blob != (BlobInfo *) NULL); 01327 extent=0; 01328 switch (image->blob->type) 01329 { 01330 case UndefinedStream: 01331 { 01332 extent=image->blob->size; 01333 break; 01334 } 01335 case FileStream: 01336 { 01337 if (fstat(fileno(image->blob->file),&image->blob->properties) == 0) 01338 extent=(MagickSizeType) image->blob->properties.st_size; 01339 break; 01340 } 01341 case StandardStream: 01342 case PipeStream: 01343 { 01344 extent=image->blob->size; 01345 break; 01346 } 01347 case ZipStream: 01348 case BZipStream: 01349 { 01350 MagickBooleanType 01351 status; 01352 01353 status=GetPathAttributes(image->filename,&image->blob->properties); 01354 if (status != MagickFalse) 01355 extent=(MagickSizeType) image->blob->properties.st_size; 01356 break; 01357 } 01358 case FifoStream: 01359 break; 01360 case BlobStream: 01361 { 01362 extent=(MagickSizeType) image->blob->length; 01363 break; 01364 } 01365 } 01366 return(extent); 01367 } 01368 01369 /* 01370 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01371 % % 01372 % % 01373 % % 01374 + G e t B l o b S t r e a m D a t a % 01375 % % 01376 % % 01377 % % 01378 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01379 % 01380 % GetBlobStreamData() returns the stream data for the image. 01381 % 01382 % The format of the GetBlobStreamData method is: 01383 % 01384 % unsigned char *GetBlobStreamData(const Image *image) 01385 % 01386 % A description of each parameter follows: 01387 % 01388 % o image: the image. 01389 % 01390 */ 01391 MagickExport unsigned char *GetBlobStreamData(const Image *image) 01392 { 01393 assert(image != (const Image *) NULL); 01394 assert(image->signature == MagickSignature); 01395 return(image->blob->data); 01396 } 01397 01398 /* 01399 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01400 % % 01401 % % 01402 % % 01403 + G e t B l o b S t r e a m H a n d l e r % 01404 % % 01405 % % 01406 % % 01407 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01408 % 01409 % GetBlobStreamHandler() returns the stream handler for the image. 01410 % 01411 % The format of the GetBlobStreamHandler method is: 01412 % 01413 % StreamHandler GetBlobStreamHandler(const Image *image) 01414 % 01415 % A description of each parameter follows: 01416 % 01417 % o image: the image. 01418 % 01419 */ 01420 MagickPrivate StreamHandler GetBlobStreamHandler(const Image *image) 01421 { 01422 assert(image != (const Image *) NULL); 01423 assert(image->signature == MagickSignature); 01424 if (image->debug != MagickFalse) 01425 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 01426 return(image->blob->stream); 01427 } 01428 01429 /* 01430 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01431 % % 01432 % % 01433 % % 01434 % I m a g e T o B l o b % 01435 % % 01436 % % 01437 % % 01438 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01439 % 01440 % ImageToBlob() implements direct to memory image formats. It returns the 01441 % image as a formatted blob and its length. The magick member of the Image 01442 % structure determines the format of the returned blob (GIF, JPEG, PNG, 01443 % etc.). This method is the equivalent of WriteImage(), but writes the 01444 % formatted "file" to a memory buffer rather than to an actual file. 01445 % 01446 % The format of the ImageToBlob method is: 01447 % 01448 % unsigned char *ImageToBlob(const ImageInfo *image_info,Image *image, 01449 % size_t *length,ExceptionInfo *exception) 01450 % 01451 % A description of each parameter follows: 01452 % 01453 % o image_info: the image info. 01454 % 01455 % o image: the image. 01456 % 01457 % o length: This pointer to a size_t integer sets the initial length of the 01458 % blob. On return, it reflects the actual length of the blob. 01459 % 01460 % o exception: return any errors or warnings in this structure. 01461 % 01462 */ 01463 MagickExport unsigned char *ImageToBlob(const ImageInfo *image_info, 01464 Image *image,size_t *length,ExceptionInfo *exception) 01465 { 01466 const MagickInfo 01467 *magick_info; 01468 01469 ImageInfo 01470 *blob_info; 01471 01472 MagickBooleanType 01473 status; 01474 01475 unsigned char 01476 *blob; 01477 01478 assert(image_info != (const ImageInfo *) NULL); 01479 assert(image_info->signature == MagickSignature); 01480 if (image_info->debug != MagickFalse) 01481 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", 01482 image_info->filename); 01483 assert(image != (Image *) NULL); 01484 assert(image->signature == MagickSignature); 01485 assert(exception != (ExceptionInfo *) NULL); 01486 *length=0; 01487 blob=(unsigned char *) NULL; 01488 blob_info=CloneImageInfo(image_info); 01489 blob_info->adjoin=MagickFalse; 01490 (void) SetImageInfo(blob_info,1,exception); 01491 if (*blob_info->magick != '\0') 01492 (void) CopyMagickString(image->magick,blob_info->magick,MaxTextExtent); 01493 magick_info=GetMagickInfo(image->magick,exception); 01494 if (magick_info == (const MagickInfo *) NULL) 01495 { 01496 (void) ThrowMagickException(exception,GetMagickModule(), 01497 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'", 01498 image->filename); 01499 return(blob); 01500 } 01501 (void) CopyMagickString(blob_info->magick,image->magick,MaxTextExtent); 01502 if (GetMagickBlobSupport(magick_info) != MagickFalse) 01503 { 01504 /* 01505 Native blob support for this image format. 01506 */ 01507 blob_info->length=0; 01508 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent, 01509 sizeof(unsigned char)); 01510 if (blob_info->blob == (void *) NULL) 01511 (void) ThrowMagickException(exception,GetMagickModule(), 01512 ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename); 01513 else 01514 { 01515 (void) CloseBlob(image); 01516 image->blob->exempt=MagickTrue; 01517 *image->filename='\0'; 01518 status=WriteImage(blob_info,image,exception); 01519 if ((status != MagickFalse) && (image->blob->length != 0)) 01520 { 01521 *length=image->blob->length; 01522 blob=DetachBlob(image->blob); 01523 blob=(unsigned char *) ResizeQuantumMemory(blob,*length, 01524 sizeof(*blob)); 01525 } 01526 } 01527 } 01528 else 01529 { 01530 char 01531 unique[MaxTextExtent]; 01532 01533 int 01534 file; 01535 01536 /* 01537 Write file to disk in blob image format. 01538 */ 01539 file=AcquireUniqueFileResource(unique); 01540 if (file == -1) 01541 { 01542 ThrowFileException(exception,BlobError,"UnableToWriteBlob", 01543 image_info->filename); 01544 } 01545 else 01546 { 01547 blob_info->file=fdopen(file,"wb"); 01548 if (blob_info->file != (FILE *) NULL) 01549 { 01550 (void) FormatLocaleString(image->filename,MaxTextExtent,"%s:%s", 01551 image->magick,unique); 01552 status=WriteImage(blob_info,image,exception); 01553 (void) fclose(blob_info->file); 01554 if (status != MagickFalse) 01555 blob=FileToBlob(image->filename,~0UL,length,exception); 01556 } 01557 (void) RelinquishUniqueFileResource(unique); 01558 } 01559 } 01560 blob_info=DestroyImageInfo(blob_info); 01561 return(blob); 01562 } 01563 01564 /* 01565 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01566 % % 01567 % % 01568 % % 01569 % I m a g e T o F i l e % 01570 % % 01571 % % 01572 % % 01573 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01574 % 01575 % ImageToFile() writes an image to a file. It returns MagickFalse if an error 01576 % occurs otherwise MagickTrue. 01577 % 01578 % The format of the ImageToFile method is: 01579 % 01580 % MagickBooleanType ImageToFile(Image *image,char *filename, 01581 % ExceptionInfo *exception) 01582 % 01583 % A description of each parameter follows: 01584 % 01585 % o image: the image. 01586 % 01587 % o filename: Write the image to this file. 01588 % 01589 % o exception: return any errors or warnings in this structure. 01590 % 01591 */ 01592 MagickExport MagickBooleanType ImageToFile(Image *image,char *filename, 01593 ExceptionInfo *exception) 01594 { 01595 int 01596 file; 01597 01598 register const unsigned char 01599 *p; 01600 01601 register size_t 01602 i; 01603 01604 size_t 01605 length, 01606 quantum; 01607 01608 ssize_t 01609 count; 01610 01611 struct stat 01612 file_info; 01613 01614 unsigned char 01615 *buffer; 01616 01617 assert(image != (Image *) NULL); 01618 assert(image->signature == MagickSignature); 01619 assert(image->blob != (BlobInfo *) NULL); 01620 assert(image->blob->type != UndefinedStream); 01621 if (image->debug != MagickFalse) 01622 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename); 01623 assert(filename != (const char *) NULL); 01624 if (*filename == '\0') 01625 file=AcquireUniqueFileResource(filename); 01626 else 01627 if (LocaleCompare(filename,"-") == 0) 01628 file=fileno(stdout); 01629 else 01630 file=open_utf8(filename,O_RDWR | O_CREAT | O_EXCL | O_BINARY,S_MODE); 01631 if (file == -1) 01632 { 01633 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename); 01634 return(MagickFalse); 01635 } 01636 quantum=(size_t) MagickMaxBufferExtent; 01637 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0)) 01638 quantum=(size_t) MagickMin((MagickSizeType) file_info.st_size, 01639 MagickMaxBufferExtent); 01640 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer)); 01641 if (buffer == (unsigned char *) NULL) 01642 { 01643 file=close(file)-1; 01644 (void) ThrowMagickException(exception,GetMagickModule(), 01645 ResourceLimitError,"MemoryAllocationError","`%s'",filename); 01646 return(MagickFalse); 01647 } 01648 length=0; 01649 p=ReadBlobStream(image,quantum,buffer,&count); 01650 for (i=0; count > 0; p=ReadBlobStream(image,quantum,buffer,&count)) 01651 { 01652 length=(size_t) count; 01653 for (i=0; i < length; i+=count) 01654 { 01655 count=write(file,p+i,(size_t) (length-i)); 01656 if (count <= 0) 01657 { 01658 count=0; 01659 if (errno != EINTR) 01660 break; 01661 } 01662 } 01663 if (i < length) 01664 break; 01665 } 01666 if (LocaleCompare(filename,"-") != 0) 01667 file=close(file); 01668 buffer=(unsigned char *) RelinquishMagickMemory(buffer); 01669 if ((file == -1) || (i < length)) 01670 { 01671 ThrowFileException(exception,BlobError,"UnableToWriteBlob",filename); 01672 return(MagickFalse); 01673 } 01674 return(MagickTrue); 01675 } 01676 01677 /* 01678 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01679 % % 01680 % % 01681 % % 01682 % I m a g e s T o B l o b % 01683 % % 01684 % % 01685 % % 01686 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01687 % 01688 % ImagesToBlob() implements direct to memory image formats. It returns the 01689 % image sequence as a blob and its length. The magick member of the ImageInfo 01690 % structure determines the format of the returned blob (GIF, JPEG, PNG, etc.) 01691 % 01692 % Note, some image formats do not permit multiple images to the same image 01693 % stream (e.g. JPEG). in this instance, just the first image of the 01694 % sequence is returned as a blob. 01695 % 01696 % The format of the ImagesToBlob method is: 01697 % 01698 % unsigned char *ImagesToBlob(const ImageInfo *image_info,Image *images, 01699 % size_t *length,ExceptionInfo *exception) 01700 % 01701 % A description of each parameter follows: 01702 % 01703 % o image_info: the image info. 01704 % 01705 % o images: the image list. 01706 % 01707 % o length: This pointer to a size_t integer sets the initial length of the 01708 % blob. On return, it reflects the actual length of the blob. 01709 % 01710 % o exception: return any errors or warnings in this structure. 01711 % 01712 */ 01713 MagickExport unsigned char *ImagesToBlob(const ImageInfo *image_info, 01714 Image *images,size_t *length,ExceptionInfo *exception) 01715 { 01716 const MagickInfo 01717 *magick_info; 01718 01719 ImageInfo 01720 *blob_info; 01721 01722 MagickBooleanType 01723 status; 01724 01725 unsigned char 01726 *blob; 01727 01728 assert(image_info != (const ImageInfo *) NULL); 01729 assert(image_info->signature == MagickSignature); 01730 if (image_info->debug != MagickFalse) 01731 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", 01732 image_info->filename); 01733 assert(images != (Image *) NULL); 01734 assert(images->signature == MagickSignature); 01735 assert(exception != (ExceptionInfo *) NULL); 01736 *length=0; 01737 blob=(unsigned char *) NULL; 01738 blob_info=CloneImageInfo(image_info); 01739 (void) SetImageInfo(blob_info,(unsigned int) GetImageListLength(images), 01740 exception); 01741 if (*blob_info->magick != '\0') 01742 (void) CopyMagickString(images->magick,blob_info->magick,MaxTextExtent); 01743 if (blob_info->adjoin == MagickFalse) 01744 { 01745 blob_info=DestroyImageInfo(blob_info); 01746 return(ImageToBlob(image_info,images,length,exception)); 01747 } 01748 magick_info=GetMagickInfo(images->magick,exception); 01749 if (magick_info == (const MagickInfo *) NULL) 01750 { 01751 (void) ThrowMagickException(exception,GetMagickModule(), 01752 MissingDelegateError,"NoDecodeDelegateForThisImageFormat","`%s'", 01753 images->filename); 01754 return(blob); 01755 } 01756 (void) CopyMagickString(blob_info->magick,images->magick,MaxTextExtent); 01757 if (GetMagickBlobSupport(magick_info) != MagickFalse) 01758 { 01759 /* 01760 Native blob support for this images format. 01761 */ 01762 blob_info->length=0; 01763 blob_info->blob=(void *) AcquireQuantumMemory(MagickMaxBlobExtent, 01764 sizeof(unsigned char)); 01765 if (blob_info->blob == (void *) NULL) 01766 (void) ThrowMagickException(exception,GetMagickModule(), 01767 ResourceLimitError,"MemoryAllocationFailed","`%s'",images->filename); 01768 else 01769 { 01770 images->blob->exempt=MagickTrue; 01771 *images->filename='\0'; 01772 status=WriteImages(blob_info,images,images->filename,exception); 01773 if ((status != MagickFalse) && (images->blob->length != 0)) 01774 { 01775 *length=images->blob->length; 01776 blob=DetachBlob(images->blob); 01777 blob=(unsigned char *) ResizeQuantumMemory(blob,*length, 01778 sizeof(*blob)); 01779 } 01780 } 01781 } 01782 else 01783 { 01784 char 01785 filename[MaxTextExtent], 01786 unique[MaxTextExtent]; 01787 01788 int 01789 file; 01790 01791 /* 01792 Write file to disk in blob images format. 01793 */ 01794 file=AcquireUniqueFileResource(unique); 01795 if (file == -1) 01796 { 01797 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob", 01798 image_info->filename); 01799 } 01800 else 01801 { 01802 blob_info->file=fdopen(file,"wb"); 01803 if (blob_info->file != (FILE *) NULL) 01804 { 01805 (void) FormatLocaleString(filename,MaxTextExtent,"%s:%s", 01806 images->magick,unique); 01807 status=WriteImages(blob_info,images,filename,exception); 01808 (void) fclose(blob_info->file); 01809 if (status != MagickFalse) 01810 blob=FileToBlob(images->filename,~0UL,length,exception); 01811 } 01812 (void) RelinquishUniqueFileResource(unique); 01813 } 01814 } 01815 blob_info=DestroyImageInfo(blob_info); 01816 return(blob); 01817 } 01818 /* 01819 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01820 % % 01821 % % 01822 % % 01823 % I n j e c t I m a g e B l o b % 01824 % % 01825 % % 01826 % % 01827 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01828 % 01829 % InjectImageBlob() injects the image with a copy of itself in the specified 01830 % format (e.g. inject JPEG into a PDF image). 01831 % 01832 % The format of the InjectImageBlob method is: 01833 % 01834 % MagickBooleanType InjectImageBlob(const ImageInfo *image_info, 01835 % Image *image,Image *inject_image,const char *format, 01836 % ExceptionInfo *exception) 01837 % 01838 % A description of each parameter follows: 01839 % 01840 % o image_info: the image info.. 01841 % 01842 % o image: the image. 01843 % 01844 % o inject_image: inject into the image stream. 01845 % 01846 % o format: the image format. 01847 % 01848 % o exception: return any errors or warnings in this structure. 01849 % 01850 */ 01851 MagickExport MagickBooleanType InjectImageBlob(const ImageInfo *image_info, 01852 Image *image,Image *inject_image,const char *format,ExceptionInfo *exception) 01853 { 01854 char 01855 filename[MaxTextExtent]; 01856 01857 FILE 01858 *unique_file; 01859 01860 Image 01861 *byte_image; 01862 01863 ImageInfo 01864 *write_info; 01865 01866 int 01867 file; 01868 01869 MagickBooleanType 01870 status; 01871 01872 register ssize_t 01873 i; 01874 01875 size_t 01876 quantum; 01877 01878 ssize_t 01879 count; 01880 01881 struct stat 01882 file_info; 01883 01884 unsigned char 01885 *buffer; 01886 01887 /* 01888 Write inject image to a temporary file. 01889 */ 01890 assert(image_info != (ImageInfo *) NULL); 01891 assert(image_info->signature == MagickSignature); 01892 assert(image != (Image *) NULL); 01893 assert(image->signature == MagickSignature); 01894 if (image->debug != MagickFalse) 01895 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 01896 assert(inject_image != (Image *) NULL); 01897 assert(inject_image->signature == MagickSignature); 01898 assert(exception != (ExceptionInfo *) NULL); 01899 unique_file=(FILE *) NULL; 01900 file=AcquireUniqueFileResource(filename); 01901 if (file != -1) 01902 unique_file=fdopen(file,"wb"); 01903 if ((file == -1) || (unique_file == (FILE *) NULL)) 01904 { 01905 (void) CopyMagickString(image->filename,filename,MaxTextExtent); 01906 ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile", 01907 image->filename); 01908 return(MagickFalse); 01909 } 01910 byte_image=CloneImage(inject_image,0,0,MagickFalse,exception); 01911 if (byte_image == (Image *) NULL) 01912 { 01913 (void) fclose(unique_file); 01914 (void) RelinquishUniqueFileResource(filename); 01915 return(MagickFalse); 01916 } 01917 (void) FormatLocaleString(byte_image->filename,MaxTextExtent,"%s:%s",format, 01918 filename); 01919 DestroyBlob(byte_image); 01920 byte_image->blob=CloneBlobInfo((BlobInfo *) NULL); 01921 write_info=CloneImageInfo(image_info); 01922 SetImageInfoFile(write_info,unique_file); 01923 status=WriteImage(write_info,byte_image,exception); 01924 write_info=DestroyImageInfo(write_info); 01925 byte_image=DestroyImage(byte_image); 01926 (void) fclose(unique_file); 01927 if (status == MagickFalse) 01928 { 01929 (void) RelinquishUniqueFileResource(filename); 01930 return(MagickFalse); 01931 } 01932 /* 01933 Inject into image stream. 01934 */ 01935 file=open_utf8(filename,O_RDONLY | O_BINARY,0); 01936 if (file == -1) 01937 { 01938 (void) RelinquishUniqueFileResource(filename); 01939 ThrowFileException(exception,FileOpenError,"UnableToOpenFile", 01940 image_info->filename); 01941 return(MagickFalse); 01942 } 01943 quantum=(size_t) MagickMaxBufferExtent; 01944 if ((fstat(file,&file_info) == 0) && (file_info.st_size != 0)) 01945 quantum=(size_t) MagickMin(file_info.st_size,MagickMaxBufferExtent); 01946 buffer=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*buffer)); 01947 if (buffer == (unsigned char *) NULL) 01948 { 01949 (void) RelinquishUniqueFileResource(filename); 01950 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", 01951 image->filename); 01952 } 01953 for (i=0; ; i+=count) 01954 { 01955 count=(ssize_t) read(file,buffer,quantum); 01956 if (count <= 0) 01957 { 01958 count=0; 01959 if (errno != EINTR) 01960 break; 01961 } 01962 status=WriteBlobStream(image,(size_t) count,buffer) == count ? MagickTrue : 01963 MagickFalse; 01964 } 01965 file=close(file); 01966 if (file == -1) 01967 ThrowFileException(exception,FileOpenError,"UnableToWriteBlob",filename); 01968 (void) RelinquishUniqueFileResource(filename); 01969 buffer=(unsigned char *) RelinquishMagickMemory(buffer); 01970 return(status); 01971 } 01972 01973 /* 01974 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01975 % % 01976 % % 01977 % % 01978 + I s B l o b E x e m p t % 01979 % % 01980 % % 01981 % % 01982 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 01983 % 01984 % IsBlobExempt() returns true if the blob is exempt. 01985 % 01986 % The format of the IsBlobExempt method is: 01987 % 01988 % MagickBooleanType IsBlobExempt(const Image *image) 01989 % 01990 % A description of each parameter follows: 01991 % 01992 % o image: the image. 01993 % 01994 */ 01995 MagickPrivate MagickBooleanType IsBlobExempt(const Image *image) 01996 { 01997 assert(image != (const Image *) NULL); 01998 assert(image->signature == MagickSignature); 01999 if (image->debug != MagickFalse) 02000 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 02001 return(image->blob->exempt); 02002 } 02003 02004 /* 02005 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 02006 % % 02007 % % 02008 % % 02009 + I s B l o b S e e k a b l e % 02010 % % 02011 % % 02012 % % 02013 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 02014 % 02015 % IsBlobSeekable() returns true if the blob is seekable. 02016 % 02017 % The format of the IsBlobSeekable method is: 02018 % 02019 % MagickBooleanType IsBlobSeekable(const Image *image) 02020 % 02021 % A description of each parameter follows: 02022 % 02023 % o image: the image. 02024 % 02025 */ 02026 MagickPrivate MagickBooleanType IsBlobSeekable(const Image *image) 02027 { 02028 MagickBooleanType 02029 seekable; 02030 02031 assert(image != (const Image *) NULL); 02032 assert(image->signature == MagickSignature); 02033 if (image->debug != MagickFalse) 02034 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 02035 switch (image->blob->type) 02036 { 02037 case FileStream: 02038 case BlobStream: 02039 case ZipStream: 02040 { 02041 seekable=MagickTrue; 02042 break; 02043 } 02044 default: 02045 { 02046 seekable=MagickFalse; 02047 break; 02048 } 02049 } 02050 return(seekable); 02051 } 02052 02053 /* 02054 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 02055 % % 02056 % % 02057 % % 02058 + I s B l o b T e m p o r a r y % 02059 % % 02060 % % 02061 % % 02062 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 02063 % 02064 % IsBlobTemporary() returns true if the blob is temporary. 02065 % 02066 % The format of the IsBlobTemporary method is: 02067 % 02068 % MagickBooleanType IsBlobTemporary(const Image *image) 02069 % 02070 % A description of each parameter follows: 02071 % 02072 % o image: the image. 02073 % 02074 */ 02075 MagickPrivate MagickBooleanType IsBlobTemporary(const Image *image) 02076 { 02077 assert(image != (const Image *) NULL); 02078 assert(image->signature == MagickSignature); 02079 if (image->debug != MagickFalse) 02080 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 02081 return(image->blob->temporary); 02082 } 02083 02084 /* 02085 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 02086 % % 02087 % % 02088 % % 02089 + M a p B l o b % 02090 % % 02091 % % 02092 % % 02093 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 02094 % 02095 % MapBlob() creates a mapping from a file to a binary large object. 02096 % 02097 % The format of the MapBlob method is: 02098 % 02099 % unsigned char *MapBlob(int file,const MapMode mode, 02100 % const MagickOffsetType offset,const size_t length) 02101 % 02102 % A description of each parameter follows: 02103 % 02104 % o file: map this file descriptor. 02105 % 02106 % o mode: ReadMode, WriteMode, or IOMode. 02107 % 02108 % o offset: starting at this offset within the file. 02109 % 02110 % o length: the length of the mapping is returned in this pointer. 02111 % 02112 */ 02113 MagickExport unsigned char *MapBlob(int file,const MapMode mode, 02114 const MagickOffsetType offset,const size_t length) 02115 { 02116 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO) 02117 int 02118 flags, 02119 protection; 02120 02121 unsigned char 02122 *map; 02123 02124 /* 02125 Map file. 02126 */ 02127 flags=0; 02128 if (file == -1) 02129 #if defined(MAP_ANONYMOUS) 02130 flags|=MAP_ANONYMOUS; 02131 #else 02132 return((unsigned char *) NULL); 02133 #endif 02134 switch (mode) 02135 { 02136 case ReadMode: 02137 default: 02138 { 02139 protection=PROT_READ; 02140 flags|=MAP_PRIVATE; 02141 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file, 02142 (off_t) offset); 02143 break; 02144 } 02145 case WriteMode: 02146 { 02147 protection=PROT_WRITE; 02148 flags|=MAP_SHARED; 02149 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file, 02150 (off_t) offset); 02151 #if defined(MAGICKCORE_HAVE_POSIX_MADVISE) 02152 (void) posix_madvise(map,length,POSIX_MADV_SEQUENTIAL | 02153 POSIX_MADV_WILLNEED); 02154 #endif 02155 break; 02156 } 02157 case IOMode: 02158 { 02159 protection=PROT_READ | PROT_WRITE; 02160 flags|=MAP_SHARED; 02161 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file, 02162 (off_t) offset); 02163 break; 02164 } 02165 } 02166 if (map == (unsigned char *) MAP_FAILED) 02167 return((unsigned char *) NULL); 02168 return(map); 02169 #else 02170 (void) file; 02171 (void) mode; 02172 (void) offset; 02173 (void) length; 02174 return((unsigned char *) NULL); 02175 #endif 02176 } 02177 02178 /* 02179 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 02180 % % 02181 % % 02182 % % 02183 + M S B O r d e r L o n g % 02184 % % 02185 % % 02186 % % 02187 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 02188 % 02189 % MSBOrderLong() converts a least-significant byte first buffer of integers to 02190 % most-significant byte first. 02191 % 02192 % The format of the MSBOrderLong method is: 02193 % 02194 % void MSBOrderLong(unsigned char *buffer,const size_t length) 02195 % 02196 % A description of each parameter follows. 02197 % 02198 % o buffer: Specifies a pointer to a buffer of integers. 02199 % 02200 % o length: Specifies the length of the buffer. 02201 % 02202 */ 02203 MagickExport void MSBOrderLong(unsigned char *buffer,const size_t length) 02204 { 02205 int 02206 c; 02207 02208 register unsigned char 02209 *p, 02210 *q; 02211 02212 assert(buffer != (unsigned char *) NULL); 02213 q=buffer+length; 02214 while (buffer < q) 02215 { 02216 p=buffer+3; 02217 c=(int) (*p); 02218 *p=(*buffer); 02219 *buffer++=(unsigned char) c; 02220 p=buffer+1; 02221 c=(int) (*p); 02222 *p=(*buffer); 02223 *buffer++=(unsigned char) c; 02224 buffer+=2; 02225 } 02226 } 02227 02228 /* 02229 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 02230 % % 02231 % % 02232 % % 02233 + M S B O r d e r S h o r t % 02234 % % 02235 % % 02236 % % 02237 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 02238 % 02239 % MSBOrderShort() converts a least-significant byte first buffer of integers 02240 % to most-significant byte first. 02241 % 02242 % The format of the MSBOrderShort method is: 02243 % 02244 % void MSBOrderShort(unsigned char *p,const size_t length) 02245 % 02246 % A description of each parameter follows. 02247 % 02248 % o p: Specifies a pointer to a buffer of integers. 02249 % 02250 % o length: Specifies the length of the buffer. 02251 % 02252 */ 02253 MagickExport void MSBOrderShort(unsigned char *p,const size_t length) 02254 { 02255 int 02256 c; 02257 02258 register unsigned char 02259 *q; 02260 02261 assert(p != (unsigned char *) NULL); 02262 q=p+length; 02263 while (p < q) 02264 { 02265 c=(int) (*p); 02266 *p=(*(p+1)); 02267 p++; 02268 *p++=(unsigned char) c; 02269 } 02270 } 02271 02272 /* 02273 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 02274 % % 02275 % % 02276 % % 02277 + O p e n B l o b % 02278 % % 02279 % % 02280 % % 02281 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 02282 % 02283 % OpenBlob() opens a file associated with the image. A file name of '-' sets 02284 % the file to stdin for type 'r' and stdout for type 'w'. If the filename 02285 % suffix is '.gz' or '.Z', the image is decompressed for type 'r' and 02286 % compressed for type 'w'. If the filename prefix is '|', it is piped to or 02287 % from a system command. 02288 % 02289 % The format of the OpenBlob method is: 02290 % 02291 % MagickBooleanType OpenBlob(const ImageInfo *image_info,Image *image, 02292 % const BlobMode mode,ExceptionInfo *exception) 02293 % 02294 % A description of each parameter follows: 02295 % 02296 % o image_info: the image info. 02297 % 02298 % o image: the image. 02299 % 02300 % o mode: the mode for opening the file. 02301 % 02302 */ 02303 MagickExport MagickBooleanType OpenBlob(const ImageInfo *image_info, 02304 Image *image,const BlobMode mode,ExceptionInfo *exception) 02305 { 02306 char 02307 extension[MaxTextExtent], 02308 filename[MaxTextExtent]; 02309 02310 const char 02311 *type; 02312 02313 MagickBooleanType 02314 status; 02315 02316 PolicyRights 02317 rights; 02318 02319 assert(image_info != (ImageInfo *) NULL); 02320 assert(image_info->signature == MagickSignature); 02321 if (image_info->debug != MagickFalse) 02322 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", 02323 image_info->filename); 02324 assert(image != (Image *) NULL); 02325 assert(image->signature == MagickSignature); 02326 if (image_info->blob != (void *) NULL) 02327 { 02328 if (image_info->stream != (StreamHandler) NULL) 02329 image->blob->stream=(StreamHandler) image_info->stream; 02330 AttachBlob(image->blob,image_info->blob,image_info->length); 02331 return(MagickTrue); 02332 } 02333 (void) DetachBlob(image->blob); 02334 switch (mode) 02335 { 02336 default: type="r"; break; 02337 case ReadBlobMode: type="r"; break; 02338 case ReadBinaryBlobMode: type="rb"; break; 02339 case WriteBlobMode: type="w"; break; 02340 case WriteBinaryBlobMode: type="w+b"; break; 02341 case AppendBlobMode: type="a"; break; 02342 case AppendBinaryBlobMode: type="a+b"; break; 02343 } 02344 if (*type != 'r') 02345 image->blob->synchronize=image_info->synchronize; 02346 if (image_info->stream != (StreamHandler) NULL) 02347 { 02348 image->blob->stream=(StreamHandler) image_info->stream; 02349 if (*type == 'w') 02350 { 02351 image->blob->type=FifoStream; 02352 return(MagickTrue); 02353 } 02354 } 02355 /* 02356 Open image file. 02357 */ 02358 *filename='\0'; 02359 (void) CopyMagickString(filename,image->filename,MaxTextExtent); 02360 rights=ReadPolicyRights; 02361 if (*type == 'w') 02362 rights=WritePolicyRights; 02363 if (IsRightsAuthorized(PathPolicyDomain,rights,filename) == MagickFalse) 02364 { 02365 errno=EPERM; 02366 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError, 02367 "NotAuthorized","`%s'",filename); 02368 return(MagickFalse); 02369 } 02370 if ((LocaleCompare(filename,"-") == 0) || 02371 ((*filename == '\0') && (image_info->file == (FILE *) NULL))) 02372 { 02373 image->blob->file=(*type == 'r') ? stdin : stdout; 02374 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__) 02375 if (strchr(type,'b') != (char *) NULL) 02376 setmode(_fileno(image->blob->file),_O_BINARY); 02377 #endif 02378 image->blob->type=StandardStream; 02379 image->blob->exempt=MagickTrue; 02380 return(MagickTrue); 02381 } 02382 if (LocaleNCompare(filename,"fd:",3) == 0) 02383 { 02384 char 02385 mode[MaxTextExtent]; 02386 02387 *mode=(*type); 02388 mode[1]='\0'; 02389 image->blob->file=fdopen(StringToLong(filename+3),mode); 02390 #if defined(MAGICKCORE_WINDOWS_SUPPORT) || defined(__OS2__) 02391 if (strchr(type,'b') != (char *) NULL) 02392 setmode(_fileno(image->blob->file),_O_BINARY); 02393 #endif 02394 image->blob->type=StandardStream; 02395 image->blob->exempt=MagickTrue; 02396 return(MagickTrue); 02397 } 02398 #if defined(MAGICKCORE_HAVE_POPEN) 02399 if (*filename == '|') 02400 { 02401 char 02402 mode[MaxTextExtent]; 02403 02404 /* 02405 Pipe image to or from a system command. 02406 */ 02407 #if defined(SIGPIPE) 02408 if (*type == 'w') 02409 (void) signal(SIGPIPE,SIG_IGN); 02410 #endif 02411 *mode=(*type); 02412 mode[1]='\0'; 02413 image->blob->file=(FILE *) popen_utf8(filename+1,mode); 02414 if (image->blob->file == (FILE *) NULL) 02415 { 02416 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename); 02417 return(MagickFalse); 02418 } 02419 image->blob->type=PipeStream; 02420 image->blob->exempt=MagickTrue; 02421 return(MagickTrue); 02422 } 02423 #endif 02424 status=GetPathAttributes(filename,&image->blob->properties); 02425 #if defined(S_ISFIFO) 02426 if ((status == MagickTrue) && S_ISFIFO(image->blob->properties.st_mode)) 02427 { 02428 image->blob->file=(FILE *) fopen_utf8(filename,type); 02429 if (image->blob->file == (FILE *) NULL) 02430 { 02431 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename); 02432 return(MagickFalse); 02433 } 02434 image->blob->type=FileStream; 02435 image->blob->exempt=MagickTrue; 02436 return(MagickTrue); 02437 } 02438 #endif 02439 GetPathComponent(image->filename,ExtensionPath,extension); 02440 if (*type == 'w') 02441 { 02442 (void) CopyMagickString(filename,image->filename,MaxTextExtent); 02443 if ((image_info->adjoin == MagickFalse) || 02444 (strchr(filename,'%') != (char *) NULL)) 02445 { 02446 /* 02447 Form filename for multi-part images. 02448 */ 02449 (void) InterpretImageFilename(image_info,image,image->filename,(int) 02450 image->scene,filename,exception); 02451 if ((LocaleCompare(filename,image->filename) == 0) && 02452 ((GetPreviousImageInList(image) != (Image *) NULL) || 02453 (GetNextImageInList(image) != (Image *) NULL))) 02454 { 02455 char 02456 path[MaxTextExtent]; 02457 02458 GetPathComponent(image->filename,RootPath,path); 02459 if (*extension == '\0') 02460 (void) FormatLocaleString(filename,MaxTextExtent,"%s-%.20g", 02461 path,(double) image->scene); 02462 else 02463 (void) FormatLocaleString(filename,MaxTextExtent,"%s-%.20g.%s", 02464 path,(double) image->scene,extension); 02465 } 02466 (void) CopyMagickString(image->filename,filename,MaxTextExtent); 02467 #if defined(macintosh) 02468 SetApplicationType(filename,image_info->magick,'8BIM'); 02469 #endif 02470 } 02471 } 02472 if (image_info->file != (FILE *) NULL) 02473 { 02474 image->blob->file=image_info->file; 02475 image->blob->type=FileStream; 02476 image->blob->exempt=MagickTrue; 02477 } 02478 else 02479 if (*type == 'r') 02480 { 02481 image->blob->file=(FILE *) fopen_utf8(filename,type); 02482 if (image->blob->file != (FILE *) NULL) 02483 { 02484 size_t 02485 count; 02486 02487 unsigned char 02488 magick[3]; 02489 02490 image->blob->type=FileStream; 02491 #if defined(MAGICKCORE_HAVE_SETVBUF) 02492 (void) setvbuf(image->blob->file,(char *) NULL,(int) _IOFBF,16384); 02493 #endif 02494 (void) ResetMagickMemory(magick,0,sizeof(magick)); 02495 count=fread(magick,1,sizeof(magick),image->blob->file); 02496 (void) rewind(image->blob->file); 02497 (void) LogMagickEvent(BlobEvent,GetMagickModule(), 02498 " read %.20g magic header bytes",(double) count); 02499 #if defined(MAGICKCORE_ZLIB_DELEGATE) 02500 if (((int) magick[0] == 0x1F) && ((int) magick[1] == 0x8B) && 02501 ((int) magick[2] == 0x08)) 02502 { 02503 (void) fclose(image->blob->file); 02504 image->blob->gzfile=gzopen(filename,type); 02505 if (image->blob->gzfile != (gzFile) NULL) 02506 image->blob->type=ZipStream; 02507 } 02508 #endif 02509 #if defined(MAGICKCORE_BZLIB_DELEGATE) 02510 if (strncmp((char *) magick,"BZh",3) == 0) 02511 { 02512 (void) fclose(image->blob->file); 02513 image->blob->bzfile=BZ2_bzopen(filename,type); 02514 if (image->blob->bzfile != (BZFILE *) NULL) 02515 image->blob->type=BZipStream; 02516 } 02517 #endif 02518 if (image->blob->type == FileStream) 02519 { 02520 const MagickInfo 02521 *magick_info; 02522 02523 ExceptionInfo 02524 *sans_exception; 02525 02526 struct stat 02527 *properties; 02528 02529 sans_exception=AcquireExceptionInfo(); 02530 magick_info=GetMagickInfo(image_info->magick,sans_exception); 02531 sans_exception=DestroyExceptionInfo(sans_exception); 02532 properties=(&image->blob->properties); 02533 if ((magick_info != (const MagickInfo *) NULL) && 02534 (GetMagickBlobSupport(magick_info) != MagickFalse) && 02535 (properties->st_size <= MagickMaxBufferExtent)) 02536 { 02537 size_t 02538 length; 02539 02540 void 02541 *blob; 02542 02543 length=(size_t) properties->st_size; 02544 blob=MapBlob(fileno(image->blob->file),ReadMode,0,length); 02545 if (blob != (void *) NULL) 02546 { 02547 /* 02548 Format supports blobs-- use memory-mapped I/O. 02549 */ 02550 if (image_info->file != (FILE *) NULL) 02551 image->blob->exempt=MagickFalse; 02552 else 02553 { 02554 (void) fclose(image->blob->file); 02555 image->blob->file=(FILE *) NULL; 02556 } 02557 AttachBlob(image->blob,blob,length); 02558 image->blob->mapped=MagickTrue; 02559 } 02560 } 02561 } 02562 } 02563 } 02564 else 02565 #if defined(MAGICKCORE_ZLIB_DELEGATE) 02566 if ((LocaleCompare(extension,"Z") == 0) || 02567 (LocaleCompare(extension,"gz") == 0) || 02568 (LocaleCompare(extension,"wmz") == 0) || 02569 (LocaleCompare(extension,"svgz") == 0)) 02570 { 02571 if (mode == WriteBinaryBlobMode) 02572 type="wb"; 02573 image->blob->gzfile=gzopen(filename,type); 02574 if (image->blob->gzfile != (gzFile) NULL) 02575 image->blob->type=ZipStream; 02576 } 02577 else 02578 #endif 02579 #if defined(MAGICKCORE_BZLIB_DELEGATE) 02580 if (LocaleCompare(extension,"bz2") == 0) 02581 { 02582 image->blob->bzfile=BZ2_bzopen(filename,type); 02583 if (image->blob->bzfile != (BZFILE *) NULL) 02584 image->blob->type=BZipStream; 02585 } 02586 else 02587 #endif 02588 { 02589 image->blob->file=(FILE *) fopen_utf8(filename,type); 02590 if (image->blob->file != (FILE *) NULL) 02591 { 02592 image->blob->type=FileStream; 02593 #if defined(MAGICKCORE_HAVE_SETVBUF) 02594 (void) setvbuf(image->blob->file,(char *) NULL,(int) _IOFBF, 02595 16384); 02596 #endif 02597 } 02598 } 02599 image->blob->status=MagickFalse; 02600 if (image->blob->type != UndefinedStream) 02601 image->blob->size=GetBlobSize(image); 02602 else 02603 { 02604 ThrowFileException(exception,BlobError,"UnableToOpenBlob",filename); 02605 return(MagickFalse); 02606 } 02607 return(MagickTrue); 02608 } 02609 02610 /* 02611 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 02612 % % 02613 % % 02614 % % 02615 + P i n g B l o b % 02616 % % 02617 % % 02618 % % 02619 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 02620 % 02621 % PingBlob() returns all the attributes of an image or image sequence except 02622 % for the pixels. It is much faster and consumes far less memory than 02623 % BlobToImage(). On failure, a NULL image is returned and exception 02624 % describes the reason for the failure. 02625 % 02626 % The format of the PingBlob method is: 02627 % 02628 % Image *PingBlob(const ImageInfo *image_info,const void *blob, 02629 % const size_t length,ExceptionInfo *exception) 02630 % 02631 % A description of each parameter follows: 02632 % 02633 % o image_info: the image info. 02634 % 02635 % o blob: the address of a character stream in one of the image formats 02636 % understood by ImageMagick. 02637 % 02638 % o length: This size_t integer reflects the length in bytes of the blob. 02639 % 02640 % o exception: return any errors or warnings in this structure. 02641 % 02642 */ 02643 02644 #if defined(__cplusplus) || defined(c_plusplus) 02645 extern "C" { 02646 #endif 02647 02648 static size_t PingStream(const Image *magick_unused(image), 02649 const void *magick_unused(pixels),const size_t columns) 02650 { 02651 return(columns); 02652 } 02653 02654 #if defined(__cplusplus) || defined(c_plusplus) 02655 } 02656 #endif 02657 02658 MagickExport Image *PingBlob(const ImageInfo *image_info,const void *blob, 02659 const size_t length,ExceptionInfo *exception) 02660 { 02661 Image 02662 *image; 02663 02664 ImageInfo 02665 *ping_info; 02666 02667 assert(image_info != (ImageInfo *) NULL); 02668 assert(image_info->signature == MagickSignature); 02669 if (image_info->debug != MagickFalse) 02670 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", 02671 image_info->filename); 02672 assert(exception != (ExceptionInfo *) NULL); 02673 if ((blob == (const void *) NULL) || (length == 0)) 02674 { 02675 (void) ThrowMagickException(exception,GetMagickModule(),BlobError, 02676 "UnrecognizedImageFormat","`%s'",image_info->magick); 02677 return((Image *) NULL); 02678 } 02679 ping_info=CloneImageInfo(image_info); 02680 ping_info->blob=(void *) AcquireQuantumMemory(length,sizeof(unsigned char)); 02681 if (ping_info->blob == (const void *) NULL) 02682 { 02683 (void) ThrowMagickException(exception,GetMagickModule(), 02684 ResourceLimitFatalError,"MemoryAllocationFailed","`%s'",""); 02685 return((Image *) NULL); 02686 } 02687 (void) memcpy(ping_info->blob,blob,length); 02688 ping_info->length=length; 02689 ping_info->ping=MagickTrue; 02690 image=ReadStream(ping_info,&PingStream,exception); 02691 ping_info->blob=(void *) RelinquishMagickMemory(ping_info->blob); 02692 ping_info=DestroyImageInfo(ping_info); 02693 return(image); 02694 } 02695 02696 /* 02697 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 02698 % % 02699 % % 02700 % % 02701 + R e a d B l o b % 02702 % % 02703 % % 02704 % % 02705 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 02706 % 02707 % ReadBlob() reads data from the blob or image file and returns it. It 02708 % returns the number of bytes read. 02709 % 02710 % The format of the ReadBlob method is: 02711 % 02712 % ssize_t ReadBlob(Image *image,const size_t length,unsigned char *data) 02713 % 02714 % A description of each parameter follows: 02715 % 02716 % o image: the image. 02717 % 02718 % o length: Specifies an integer representing the number of bytes to read 02719 % from the file. 02720 % 02721 % o data: Specifies an area to place the information requested from the 02722 % file. 02723 % 02724 */ 02725 MagickExport ssize_t ReadBlob(Image *image,const size_t length, 02726 unsigned char *data) 02727 { 02728 int 02729 c; 02730 02731 register unsigned char 02732 *q; 02733 02734 ssize_t 02735 count; 02736 02737 assert(image != (Image *) NULL); 02738 assert(image->signature == MagickSignature); 02739 assert(image->blob != (BlobInfo *) NULL); 02740 assert(image->blob->type != UndefinedStream); 02741 if (length == 0) 02742 return(0); 02743 assert(data != (void *) NULL); 02744 count=0; 02745 q=data; 02746 switch (image->blob->type) 02747 { 02748 case UndefinedStream: 02749 break; 02750 case FileStream: 02751 case StandardStream: 02752 case PipeStream: 02753 { 02754 switch (length) 02755 { 02756 default: 02757 { 02758 count=(ssize_t) fread(q,1,length,image->blob->file); 02759 break; 02760 } 02761 case 2: 02762 { 02763 c=getc(image->blob->file); 02764 if (c == EOF) 02765 break; 02766 *q++=(unsigned char) c; 02767 count++; 02768 } 02769 case 1: 02770 { 02771 c=getc(image->blob->file); 02772 if (c == EOF) 02773 break; 02774 *q++=(unsigned char) c; 02775 count++; 02776 } 02777 case 0: 02778 break; 02779 } 02780 break; 02781 } 02782 case ZipStream: 02783 { 02784 #if defined(MAGICKCORE_ZLIB_DELEGATE) 02785 switch (length) 02786 { 02787 default: 02788 { 02789 count=(ssize_t) gzread(image->blob->gzfile,q,(unsigned int) length); 02790 break; 02791 } 02792 case 2: 02793 { 02794 c=gzgetc(image->blob->gzfile); 02795 if (c == EOF) 02796 break; 02797 *q++=(unsigned char) c; 02798 count++; 02799 } 02800 case 1: 02801 { 02802 c=gzgetc(image->blob->gzfile); 02803 if (c == EOF) 02804 break; 02805 *q++=(unsigned char) c; 02806 count++; 02807 } 02808 case 0: 02809 break; 02810 } 02811 #endif 02812 break; 02813 } 02814 case BZipStream: 02815 { 02816 #if defined(MAGICKCORE_BZLIB_DELEGATE) 02817 count=(ssize_t) BZ2_bzread(image->blob->bzfile,q,(int) length); 02818 #endif 02819 break; 02820 } 02821 case FifoStream: 02822 break; 02823 case BlobStream: 02824 { 02825 register const unsigned char 02826 *p; 02827 02828 if (image->blob->offset >= (MagickOffsetType) image->blob->length) 02829 { 02830 image->blob->eof=MagickTrue; 02831 break; 02832 } 02833 p=image->blob->data+image->blob->offset; 02834 count=(ssize_t) MagickMin(length,image->blob->length-image->blob->offset); 02835 image->blob->offset+=count; 02836 if (count != (ssize_t) length) 02837 image->blob->eof=MagickTrue; 02838 (void) memcpy(q,p,(size_t) count); 02839 break; 02840 } 02841 } 02842 return(count); 02843 } 02844 02845 /* 02846 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 02847 % % 02848 % % 02849 % % 02850 + R e a d B l o b B y t e % 02851 % % 02852 % % 02853 % % 02854 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 02855 % 02856 % ReadBlobByte() reads a single byte from the image file and returns it. 02857 % 02858 % The format of the ReadBlobByte method is: 02859 % 02860 % int ReadBlobByte(Image *image) 02861 % 02862 % A description of each parameter follows. 02863 % 02864 % o image: the image. 02865 % 02866 */ 02867 MagickExport int ReadBlobByte(Image *image) 02868 { 02869 register const unsigned char 02870 *p; 02871 02872 ssize_t 02873 count; 02874 02875 unsigned char 02876 buffer[1]; 02877 02878 assert(image != (Image *) NULL); 02879 assert(image->signature == MagickSignature); 02880 p=ReadBlobStream(image,1,buffer,&count); 02881 if (count != 1) 02882 return(EOF); 02883 return((int) (*p)); 02884 } 02885 02886 /* 02887 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 02888 % % 02889 % % 02890 % % 02891 + R e a d B l o b D o u b l e % 02892 % % 02893 % % 02894 % % 02895 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 02896 % 02897 % ReadBlobDouble() reads a double value as a 64-bit quantity in the byte-order 02898 % specified by the endian member of the image structure. 02899 % 02900 % The format of the ReadBlobDouble method is: 02901 % 02902 % double ReadBlobDouble(Image *image) 02903 % 02904 % A description of each parameter follows. 02905 % 02906 % o image: the image. 02907 % 02908 */ 02909 MagickExport double ReadBlobDouble(Image *image) 02910 { 02911 union 02912 { 02913 MagickSizeType 02914 unsigned_value; 02915 02916 double 02917 double_value; 02918 } quantum; 02919 02920 quantum.double_value=0.0; 02921 quantum.unsigned_value=ReadBlobLongLong(image); 02922 return(quantum.double_value); 02923 } 02924 02925 /* 02926 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 02927 % % 02928 % % 02929 % % 02930 + R e a d B l o b F l o a t % 02931 % % 02932 % % 02933 % % 02934 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 02935 % 02936 % ReadBlobFloat() reads a float value as a 32-bit quantity in the byte-order 02937 % specified by the endian member of the image structure. 02938 % 02939 % The format of the ReadBlobFloat method is: 02940 % 02941 % float ReadBlobFloat(Image *image) 02942 % 02943 % A description of each parameter follows. 02944 % 02945 % o image: the image. 02946 % 02947 */ 02948 MagickExport float ReadBlobFloat(Image *image) 02949 { 02950 union 02951 { 02952 unsigned int 02953 unsigned_value; 02954 02955 float 02956 float_value; 02957 } quantum; 02958 02959 quantum.float_value=0.0; 02960 quantum.unsigned_value=ReadBlobLong(image); 02961 return(quantum.float_value); 02962 } 02963 02964 /* 02965 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 02966 % % 02967 % % 02968 % % 02969 + R e a d B l o b L o n g % 02970 % % 02971 % % 02972 % % 02973 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 02974 % 02975 % ReadBlobLong() reads a ssize_t value as a 32-bit quantity in the byte-order 02976 % specified by the endian member of the image structure. 02977 % 02978 % The format of the ReadBlobLong method is: 02979 % 02980 % unsigned int ReadBlobLong(Image *image) 02981 % 02982 % A description of each parameter follows. 02983 % 02984 % o image: the image. 02985 % 02986 */ 02987 MagickExport unsigned int ReadBlobLong(Image *image) 02988 { 02989 register const unsigned char 02990 *p; 02991 02992 ssize_t 02993 count; 02994 02995 unsigned char 02996 buffer[4]; 02997 02998 unsigned int 02999 value; 03000 03001 assert(image != (Image *) NULL); 03002 assert(image->signature == MagickSignature); 03003 *buffer='\0'; 03004 p=ReadBlobStream(image,4,buffer,&count); 03005 if (count != 4) 03006 return(0UL); 03007 if (image->endian == LSBEndian) 03008 { 03009 value=(unsigned int) (*p++); 03010 value|=((unsigned int) (*p++)) << 8; 03011 value|=((unsigned int) (*p++)) << 16; 03012 value|=((unsigned int) (*p++)) << 24; 03013 return(value); 03014 } 03015 value=((unsigned int) (*p++)) << 24; 03016 value|=((unsigned int) (*p++)) << 16; 03017 value|=((unsigned int) (*p++)) << 8; 03018 value|=((unsigned int) (*p++)); 03019 return(value); 03020 } 03021 03022 /* 03023 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 03024 % % 03025 % % 03026 % % 03027 + R e a d B l o b L o n g L o n g % 03028 % % 03029 % % 03030 % % 03031 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 03032 % 03033 % ReadBlobLongLong() reads a long long value as a 64-bit quantity in the 03034 % byte-order specified by the endian member of the image structure. 03035 % 03036 % The format of the ReadBlobLongLong method is: 03037 % 03038 % MagickSizeType ReadBlobLongLong(Image *image) 03039 % 03040 % A description of each parameter follows. 03041 % 03042 % o image: the image. 03043 % 03044 */ 03045 MagickExport MagickSizeType ReadBlobLongLong(Image *image) 03046 { 03047 MagickSizeType 03048 value; 03049 03050 register const unsigned char 03051 *p; 03052 03053 ssize_t 03054 count; 03055 03056 unsigned char 03057 buffer[8]; 03058 03059 assert(image != (Image *) NULL); 03060 assert(image->signature == MagickSignature); 03061 *buffer='\0'; 03062 p=ReadBlobStream(image,8,buffer,&count); 03063 if (count != 8) 03064 return(MagickULLConstant(0)); 03065 if (image->endian == LSBEndian) 03066 { 03067 value=(MagickSizeType) (*p++); 03068 value|=((MagickSizeType) (*p++)) << 8; 03069 value|=((MagickSizeType) (*p++)) << 16; 03070 value|=((MagickSizeType) (*p++)) << 24; 03071 value|=((MagickSizeType) (*p++)) << 32; 03072 value|=((MagickSizeType) (*p++)) << 40; 03073 value|=((MagickSizeType) (*p++)) << 48; 03074 value|=((MagickSizeType) (*p++)) << 56; 03075 return(value & MagickULLConstant(0xffffffffffffffff)); 03076 } 03077 value=((MagickSizeType) (*p++)) << 56; 03078 value|=((MagickSizeType) (*p++)) << 48; 03079 value|=((MagickSizeType) (*p++)) << 40; 03080 value|=((MagickSizeType) (*p++)) << 32; 03081 value|=((MagickSizeType) (*p++)) << 24; 03082 value|=((MagickSizeType) (*p++)) << 16; 03083 value|=((MagickSizeType) (*p++)) << 8; 03084 value|=((MagickSizeType) (*p++)); 03085 return(value & MagickULLConstant(0xffffffffffffffff)); 03086 } 03087 03088 /* 03089 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 03090 % % 03091 % % 03092 % % 03093 + R e a d B l o b S h o r t % 03094 % % 03095 % % 03096 % % 03097 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 03098 % 03099 % ReadBlobShort() reads a short value as a 16-bit quantity in the byte-order 03100 % specified by the endian member of the image structure. 03101 % 03102 % The format of the ReadBlobShort method is: 03103 % 03104 % unsigned short ReadBlobShort(Image *image) 03105 % 03106 % A description of each parameter follows. 03107 % 03108 % o image: the image. 03109 % 03110 */ 03111 MagickExport unsigned short ReadBlobShort(Image *image) 03112 { 03113 register const unsigned char 03114 *p; 03115 03116 register unsigned int 03117 value; 03118 03119 ssize_t 03120 count; 03121 03122 unsigned char 03123 buffer[2]; 03124 03125 assert(image != (Image *) NULL); 03126 assert(image->signature == MagickSignature); 03127 *buffer='\0'; 03128 p=ReadBlobStream(image,2,buffer,&count); 03129 if (count != 2) 03130 return((unsigned short) 0U); 03131 if (image->endian == LSBEndian) 03132 { 03133 value=(unsigned int) (*p++); 03134 value|=((unsigned int) (*p++)) << 8; 03135 return((unsigned short) (value & 0xffff)); 03136 } 03137 value=(unsigned int) ((*p++) << 8); 03138 value|=(unsigned int) (*p++); 03139 return((unsigned short) (value & 0xffff)); 03140 } 03141 03142 /* 03143 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 03144 % % 03145 % % 03146 % % 03147 + R e a d B l o b L S B L o n g % 03148 % % 03149 % % 03150 % % 03151 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 03152 % 03153 % ReadBlobLSBLong() reads a ssize_t value as a 32-bit quantity in 03154 % least-significant byte first order. 03155 % 03156 % The format of the ReadBlobLSBLong method is: 03157 % 03158 % unsigned int ReadBlobLSBLong(Image *image) 03159 % 03160 % A description of each parameter follows. 03161 % 03162 % o image: the image. 03163 % 03164 */ 03165 MagickExport unsigned int ReadBlobLSBLong(Image *image) 03166 { 03167 register const unsigned char 03168 *p; 03169 03170 register unsigned int 03171 value; 03172 03173 ssize_t 03174 count; 03175 03176 unsigned char 03177 buffer[4]; 03178 03179 assert(image != (Image *) NULL); 03180 assert(image->signature == MagickSignature); 03181 *buffer='\0'; 03182 p=ReadBlobStream(image,4,buffer,&count); 03183 if (count != 4) 03184 return(0U); 03185 value=(unsigned int) (*p++); 03186 value|=((unsigned int) (*p++)) << 8; 03187 value|=((unsigned int) (*p++)) << 16; 03188 value|=((unsigned int) (*p++)) << 24; 03189 return(value); 03190 } 03191 03192 /* 03193 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 03194 % % 03195 % % 03196 % % 03197 + R e a d B l o b L S B S h o r t % 03198 % % 03199 % % 03200 % % 03201 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 03202 % 03203 % ReadBlobLSBShort() reads a short value as a 16-bit quantity in 03204 % least-significant byte first order. 03205 % 03206 % The format of the ReadBlobLSBShort method is: 03207 % 03208 % unsigned short ReadBlobLSBShort(Image *image) 03209 % 03210 % A description of each parameter follows. 03211 % 03212 % o image: the image. 03213 % 03214 */ 03215 MagickExport unsigned short ReadBlobLSBShort(Image *image) 03216 { 03217 register const unsigned char 03218 *p; 03219 03220 register unsigned int 03221 value; 03222 03223 ssize_t 03224 count; 03225 03226 unsigned char 03227 buffer[2]; 03228 03229 assert(image != (Image *) NULL); 03230 assert(image->signature == MagickSignature); 03231 *buffer='\0'; 03232 p=ReadBlobStream(image,2,buffer,&count); 03233 if (count != 2) 03234 return((unsigned short) 0U); 03235 value=(unsigned int) (*p++); 03236 value|=((unsigned int) ((*p++)) << 8); 03237 return((unsigned short) (value & 0xffff)); 03238 } 03239 03240 /* 03241 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 03242 % % 03243 % % 03244 % % 03245 + R e a d B l o b M S B L o n g % 03246 % % 03247 % % 03248 % % 03249 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 03250 % 03251 % ReadBlobMSBLong() reads a ssize_t value as a 32-bit quantity in 03252 % most-significant byte first order. 03253 % 03254 % The format of the ReadBlobMSBLong method is: 03255 % 03256 % unsigned int ReadBlobMSBLong(Image *image) 03257 % 03258 % A description of each parameter follows. 03259 % 03260 % o image: the image. 03261 % 03262 */ 03263 MagickExport unsigned int ReadBlobMSBLong(Image *image) 03264 { 03265 register const unsigned char 03266 *p; 03267 03268 register unsigned int 03269 value; 03270 03271 ssize_t 03272 count; 03273 03274 unsigned char 03275 buffer[4]; 03276 03277 assert(image != (Image *) NULL); 03278 assert(image->signature == MagickSignature); 03279 *buffer='\0'; 03280 p=ReadBlobStream(image,4,buffer,&count); 03281 if (count != 4) 03282 return(0UL); 03283 value=((unsigned int) (*p++) << 24); 03284 value|=((unsigned int) (*p++) << 16); 03285 value|=((unsigned int) (*p++) << 8); 03286 value|=(unsigned int) (*p++); 03287 return(value); 03288 } 03289 03290 /* 03291 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 03292 % % 03293 % % 03294 % % 03295 + R e a d B l o b M S B L o n g L o n g % 03296 % % 03297 % % 03298 % % 03299 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 03300 % 03301 % ReadBlobMSBLongLong() reads a ssize_t value as a 64-bit quantity in 03302 % most-significant byte first order. 03303 % 03304 % The format of the ReadBlobMSBLongLong method is: 03305 % 03306 % unsigned int ReadBlobMSBLongLong(Image *image) 03307 % 03308 % A description of each parameter follows. 03309 % 03310 % o image: the image. 03311 % 03312 */ 03313 MagickExport MagickSizeType ReadBlobMSBLongLong(Image *image) 03314 { 03315 register const unsigned char 03316 *p; 03317 03318 register MagickSizeType 03319 value; 03320 03321 ssize_t 03322 count; 03323 03324 unsigned char 03325 buffer[8]; 03326 03327 assert(image != (Image *) NULL); 03328 assert(image->signature == MagickSignature); 03329 *buffer='\0'; 03330 p=ReadBlobStream(image,8,buffer,&count); 03331 if (count != 8) 03332 return(MagickULLConstant(0)); 03333 value=((MagickSizeType) (*p++)) << 56; 03334 value|=((MagickSizeType) (*p++)) << 48; 03335 value|=((MagickSizeType) (*p++)) << 40; 03336 value|=((MagickSizeType) (*p++)) << 32; 03337 value|=((MagickSizeType) (*p++)) << 24; 03338 value|=((MagickSizeType) (*p++)) << 16; 03339 value|=((MagickSizeType) (*p++)) << 8; 03340 value|=((MagickSizeType) (*p++)); 03341 return(value & MagickULLConstant(0xffffffffffffffff)); 03342 } 03343 03344 /* 03345 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 03346 % % 03347 % % 03348 % % 03349 + R e a d B l o b M S B S h o r t % 03350 % % 03351 % % 03352 % % 03353 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 03354 % 03355 % ReadBlobMSBShort() reads a short value as a 16-bit quantity in 03356 % most-significant byte first order. 03357 % 03358 % The format of the ReadBlobMSBShort method is: 03359 % 03360 % unsigned short ReadBlobMSBShort(Image *image) 03361 % 03362 % A description of each parameter follows. 03363 % 03364 % o image: the image. 03365 % 03366 */ 03367 MagickExport unsigned short ReadBlobMSBShort(Image *image) 03368 { 03369 register const unsigned char 03370 *p; 03371 03372 register unsigned int 03373 value; 03374 03375 ssize_t 03376 count; 03377 03378 unsigned char 03379 buffer[2]; 03380 03381 assert(image != (Image *) NULL); 03382 assert(image->signature == MagickSignature); 03383 *buffer='\0'; 03384 p=ReadBlobStream(image,2,buffer,&count); 03385 if (count != 2) 03386 return((unsigned short) 0U); 03387 value=(unsigned int) ((*p++) << 8); 03388 value|=(unsigned int) (*p++); 03389 return((unsigned short) (value & 0xffff)); 03390 } 03391 03392 /* 03393 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 03394 % % 03395 % % 03396 % % 03397 + R e a d B l o b S t r i n g % 03398 % % 03399 % % 03400 % % 03401 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 03402 % 03403 % ReadBlobString() reads characters from a blob or file until a newline 03404 % character is read or an end-of-file condition is encountered. 03405 % 03406 % The format of the ReadBlobString method is: 03407 % 03408 % char *ReadBlobString(Image *image,char *string) 03409 % 03410 % A description of each parameter follows: 03411 % 03412 % o image: the image. 03413 % 03414 % o string: the address of a character buffer. 03415 % 03416 */ 03417 MagickExport char *ReadBlobString(Image *image,char *string) 03418 { 03419 register const unsigned char 03420 *p; 03421 03422 register ssize_t 03423 i; 03424 03425 ssize_t 03426 count; 03427 03428 unsigned char 03429 buffer[1]; 03430 03431 assert(image != (Image *) NULL); 03432 assert(image->signature == MagickSignature); 03433 for (i=0; i < (MaxTextExtent-1L); i++) 03434 { 03435 p=ReadBlobStream(image,1,buffer,&count); 03436 if (count != 1) 03437 { 03438 if (i == 0) 03439 return((char *) NULL); 03440 break; 03441 } 03442 string[i]=(char) (*p); 03443 if ((string[i] == '\r') || (string[i] == '\n')) 03444 break; 03445 } 03446 if (string[i] == '\r') 03447 (void) ReadBlobStream(image,1,buffer,&count); 03448 string[i]='\0'; 03449 return(string); 03450 } 03451 03452 /* 03453 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 03454 % % 03455 % % 03456 % % 03457 + R e f e r e n c e B l o b % 03458 % % 03459 % % 03460 % % 03461 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 03462 % 03463 % ReferenceBlob() increments the reference count associated with the pixel 03464 % blob returning a pointer to the blob. 03465 % 03466 % The format of the ReferenceBlob method is: 03467 % 03468 % BlobInfo ReferenceBlob(BlobInfo *blob_info) 03469 % 03470 % A description of each parameter follows: 03471 % 03472 % o blob_info: the blob_info. 03473 % 03474 */ 03475 MagickExport BlobInfo *ReferenceBlob(BlobInfo *blob) 03476 { 03477 assert(blob != (BlobInfo *) NULL); 03478 assert(blob->signature == MagickSignature); 03479 if (blob->debug != MagickFalse) 03480 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"..."); 03481 LockSemaphoreInfo(blob->semaphore); 03482 blob->reference_count++; 03483 UnlockSemaphoreInfo(blob->semaphore); 03484 return(blob); 03485 } 03486 03487 /* 03488 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 03489 % % 03490 % % 03491 % % 03492 + S e e k B l o b % 03493 % % 03494 % % 03495 % % 03496 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 03497 % 03498 % SeekBlob() sets the offset in bytes from the beginning of a blob or file 03499 % and returns the resulting offset. 03500 % 03501 % The format of the SeekBlob method is: 03502 % 03503 % MagickOffsetType SeekBlob(Image *image,const MagickOffsetType offset, 03504 % const int whence) 03505 % 03506 % A description of each parameter follows: 03507 % 03508 % o image: the image. 03509 % 03510 % o offset: Specifies an integer representing the offset in bytes. 03511 % 03512 % o whence: Specifies an integer representing how the offset is 03513 % treated relative to the beginning of the blob as follows: 03514 % 03515 % SEEK_SET Set position equal to offset bytes. 03516 % SEEK_CUR Set position to current location plus offset. 03517 % SEEK_END Set position to EOF plus offset. 03518 % 03519 */ 03520 MagickExport MagickOffsetType SeekBlob(Image *image, 03521 const MagickOffsetType offset,const int whence) 03522 { 03523 assert(image != (Image *) NULL); 03524 assert(image->signature == MagickSignature); 03525 if (image->debug != MagickFalse) 03526 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 03527 assert(image->blob != (BlobInfo *) NULL); 03528 assert(image->blob->type != UndefinedStream); 03529 switch (image->blob->type) 03530 { 03531 case UndefinedStream: 03532 break; 03533 case FileStream: 03534 { 03535 if (fseek(image->blob->file,offset,whence) < 0) 03536 return(-1); 03537 image->blob->offset=TellBlob(image); 03538 break; 03539 } 03540 case StandardStream: 03541 case PipeStream: 03542 case ZipStream: 03543 { 03544 #if defined(MAGICKCORE_ZLIB_DELEGATE) 03545 if (gzseek(image->blob->gzfile,(off_t) offset,whence) < 0) 03546 return(-1); 03547 #endif 03548 image->blob->offset=TellBlob(image); 03549 break; 03550 } 03551 case BZipStream: 03552 return(-1); 03553 case FifoStream: 03554 return(-1); 03555 case BlobStream: 03556 { 03557 switch (whence) 03558 { 03559 case SEEK_SET: 03560 default: 03561 { 03562 if (offset < 0) 03563 return(-1); 03564 image->blob->offset=offset; 03565 break; 03566 } 03567 case SEEK_CUR: 03568 { 03569 if ((image->blob->offset+offset) < 0) 03570 return(-1); 03571 image->blob->offset+=offset; 03572 break; 03573 } 03574 case SEEK_END: 03575 { 03576 if (((MagickOffsetType) image->blob->length+offset) < 0) 03577 return(-1); 03578 image->blob->offset=image->blob->length+offset; 03579 break; 03580 } 03581 } 03582 if (image->blob->offset <= (MagickOffsetType) 03583 ((off_t) image->blob->length)) 03584 image->blob->eof=MagickFalse; 03585 else 03586 if (image->blob->mapped != MagickFalse) 03587 return(-1); 03588 else 03589 { 03590 image->blob->extent=(size_t) (image->blob->offset+ 03591 image->blob->quantum); 03592 image->blob->data=(unsigned char *) ResizeQuantumMemory( 03593 image->blob->data,image->blob->extent+1, 03594 sizeof(*image->blob->data)); 03595 (void) SyncBlob(image); 03596 if (image->blob->data == (unsigned char *) NULL) 03597 { 03598 (void) DetachBlob(image->blob); 03599 return(-1); 03600 } 03601 } 03602 break; 03603 } 03604 } 03605 return(image->blob->offset); 03606 } 03607 03608 /* 03609 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 03610 % % 03611 % % 03612 % % 03613 + S e t B l o b E x e m p t % 03614 % % 03615 % % 03616 % % 03617 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 03618 % 03619 % SetBlobExempt() sets the blob exempt status. 03620 % 03621 % The format of the SetBlobExempt method is: 03622 % 03623 % MagickBooleanType SetBlobExempt(const Image *image, 03624 % const MagickBooleanType exempt) 03625 % 03626 % A description of each parameter follows: 03627 % 03628 % o image: the image. 03629 % 03630 % o exempt: Set to true if this blob is exempt from being closed. 03631 % 03632 */ 03633 MagickPrivate void SetBlobExempt(Image *image,const MagickBooleanType exempt) 03634 { 03635 assert(image != (const Image *) NULL); 03636 assert(image->signature == MagickSignature); 03637 if (image->debug != MagickFalse) 03638 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 03639 image->blob->exempt=exempt; 03640 } 03641 03642 /* 03643 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 03644 % % 03645 % % 03646 % % 03647 + S e t B l o b E x t e n t % 03648 % % 03649 % % 03650 % % 03651 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 03652 % 03653 % SetBlobExtent() ensures enough space is allocated for the blob. If the 03654 % method is successful, subsequent writes to bytes in the specified range are 03655 % guaranteed not to fail. 03656 % 03657 % The format of the SetBlobExtent method is: 03658 % 03659 % MagickBooleanType SetBlobExtent(Image *image,const MagickSizeType extent) 03660 % 03661 % A description of each parameter follows: 03662 % 03663 % o image: the image. 03664 % 03665 % o extent: the blob maximum extent. 03666 % 03667 */ 03668 MagickPrivate MagickBooleanType SetBlobExtent(Image *image, 03669 const MagickSizeType extent) 03670 { 03671 assert(image != (Image *) NULL); 03672 assert(image->signature == MagickSignature); 03673 if (image->debug != MagickFalse) 03674 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 03675 assert(image->blob != (BlobInfo *) NULL); 03676 assert(image->blob->type != UndefinedStream); 03677 switch (image->blob->type) 03678 { 03679 case UndefinedStream: 03680 break; 03681 case FileStream: 03682 { 03683 if (extent != (MagickSizeType) ((off_t) extent)) 03684 return(MagickFalse); 03685 #if !defined(MAGICKCORE_POSIX_FALLOCATE) 03686 return(MagickFalse); 03687 #else 03688 { 03689 int 03690 status; 03691 03692 MagickOffsetType 03693 offset; 03694 03695 offset=TellBlob(image); 03696 status=posix_fallocate(fileno(image->blob->file),(off_t) offset, 03697 (off_t) (extent-offset)); 03698 if (status != 0) 03699 return(MagickFalse); 03700 } 03701 #endif 03702 break; 03703 } 03704 case StandardStream: 03705 case PipeStream: 03706 case ZipStream: 03707 return(MagickFalse); 03708 case BZipStream: 03709 return(MagickFalse); 03710 case FifoStream: 03711 return(MagickFalse); 03712 case BlobStream: 03713 { 03714 if (image->blob->mapped != MagickFalse) 03715 { 03716 if (image->blob->file == (FILE *) NULL) 03717 return(MagickFalse); 03718 (void) UnmapBlob(image->blob->data,image->blob->length); 03719 #if !defined(MAGICKCORE_POSIX_FALLOCATE) 03720 return(MagickFalse); 03721 #else 03722 { 03723 int 03724 status; 03725 03726 MagickOffsetType 03727 offset; 03728 03729 offset=TellBlob(image); 03730 status=posix_fallocate(fileno(image->blob->file),(off_t) offset, 03731 (off_t) (extent-offset)); 03732 if (status != 0) 03733 return(MagickFalse); 03734 } 03735 image->blob->data=(unsigned char*) MapBlob(fileno(image->blob->file), 03736 WriteMode,0,(size_t) extent); 03737 image->blob->extent=(size_t) extent; 03738 image->blob->length=(size_t) extent; 03739 (void) SyncBlob(image); 03740 break; 03741 #endif 03742 } 03743 if (extent != (MagickSizeType) ((size_t) extent)) 03744 return(MagickFalse); 03745 image->blob->extent=(size_t) extent; 03746 image->blob->data=(unsigned char *) ResizeQuantumMemory(image->blob->data, 03747 image->blob->extent+1,sizeof(*image->blob->data)); 03748 (void) SyncBlob(image); 03749 if (image->blob->data == (unsigned char *) NULL) 03750 { 03751 (void) DetachBlob(image->blob); 03752 return(MagickFalse); 03753 } 03754 break; 03755 } 03756 } 03757 return(MagickTrue); 03758 } 03759 03760 /* 03761 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 03762 % % 03763 % % 03764 % % 03765 + S y n c B l o b % 03766 % % 03767 % % 03768 % % 03769 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 03770 % 03771 % SyncBlob() flushes the datastream if it is a file or synchronizes the data 03772 % attributes if it is an blob. 03773 % 03774 % The format of the SyncBlob method is: 03775 % 03776 % int SyncBlob(Image *image) 03777 % 03778 % A description of each parameter follows: 03779 % 03780 % o image: the image. 03781 % 03782 */ 03783 static int SyncBlob(Image *image) 03784 { 03785 int 03786 status; 03787 03788 assert(image != (Image *) NULL); 03789 assert(image->signature == MagickSignature); 03790 if (image->debug != MagickFalse) 03791 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 03792 assert(image->blob != (BlobInfo *) NULL); 03793 assert(image->blob->type != UndefinedStream); 03794 status=0; 03795 switch (image->blob->type) 03796 { 03797 case UndefinedStream: 03798 break; 03799 case FileStream: 03800 case StandardStream: 03801 case PipeStream: 03802 { 03803 status=fflush(image->blob->file); 03804 break; 03805 } 03806 case ZipStream: 03807 { 03808 #if defined(MAGICKCORE_ZLIB_DELEGATE) 03809 status=gzflush(image->blob->gzfile,Z_SYNC_FLUSH); 03810 #endif 03811 break; 03812 } 03813 case BZipStream: 03814 { 03815 #if defined(MAGICKCORE_BZLIB_DELEGATE) 03816 status=BZ2_bzflush(image->blob->bzfile); 03817 #endif 03818 break; 03819 } 03820 case FifoStream: 03821 break; 03822 case BlobStream: 03823 { 03824 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO) 03825 if (image->blob->mapped != MagickFalse) 03826 status=msync(image->blob->data,image->blob->length,MS_SYNC); 03827 #endif 03828 break; 03829 } 03830 } 03831 return(status); 03832 } 03833 03834 /* 03835 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 03836 % % 03837 % % 03838 % % 03839 + T e l l B l o b % 03840 % % 03841 % % 03842 % % 03843 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 03844 % 03845 % TellBlob() obtains the current value of the blob or file position. 03846 % 03847 % The format of the TellBlob method is: 03848 % 03849 % MagickOffsetType TellBlob(const Image *image) 03850 % 03851 % A description of each parameter follows: 03852 % 03853 % o image: the image. 03854 % 03855 */ 03856 MagickExport MagickOffsetType TellBlob(const Image *image) 03857 { 03858 MagickOffsetType 03859 offset; 03860 03861 assert(image != (Image *) NULL); 03862 assert(image->signature == MagickSignature); 03863 if (image->debug != MagickFalse) 03864 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 03865 assert(image->blob != (BlobInfo *) NULL); 03866 assert(image->blob->type != UndefinedStream); 03867 offset=(-1); 03868 switch (image->blob->type) 03869 { 03870 case UndefinedStream: 03871 break; 03872 case FileStream: 03873 { 03874 offset=ftell(image->blob->file); 03875 break; 03876 } 03877 case StandardStream: 03878 case PipeStream: 03879 break; 03880 case ZipStream: 03881 { 03882 #if defined(MAGICKCORE_ZLIB_DELEGATE) 03883 offset=(MagickOffsetType) gztell(image->blob->gzfile); 03884 #endif 03885 break; 03886 } 03887 case BZipStream: 03888 break; 03889 case FifoStream: 03890 break; 03891 case BlobStream: 03892 { 03893 offset=image->blob->offset; 03894 break; 03895 } 03896 } 03897 return(offset); 03898 } 03899 03900 /* 03901 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 03902 % % 03903 % % 03904 % % 03905 + U n m a p B l o b % 03906 % % 03907 % % 03908 % % 03909 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 03910 % 03911 % UnmapBlob() deallocates the binary large object previously allocated with 03912 % the MapBlob method. 03913 % 03914 % The format of the UnmapBlob method is: 03915 % 03916 % MagickBooleanType UnmapBlob(void *map,const size_t length) 03917 % 03918 % A description of each parameter follows: 03919 % 03920 % o map: the address of the binary large object. 03921 % 03922 % o length: the length of the binary large object. 03923 % 03924 */ 03925 MagickExport MagickBooleanType UnmapBlob(void *map,const size_t length) 03926 { 03927 #if defined(MAGICKCORE_HAVE_MMAP_FILEIO) 03928 int 03929 status; 03930 03931 status=munmap(map,length); 03932 return(status == -1 ? MagickFalse : MagickTrue); 03933 #else 03934 (void) map; 03935 (void) length; 03936 return(MagickFalse); 03937 #endif 03938 } 03939 03940 /* 03941 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 03942 % % 03943 % % 03944 % % 03945 + W r i t e B l o b % 03946 % % 03947 % % 03948 % % 03949 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 03950 % 03951 % WriteBlob() writes data to a blob or image file. It returns the number of 03952 % bytes written. 03953 % 03954 % The format of the WriteBlob method is: 03955 % 03956 % ssize_t WriteBlob(Image *image,const size_t length, 03957 % const unsigned char *data) 03958 % 03959 % A description of each parameter follows: 03960 % 03961 % o image: the image. 03962 % 03963 % o length: Specifies an integer representing the number of bytes to 03964 % write to the file. 03965 % 03966 % o data: The address of the data to write to the blob or file. 03967 % 03968 */ 03969 MagickExport ssize_t WriteBlob(Image *image,const size_t length, 03970 const unsigned char *data) 03971 { 03972 int 03973 c; 03974 03975 register const unsigned char 03976 *p; 03977 03978 ssize_t 03979 count; 03980 03981 assert(image != (Image *) NULL); 03982 assert(image->signature == MagickSignature); 03983 assert(data != (const unsigned char *) NULL); 03984 assert(image->blob != (BlobInfo *) NULL); 03985 assert(image->blob->type != UndefinedStream); 03986 if (length == 0) 03987 return(0); 03988 count=0; 03989 p=data; 03990 switch (image->blob->type) 03991 { 03992 case UndefinedStream: 03993 break; 03994 case FileStream: 03995 case StandardStream: 03996 case PipeStream: 03997 { 03998 switch (length) 03999 { 04000 default: 04001 { 04002 count=(ssize_t) fwrite((const char *) data,1,length, 04003 image->blob->file); 04004 break; 04005 } 04006 case 2: 04007 { 04008 c=putc((int) *p++,image->blob->file); 04009 if (c == EOF) 04010 break; 04011 count++; 04012 } 04013 case 1: 04014 { 04015 c=putc((int) *p++,image->blob->file); 04016 if (c == EOF) 04017 break; 04018 count++; 04019 } 04020 case 0: 04021 break; 04022 } 04023 break; 04024 } 04025 case ZipStream: 04026 { 04027 #if defined(MAGICKCORE_ZLIB_DELEGATE) 04028 switch (length) 04029 { 04030 default: 04031 { 04032 count=(ssize_t) gzwrite(image->blob->gzfile,(void *) data, 04033 (unsigned int) length); 04034 break; 04035 } 04036 case 2: 04037 { 04038 c=gzputc(image->blob->gzfile,(int) *p++); 04039 if (c == EOF) 04040 break; 04041 count++; 04042 } 04043 case 1: 04044 { 04045 c=gzputc(image->blob->gzfile,(int) *p++); 04046 if (c == EOF) 04047 break; 04048 count++; 04049 } 04050 case 0: 04051 break; 04052 } 04053 #endif 04054 break; 04055 } 04056 case BZipStream: 04057 { 04058 #if defined(MAGICKCORE_BZLIB_DELEGATE) 04059 count=(ssize_t) BZ2_bzwrite(image->blob->bzfile,(void *) data,(int) 04060 length); 04061 #endif 04062 break; 04063 } 04064 case FifoStream: 04065 { 04066 count=(ssize_t) image->blob->stream(image,data,length); 04067 break; 04068 } 04069 case BlobStream: 04070 { 04071 register unsigned char 04072 *q; 04073 04074 if ((image->blob->offset+(MagickOffsetType) length) >= 04075 (MagickOffsetType) image->blob->extent) 04076 { 04077 if (image->blob->mapped != MagickFalse) 04078 return(0); 04079 image->blob->quantum<<=1; 04080 image->blob->extent+=length+image->blob->quantum; 04081 image->blob->data=(unsigned char *) ResizeQuantumMemory( 04082 image->blob->data,image->blob->extent+1,sizeof(*image->blob->data)); 04083 (void) SyncBlob(image); 04084 if (image->blob->data == (unsigned char *) NULL) 04085 { 04086 (void) DetachBlob(image->blob); 04087 return(0); 04088 } 04089 } 04090 q=image->blob->data+image->blob->offset; 04091 (void) memcpy(q,p,length); 04092 image->blob->offset+=length; 04093 if (image->blob->offset >= (MagickOffsetType) image->blob->length) 04094 image->blob->length=(size_t) image->blob->offset; 04095 count=(ssize_t) length; 04096 } 04097 } 04098 return(count); 04099 } 04100 04101 /* 04102 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 04103 % % 04104 % % 04105 % % 04106 + W r i t e B l o b B y t e % 04107 % % 04108 % % 04109 % % 04110 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 04111 % 04112 % WriteBlobByte() write an integer to a blob. It returns the number of bytes 04113 % written (either 0 or 1); 04114 % 04115 % The format of the WriteBlobByte method is: 04116 % 04117 % ssize_t WriteBlobByte(Image *image,const unsigned char value) 04118 % 04119 % A description of each parameter follows. 04120 % 04121 % o image: the image. 04122 % 04123 % o value: Specifies the value to write. 04124 % 04125 */ 04126 MagickExport ssize_t WriteBlobByte(Image *image,const unsigned char value) 04127 { 04128 assert(image != (Image *) NULL); 04129 assert(image->signature == MagickSignature); 04130 return(WriteBlobStream(image,1,&value)); 04131 } 04132 04133 /* 04134 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 04135 % % 04136 % % 04137 % % 04138 + W r i t e B l o b F l o a t % 04139 % % 04140 % % 04141 % % 04142 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 04143 % 04144 % WriteBlobFloat() writes a float value as a 32-bit quantity in the byte-order 04145 % specified by the endian member of the image structure. 04146 % 04147 % The format of the WriteBlobFloat method is: 04148 % 04149 % ssize_t WriteBlobFloat(Image *image,const float value) 04150 % 04151 % A description of each parameter follows. 04152 % 04153 % o image: the image. 04154 % 04155 % o value: Specifies the value to write. 04156 % 04157 */ 04158 MagickExport ssize_t WriteBlobFloat(Image *image,const float value) 04159 { 04160 union 04161 { 04162 unsigned int 04163 unsigned_value; 04164 04165 float 04166 float_value; 04167 } quantum; 04168 04169 quantum.unsigned_value=0U; 04170 quantum.float_value=value; 04171 return(WriteBlobLong(image,quantum.unsigned_value)); 04172 } 04173 04174 /* 04175 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 04176 % % 04177 % % 04178 % % 04179 + W r i t e B l o b L o n g % 04180 % % 04181 % % 04182 % % 04183 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 04184 % 04185 % WriteBlobLong() writes a ssize_t value as a 32-bit quantity in the byte-order 04186 % specified by the endian member of the image structure. 04187 % 04188 % The format of the WriteBlobLong method is: 04189 % 04190 % ssize_t WriteBlobLong(Image *image,const unsigned int value) 04191 % 04192 % A description of each parameter follows. 04193 % 04194 % o image: the image. 04195 % 04196 % o value: Specifies the value to write. 04197 % 04198 */ 04199 MagickExport ssize_t WriteBlobLong(Image *image,const unsigned int value) 04200 { 04201 unsigned char 04202 buffer[4]; 04203 04204 assert(image != (Image *) NULL); 04205 assert(image->signature == MagickSignature); 04206 if (image->endian == LSBEndian) 04207 { 04208 buffer[0]=(unsigned char) value; 04209 buffer[1]=(unsigned char) (value >> 8); 04210 buffer[2]=(unsigned char) (value >> 16); 04211 buffer[3]=(unsigned char) (value >> 24); 04212 return(WriteBlobStream(image,4,buffer)); 04213 } 04214 buffer[0]=(unsigned char) (value >> 24); 04215 buffer[1]=(unsigned char) (value >> 16); 04216 buffer[2]=(unsigned char) (value >> 8); 04217 buffer[3]=(unsigned char) value; 04218 return(WriteBlobStream(image,4,buffer)); 04219 } 04220 04221 /* 04222 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 04223 % % 04224 % % 04225 % % 04226 + W r i t e B l o b S h o r t % 04227 % % 04228 % % 04229 % % 04230 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 04231 % 04232 % WriteBlobShort() writes a short value as a 16-bit quantity in the 04233 % byte-order specified by the endian member of the image structure. 04234 % 04235 % The format of the WriteBlobShort method is: 04236 % 04237 % ssize_t WriteBlobShort(Image *image,const unsigned short value) 04238 % 04239 % A description of each parameter follows. 04240 % 04241 % o image: the image. 04242 % 04243 % o value: Specifies the value to write. 04244 % 04245 */ 04246 MagickExport ssize_t WriteBlobShort(Image *image,const unsigned short value) 04247 { 04248 unsigned char 04249 buffer[2]; 04250 04251