MagickCore 7.1.1-43
Convert, Edit, Or Compose Bitmap Images
Loading...
Searching...
No Matches
string.c
1/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% SSSSS TTTTT RRRR IIIII N N GGGG %
7% SS T R R I NN N G %
8% SSS T RRRR I N N N G GGG %
9% SS T R R I N NN G G %
10% SSSSS T R R IIIII N N GGGG %
11% %
12% %
13% MagickCore String Methods %
14% %
15% Software Design %
16% Cristy %
17% August 2003 %
18% %
19% %
20% Copyright @ 1999 ImageMagick Studio LLC, a non-profit organization %
21% dedicated to making software imaging solutions freely available. %
22% %
23% You may not use this file except in compliance with the license. You may %
24% obtain a copy of the license at %
25% %
26% https://imagemagick.org/script/license.php %
27% %
28% unless required by applicable law or agreed to in writing, software %
29% distributed under the license is distributed on an "as is" basis, %
30% without warranties or conditions of any kind, either express or implied. %
31% See the license for the specific language governing permissions and %
32% limitations under the license. %
33% %
34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35%
36%
37*/
38
39/*
40 Include declarations.
41*/
42#include "MagickCore/studio.h"
43#include "MagickCore/blob.h"
44#include "MagickCore/blob-private.h"
45#include "MagickCore/exception.h"
46#include "MagickCore/exception-private.h"
47#include "MagickCore/image-private.h"
48#include "MagickCore/list.h"
49#include "MagickCore/locale_.h"
50#include "MagickCore/log.h"
51#include "MagickCore/memory_.h"
52#include "MagickCore/memory-private.h"
53#include "MagickCore/nt-base-private.h"
54#include "MagickCore/property.h"
55#include "MagickCore/policy.h"
56#include "MagickCore/resource_.h"
57#include "MagickCore/resource-private.h"
58#include "MagickCore/signature-private.h"
59#include "MagickCore/string_.h"
60#include "MagickCore/string-private.h"
61#include "MagickCore/utility-private.h"
62
63/*
64 Define declarations.
65*/
66#define CharsPerLine 0x14
67
68/*
69%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
70% %
71% %
72% %
73% A c q u i r e S t r i n g %
74% %
75% %
76% %
77%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
78%
79% AcquireString() returns an new extended string, containing a clone of the
80% given string.
81%
82% An extended string is the string length, plus an extra MagickPathExtent space
83% to allow for the string to be actively worked on.
84%
85% The returned string should be freed using DestroyString().
86%
87% The format of the AcquireString method is:
88%
89% char *AcquireString(const char *source)
90%
91% A description of each parameter follows:
92%
93% o source: A character string.
94%
95*/
96MagickExport char *AcquireString(const char *source)
97{
98 char
99 *destination;
100
101 size_t
102 length;
103
104 length=0;
105 if (source != (char *) NULL)
106 length+=strlen(source);
107 if (~length < MagickPathExtent)
108 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
109 destination=(char *) AcquireQuantumMemory(length+MagickPathExtent,
110 sizeof(*destination));
111 if (destination == (char *) NULL)
112 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
113 if (source != (char *) NULL)
114 (void) memcpy(destination,source,length*sizeof(*destination));
115 destination[length]='\0';
116 return(destination);
117}
118
119/*
120%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
121% %
122% %
123% %
124% A c q u i r e S t r i n g I n f o %
125% %
126% %
127% %
128%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
129%
130% AcquireStringInfo() allocates the StringInfo structure.
131%
132% The format of the AcquireStringInfo method is:
133%
134% StringInfo *AcquireStringInfo(const size_t length)
135%
136% A description of each parameter follows:
137%
138% o length: the string length.
139%
140*/
141
142static StringInfo *AcquireStringInfoContainer(void)
143{
145 *string_info;
146
147 string_info=(StringInfo *) AcquireCriticalMemory(sizeof(*string_info));
148 (void) memset(string_info,0,sizeof(*string_info));
149 string_info->signature=MagickCoreSignature;
150 return(string_info);
151}
152
153MagickExport StringInfo *AcquireStringInfo(const size_t length)
154{
156 *string_info;
157
158 string_info=AcquireStringInfoContainer();
159 string_info->length=length;
160 if (~string_info->length >= (MagickPathExtent-1))
161 string_info->datum=(unsigned char *) AcquireQuantumMemory(
162 string_info->length+MagickPathExtent,sizeof(*string_info->datum));
163 if (string_info->datum == (unsigned char *) NULL)
164 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
165 (void) memset(string_info->datum,0,(length+MagickPathExtent)*
166 sizeof(*string_info->datum));
167 return(string_info);
168}
169
170/*
171%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
172% %
173% %
174% %
175% B l o b T o S t r i n g I n f o %
176% %
177% %
178% %
179%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
180%
181% BlobToStringInfo() returns the contents of a blob as a StringInfo structure
182% with MagickPathExtent extra space.
183%
184% The format of the BlobToStringInfo method is:
185%
186% StringInfo *BlobToStringInfo(const void *blob,const size_t length)
187%
188% A description of each parameter follows:
189%
190% o blob: the blob.
191%
192% o length: the length of the blob.
193%
194*/
195MagickExport StringInfo *BlobToStringInfo(const void *blob,const size_t length)
196{
198 *string_info;
199
200 if (~length < MagickPathExtent)
201 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
202 string_info=AcquireStringInfoContainer();
203 string_info->length=length;
204 string_info->datum=(unsigned char *) AcquireQuantumMemory(length+
205 MagickPathExtent,sizeof(*string_info->datum));
206 if (string_info->datum == (unsigned char *) NULL)
207 {
208 string_info=DestroyStringInfo(string_info);
209 return((StringInfo *) NULL);
210 }
211 if (blob != (const void *) NULL)
212 (void) memcpy(string_info->datum,blob,length);
213 else
214 (void) memset(string_info->datum,0,length*sizeof(*string_info->datum));
215 (void) memset(string_info->datum+length,0,MagickPathExtent*
216 sizeof(*string_info->datum));
217 return(string_info);
218}
219
220/*
221%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
222% %
223% %
224% %
225% C l o n e S t r i n g %
226% %
227% %
228% %
229%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
230%
231% CloneString() replaces or frees the destination string to make it
232% a clone of the input string plus MagickPathExtent more space so the string
233% may be worked on.
234%
235% If source is a NULL pointer the destination string will be freed and set to
236% a NULL pointer. A pointer to the stored in the destination is also returned.
237%
238% When finished the non-NULL string should be freed using DestroyString()
239% or using CloneString() with a NULL pointed for the source.
240%
241% The format of the CloneString method is:
242%
243% char *CloneString(char **destination,const char *source)
244%
245% A description of each parameter follows:
246%
247% o destination: A pointer to a character string.
248%
249% o source: A character string.
250%
251*/
252MagickExport char *CloneString(char **destination,const char *source)
253{
254 size_t
255 length;
256
257 assert(destination != (char **) NULL);
258 if (source == (const char *) NULL)
259 {
260 if (*destination != (char *) NULL)
261 *destination=DestroyString(*destination);
262 return(*destination);
263 }
264 if (*destination == (char *) NULL)
265 {
266 *destination=AcquireString(source);
267 return(*destination);
268 }
269 length=strlen(source);
270 if (~length < MagickPathExtent)
271 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
272 *destination=(char *) ResizeQuantumMemory(*destination,length+
273 MagickPathExtent,sizeof(**destination));
274 if (*destination == (char *) NULL)
275 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
276 if (length != 0)
277 (void) memcpy(*destination,source,length*sizeof(**destination));
278 (*destination)[length]='\0';
279 return(*destination);
280}
281
282/*
283%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
284% %
285% %
286% %
287% C l o n e S t r i n g I n f o %
288% %
289% %
290% %
291%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
292%
293% CloneStringInfo() clones a copy of the StringInfo structure.
294%
295% The format of the CloneStringInfo method is:
296%
297% StringInfo *CloneStringInfo(const StringInfo *string_info)
298%
299% A description of each parameter follows:
300%
301% o string_info: the string info.
302%
303*/
304MagickExport StringInfo *CloneStringInfo(const StringInfo *string_info)
305{
307 *clone_info;
308
309 assert(string_info != (StringInfo *) NULL);
310 assert(string_info->signature == MagickCoreSignature);
311 clone_info=AcquireStringInfo(string_info->length);
312 (void) CloneString(&clone_info->path,string_info->path);
313 (void) CloneString(&clone_info->name,string_info->name);
314 if (string_info->length != 0)
315 (void) memcpy(clone_info->datum,string_info->datum,string_info->length+1);
316 return(clone_info);
317}
318
319/*
320%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
321% %
322% %
323% %
324% C o m p a r e S t r i n g I n f o %
325% %
326% %
327% %
328%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
329%
330% CompareStringInfo() compares the two datums target and source. It returns
331% an integer less than, equal to, or greater than zero if target is found,
332% respectively, to be less than, to match, or be greater than source.
333%
334% The format of the CompareStringInfo method is:
335%
336% int CompareStringInfo(const StringInfo *target,const StringInfo *source)
337%
338% A description of each parameter follows:
339%
340% o target: the target string.
341%
342% o source: the source string.
343%
344*/
345
346MagickExport int CompareStringInfo(const StringInfo *target,
347 const StringInfo *source)
348{
349 int
350 status;
351
352 assert(target != (StringInfo *) NULL);
353 assert(target->signature == MagickCoreSignature);
354 assert(source != (StringInfo *) NULL);
355 assert(source->signature == MagickCoreSignature);
356 status=memcmp(target->datum,source->datum,MagickMin(target->length,
357 source->length));
358 if (status != 0)
359 return(status);
360 if (target->length == source->length)
361 return(0);
362 return(target->length < source->length ? -1 : 1);
363}
364
365/*
366%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
367% %
368% %
369% %
370% C o n c a t e n a t e M a g i c k S t r i n g %
371% %
372% %
373% %
374%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
375%
376% ConcatenateMagickString() concatenates the source string to the destination
377% string. The destination buffer is always null-terminated even if the
378% string must be truncated.
379%
380% The format of the ConcatenateMagickString method is:
381%
382% size_t ConcatenateMagickString(char *magick_restrict destination,
383% const char *magick_restrict source,const size_t length)
384%
385% A description of each parameter follows:
386%
387% o destination: the destination string.
388%
389% o source: the source string.
390%
391% o length: the length of the destination string.
392%
393*/
394MagickExport size_t ConcatenateMagickString(char *magick_restrict destination,
395 const char *magick_restrict source,const size_t length)
396{
397 char
398 *magick_restrict q;
399
400 const char
401 *magick_restrict p;
402
403 size_t
404 count,
405 i;
406
407 assert(destination != (char *) NULL);
408 assert(source != (const char *) NULL);
409 assert(length >= 1);
410 p=source;
411 q=destination;
412 i=length;
413 while ((i-- != 0) && (*q != '\0'))
414 q++;
415 count=(size_t) (q-destination);
416 i=length-count;
417 if (i == 0)
418 return(count+strlen(p));
419 while (*p != '\0')
420 {
421 if (i != 1)
422 {
423 *q++=(*p);
424 i--;
425 }
426 p++;
427 }
428 *q='\0';
429 return(count+(size_t) (p-source));
430}
431
432/*
433%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
434% %
435% %
436% %
437% C o n c a t e n a t e S t r i n g %
438% %
439% %
440% %
441%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
442%
443% ConcatenateString() appends a copy of string source, including the
444% terminating null character, to the end of string destination.
445%
446% The format of the ConcatenateString method is:
447%
448% MagickBooleanType ConcatenateString(char **magick_restrict destination,
449% const char *magick_restrict source)
450%
451% A description of each parameter follows:
452%
453% o destination: A pointer to a character string.
454%
455% o source: A character string.
456%
457*/
458MagickExport MagickBooleanType ConcatenateString(
459 char **magick_restrict destination,const char *magick_restrict source)
460{
461 size_t
462 destination_length,
463 length,
464 source_length;
465
466 assert(destination != (char **) NULL);
467 if (source == (const char *) NULL)
468 return(MagickTrue);
469 if (*destination == (char *) NULL)
470 {
471 *destination=AcquireString(source);
472 return(MagickTrue);
473 }
474 destination_length=strlen(*destination);
475 source_length=strlen(source);
476 length=destination_length;
477 if (~length < source_length)
478 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
479 length+=source_length;
480 if (~length < MagickPathExtent)
481 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
482 *destination=(char *) ResizeQuantumMemory(*destination,
483 OverAllocateMemory(length+MagickPathExtent),sizeof(**destination));
484 if (*destination == (char *) NULL)
485 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
486 if (source_length != 0)
487 (void) memcpy((*destination)+destination_length,source,source_length);
488 (*destination)[length]='\0';
489 return(MagickTrue);
490}
491
492/*
493%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
494% %
495% %
496% %
497% C o n c a t e n a t e S t r i n g I n f o %
498% %
499% %
500% %
501%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
502%
503% ConcatenateStringInfo() concatenates the source string to the destination
504% string.
505%
506% The format of the ConcatenateStringInfo method is:
507%
508% void ConcatenateStringInfo(StringInfo *string_info,
509% const StringInfo *source)
510%
511% A description of each parameter follows:
512%
513% o string_info: the string info.
514%
515% o source: the source string.
516%
517*/
518MagickExport void ConcatenateStringInfo(StringInfo *string_info,
519 const StringInfo *source)
520{
521 size_t
522 length;
523
524 assert(string_info != (StringInfo *) NULL);
525 assert(string_info->signature == MagickCoreSignature);
526 assert(source != (const StringInfo *) NULL);
527 length=string_info->length;
528 if (~length < source->length)
529 ThrowFatalException(ResourceLimitFatalError,"UnableToConcatenateString");
530 length+=source->length;
531 if (~length < MagickPathExtent)
532 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
533 if (string_info->datum == (unsigned char *) NULL)
534 string_info->datum=(unsigned char *) AcquireQuantumMemory(length+
535 MagickPathExtent,sizeof(*string_info->datum));
536 else
537 string_info->datum=(unsigned char *) ResizeQuantumMemory(
538 string_info->datum,OverAllocateMemory(length+MagickPathExtent),
539 sizeof(*string_info->datum));
540 if (string_info->datum == (unsigned char *) NULL)
541 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
542 (void) memcpy(string_info->datum+string_info->length,source->datum,
543 source->length);
544 string_info->length=length;
545}
546
547/*
548%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
549% %
550% %
551% %
552% C o n f i g u r e F i l e T o S t r i n g I n f o %
553% %
554% %
555% %
556%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
557%
558% ConfigureFileToStringInfo() returns the contents of a configure file as a
559% string.
560%
561% The format of the ConfigureFileToStringInfo method is:
562%
563% StringInfo *ConfigureFileToStringInfo(const char *filename)
564% ExceptionInfo *exception)
565%
566% A description of each parameter follows:
567%
568% o filename: the filename.
569%
570*/
571MagickExport StringInfo *ConfigureFileToStringInfo(const char *filename)
572{
573 char
574 *string;
575
576 int
577 file;
578
579 MagickOffsetType
580 offset;
581
582 size_t
583 length;
584
586 *string_info;
587
588 void
589 *map;
590
591 assert(filename != (const char *) NULL);
592 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
593 if (file == -1)
594 return((StringInfo *) NULL);
595 offset=(MagickOffsetType) lseek(file,0,SEEK_END);
596 if ((offset < 0) || (offset != (MagickOffsetType) ((ssize_t) offset)))
597 {
598 file=close_utf8(file)-1;
599 return((StringInfo *) NULL);
600 }
601 length=(size_t) offset;
602 string=(char *) NULL;
603 if (~length >= (MagickPathExtent-1))
604 string=(char *) AcquireQuantumMemory(length+MagickPathExtent,
605 sizeof(*string));
606 if (string == (char *) NULL)
607 {
608 file=close_utf8(file)-1;
609 return((StringInfo *) NULL);
610 }
611 map=MapBlob(file,ReadMode,0,length);
612 if (map != (void *) NULL)
613 {
614 (void) memcpy(string,map,length);
615 (void) UnmapBlob(map,length);
616 }
617 else
618 {
619 size_t
620 i;
621
622 ssize_t
623 count;
624
625 (void) lseek(file,0,SEEK_SET);
626 for (i=0; i < length; i+=(size_t) count)
627 {
628 count=read(file,string+i,(size_t) MagickMin(length-i,(size_t)
629 MagickMaxBufferExtent));
630 if (count <= 0)
631 {
632 count=0;
633 if (errno != EINTR)
634 break;
635 }
636 }
637 if (i < length)
638 {
639 file=close_utf8(file)-1;
640 string=DestroyString(string);
641 return((StringInfo *) NULL);
642 }
643 }
644 string[length]='\0';
645 file=close_utf8(file)-1;
646 string_info=AcquireStringInfoContainer();
647 string_info->path=ConstantString(filename);
648 string_info->length=length;
649 string_info->datum=(unsigned char *) string;
650 return(string_info);
651}
652
653/*
654%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
655% %
656% %
657% %
658% C o n s t a n t S t r i n g %
659% %
660% %
661% %
662%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
663%
664% ConstantString() allocates exactly the needed memory for a string and
665% copies the source string to that memory location. A NULL string pointer
666% will allocate an empty string containing just the NUL character.
667%
668% When finished the string should be freed using DestroyString()
669%
670% The format of the ConstantString method is:
671%
672% char *ConstantString(const char *source)
673%
674% A description of each parameter follows:
675%
676% o source: A character string.
677%
678*/
679MagickExport char *ConstantString(const char *source)
680{
681 char
682 *destination;
683
684 size_t
685 length;
686
687 length=0;
688 if (source != (char *) NULL)
689 length+=strlen(source);
690 destination=(char *) NULL;
691 if (~length >= 1UL)
692 destination=(char *) AcquireQuantumMemory(length+1UL,sizeof(*destination));
693 if (destination == (char *) NULL)
694 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
695 if (source != (char *) NULL)
696 (void) memcpy(destination,source,length*sizeof(*destination));
697 destination[length]='\0';
698 return(destination);
699}
700
701/*
702%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
703% %
704% %
705% %
706% C o p y M a g i c k S t r i n g %
707% %
708% %
709% %
710%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
711%
712% CopyMagickString() copies the source string to the destination string, with
713% out exceeding the given pre-declared length.
714%
715% The destination buffer is always null-terminated even if the string must be
716% truncated. The return value is the length of the string.
717%
718% The format of the CopyMagickString method is:
719%
720% size_t CopyMagickString(const char *magick_restrict destination,
721% char *magick_restrict source,const size_t length)
722%
723% A description of each parameter follows:
724%
725% o destination: the destination string.
726%
727% o source: the source string.
728%
729% o length: the length of the destination string.
730%
731*/
732MagickExport size_t CopyMagickString(char *magick_restrict destination,
733 const char *magick_restrict source,const size_t length)
734{
735 char
736 *magick_restrict q;
737
738 const char
739 *magick_restrict p;
740
741 size_t
742 n;
743
744 p=source;
745 q=destination;
746 for (n=length; n > 4; n-=4)
747 {
748 if (((*q++)=(*p++)) == '\0')
749 return((size_t) (p-source-1));
750 if (((*q++)=(*p++)) == '\0')
751 return((size_t) (p-source-1));
752 if (((*q++)=(*p++)) == '\0')
753 return((size_t) (p-source-1));
754 if (((*q++)=(*p++)) == '\0')
755 return((size_t) (p-source-1));
756 }
757 if (length != 0)
758 {
759 while (--n != 0)
760 if (((*q++)=(*p++)) == '\0')
761 return((size_t) (p-source-1));
762 *q='\0';
763 }
764 return((size_t) (p-source));
765}
766
767/*
768%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
769% %
770% %
771% %
772% D e s t r o y S t r i n g %
773% %
774% %
775% %
776%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
777%
778% DestroyString() destroys memory associated with a string.
779%
780% The format of the DestroyString method is:
781%
782% char *DestroyString(char *string)
783%
784% A description of each parameter follows:
785%
786% o string: the string.
787%
788*/
789MagickExport char *DestroyString(char *string)
790{
791 return((char *) RelinquishMagickMemory(string));
792}
793
794/*
795%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
796% %
797% %
798% %
799% D e s t r o y S t r i n g I n f o %
800% %
801% %
802% %
803%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
804%
805% DestroyStringInfo() destroys memory associated with the StringInfo structure.
806%
807% The format of the DestroyStringInfo method is:
808%
809% StringInfo *DestroyStringInfo(StringInfo *string_info)
810%
811% A description of each parameter follows:
812%
813% o string_info: the string info.
814%
815*/
816MagickExport StringInfo *DestroyStringInfo(StringInfo *string_info)
817{
818 assert(string_info != (StringInfo *) NULL);
819 assert(string_info->signature == MagickCoreSignature);
820 if (string_info->datum != (unsigned char *) NULL)
821 string_info->datum=(unsigned char *) RelinquishMagickMemory(
822 string_info->datum);
823 if (string_info->name != (char *) NULL)
824 string_info->name=DestroyString(string_info->name);
825 if (string_info->path != (char *) NULL)
826 string_info->path=DestroyString(string_info->path);
827 string_info->signature=(~MagickCoreSignature);
828 string_info=(StringInfo *) RelinquishMagickMemory(string_info);
829 return(string_info);
830}
831
832/*
833%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
834% %
835% %
836% %
837% D e s t r o y S t r i n g L i s t %
838% %
839% %
840% %
841%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
842%
843% DestroyStringList() zeros memory associated with a string list.
844%
845% The format of the DestroyStringList method is:
846%
847% char **DestroyStringList(char **list)
848%
849% A description of each parameter follows:
850%
851% o list: the string list.
852%
853*/
854MagickExport char **DestroyStringList(char **list)
855{
856 ssize_t
857 i;
858
859 assert(list != (char **) NULL);
860 for (i=0; list[i] != (char *) NULL; i++)
861 list[i]=DestroyString(list[i]);
862 list=(char **) RelinquishMagickMemory(list);
863 return(list);
864}
865
866/*
867%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
868% %
869% %
870% %
871% E s c a p e S t r i n g %
872% %
873% %
874% %
875%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
876%
877% EscapeString() allocates memory for a backslash-escaped version of a
878% source text string, copies the escaped version of the text to that
879% memory location while adding backslash characters, and returns the
880% escaped string.
881%
882% The format of the EscapeString method is:
883%
884% char *EscapeString(const char *source,const char escape)
885%
886% A description of each parameter follows:
887%
888% o allocate_string: Method EscapeString returns the escaped string.
889%
890% o source: A character string.
891%
892% o escape: the quoted string termination character to escape (e.g. '"').
893%
894*/
895MagickExport char *EscapeString(const char *source,const char escape)
896{
897 char
898 *destination;
899
900 char
901 *q;
902
903 const char
904 *p;
905
906 size_t
907 length;
908
909 assert(source != (const char *) NULL);
910 length=0;
911 for (p=source; *p != '\0'; p++)
912 {
913 if ((*p == '\\') || (*p == escape))
914 {
915 if (~length < 1)
916 ThrowFatalException(ResourceLimitFatalError,"UnableToEscapeString");
917 length++;
918 }
919 length++;
920 }
921 destination=(char *) NULL;
922 if (~length >= (MagickPathExtent-1))
923 destination=(char *) AcquireQuantumMemory(length+MagickPathExtent,
924 sizeof(*destination));
925 if (destination == (char *) NULL)
926 ThrowFatalException(ResourceLimitFatalError,"UnableToEscapeString");
927 *destination='\0';
928 q=destination;
929 for (p=source; *p != '\0'; p++)
930 {
931 if ((*p == '\\') || (*p == escape))
932 *q++='\\';
933 *q++=(*p);
934 }
935 *q='\0';
936 return(destination);
937}
938
939/*
940%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
941% %
942% %
943% %
944% F i l e T o S t r i n g %
945% %
946% %
947% %
948%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
949%
950% FileToString() returns the contents of a file as a string.
951%
952% The format of the FileToString method is:
953%
954% char *FileToString(const char *filename,const size_t extent,
955% ExceptionInfo *exception)
956%
957% A description of each parameter follows:
958%
959% o filename: the filename.
960%
961% o extent: Maximum length of the string.
962%
963% o exception: return any errors or warnings in this structure.
964%
965*/
966MagickExport char *FileToString(const char *filename,const size_t extent,
967 ExceptionInfo *exception)
968{
969 const char
970 *p;
971
972 size_t
973 length;
974
975 assert(filename != (const char *) NULL);
976 assert(exception != (ExceptionInfo *) NULL);
977 if (IsEventLogging() != MagickFalse)
978 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
979 p=filename;
980 if ((*filename == '@') && (strlen(filename) > 1))
981 {
982 MagickBooleanType
983 status;
984
985 status=IsRightsAuthorized(PathPolicyDomain,ReadPolicyRights,filename);
986 if (status == MagickFalse)
987 {
988 errno=EPERM;
989 (void) ThrowMagickException(exception,GetMagickModule(),PolicyError,
990 "NotAuthorized","`%s'",filename);
991 return((char *) NULL);
992 }
993 p=filename+1;
994 }
995 return((char *) FileToBlob(p,extent,&length,exception));
996}
997
998/*
999%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1000% %
1001% %
1002% %
1003% F i l e T o S t r i n g I n f o %
1004% %
1005% %
1006% %
1007%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1008%
1009% FileToStringInfo() returns the contents of a file as a string.
1010%
1011% The format of the FileToStringInfo method is:
1012%
1013% StringInfo *FileToStringInfo(const char *filename,const size_t extent,
1014% ExceptionInfo *exception)
1015%
1016% A description of each parameter follows:
1017%
1018% o filename: the filename.
1019%
1020% o extent: Maximum length of the string.
1021%
1022% o exception: return any errors or warnings in this structure.
1023%
1024*/
1025MagickExport StringInfo *FileToStringInfo(const char *filename,
1026 const size_t extent,ExceptionInfo *exception)
1027{
1029 *string_info;
1030
1031 assert(filename != (const char *) NULL);
1032 assert(exception != (ExceptionInfo *) NULL);
1033 if (IsEventLogging() != MagickFalse)
1034 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
1035 string_info=AcquireStringInfoContainer();
1036 string_info->path=ConstantString(filename);
1037 string_info->datum=(unsigned char *) FileToBlob(filename,extent,
1038 &string_info->length,exception);
1039 if (string_info->datum == (unsigned char *) NULL)
1040 {
1041 string_info=DestroyStringInfo(string_info);
1042 return((StringInfo *) NULL);
1043 }
1044 return(string_info);
1045}
1046
1047/*
1048%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1049% %
1050% %
1051% %
1052% F o r m a t M a g i c k S i z e %
1053% %
1054% %
1055% %
1056%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1057%
1058% FormatMagickSize() converts a size to a human readable format, for example,
1059% 14k, 234m, 2.7g, or 3.0t. Scaling is done by repetitively dividing by
1060% 1000.
1061%
1062% The format of the FormatMagickSize method is:
1063%
1064% ssize_t FormatMagickSize(const MagickSizeType size,const char *suffix,
1065% const size_t length,char *format)
1066%
1067% A description of each parameter follows:
1068%
1069% o size: convert this size to a human readable format.
1070%
1071% o bi: use power of two rather than power of ten.
1072%
1073% o suffix: append suffix, typically B or P.
1074%
1075% o length: the maximum length of the string.
1076%
1077% o format: human readable format.
1078%
1079*/
1080MagickExport ssize_t FormatMagickSize(const MagickSizeType size,
1081 const MagickBooleanType bi,const char *suffix,const size_t length,
1082 char *format)
1083{
1084 const char
1085 **units;
1086
1087 double
1088 bytes,
1089 extent;
1090
1091 ssize_t
1092 i;
1093
1094 ssize_t
1095 count;
1096
1097 static const char
1098 *bi_units[] =
1099 {
1100 "", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi", "Ri", "Qi", (char *) NULL
1101 },
1102 *traditional_units[] =
1103 {
1104 "", "K", "M", "G", "T", "P", "E", "Z", "Y", "R", "Q", (char *) NULL
1105 };
1106
1107 bytes=1000.0;
1108 units=traditional_units;
1109 if (bi != MagickFalse)
1110 {
1111 bytes=1024.0;
1112 units=bi_units;
1113 }
1114 extent=(double) size;
1115 (void) FormatLocaleString(format,MagickFormatExtent,"%.*g",
1116 GetMagickPrecision(),extent);
1117 if (strstr(format,"e+") == (char *) NULL)
1118 {
1119 if (suffix == (const char *) NULL)
1120 count=FormatLocaleString(format,length,"%.20g%s",extent,units[0]);
1121 else
1122 count=FormatLocaleString(format,length,"%.20g%s%s",extent,units[0],
1123 suffix);
1124 return(count);
1125 }
1126 for (i=0; (extent >= bytes) && (units[i+1] != (const char *) NULL); i++)
1127 extent/=bytes;
1128 if (suffix == (const char *) NULL)
1129 count=FormatLocaleString(format,length,"%.*g%s",GetMagickPrecision(),
1130 extent,units[i]);
1131 else
1132 count=FormatLocaleString(format,length,"%.*g%s%s",GetMagickPrecision(),
1133 extent,units[i],suffix);
1134 return(count);
1135}
1136
1137/*
1138%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1139% %
1140% %
1141% %
1142% G e t E n v i r o n m e n t V a l u e %
1143% %
1144% %
1145% %
1146%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1147%
1148% GetEnvironmentValue() returns the environment string that matches the
1149% specified name.
1150%
1151% The format of the GetEnvironmentValue method is:
1152%
1153% char *GetEnvironmentValue(const char *name)
1154%
1155% A description of each parameter follows:
1156%
1157% o name: the environment name.
1158%
1159*/
1160MagickExport char *GetEnvironmentValue(const char *name)
1161{
1162#if defined(MAGICKCORE_WINDOWS_SUPPORT)
1163 return(NTGetEnvironmentValue(name));
1164#else
1165 const char
1166 *environment;
1167
1168 environment=getenv(name);
1169 if (environment == (const char *) NULL)
1170 return((char *) NULL);
1171 return(ConstantString(environment));
1172#endif
1173}
1174
1175/*
1176%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1177% %
1178% %
1179% %
1180% G e t S t r i n g I n f o D a t u m %
1181% %
1182% %
1183% %
1184%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1185%
1186% GetStringInfoDatum() returns the datum associated with the string.
1187%
1188% The format of the GetStringInfoDatum method is:
1189%
1190% unsigned char *GetStringInfoDatum(const StringInfo *string_info)
1191%
1192% A description of each parameter follows:
1193%
1194% o string_info: the string info.
1195%
1196*/
1197MagickExport unsigned char *GetStringInfoDatum(const StringInfo *string_info)
1198{
1199 assert(string_info != (StringInfo *) NULL);
1200 assert(string_info->signature == MagickCoreSignature);
1201 return(string_info->datum);
1202}
1203
1204/*
1205%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1206% %
1207% %
1208% %
1209% G e t S t r i n g I n f o L e n g t h %
1210% %
1211% %
1212% %
1213%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1214%
1215% GetStringInfoLength() returns the string length.
1216%
1217% The format of the GetStringInfoLength method is:
1218%
1219% size_t GetStringInfoLength(const StringInfo *string_info)
1220%
1221% A description of each parameter follows:
1222%
1223% o string_info: the string info.
1224%
1225*/
1226MagickExport size_t GetStringInfoLength(const StringInfo *string_info)
1227{
1228 assert(string_info != (StringInfo *) NULL);
1229 assert(string_info->signature == MagickCoreSignature);
1230 return(string_info->length);
1231}
1232
1233/*
1234%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1235% %
1236% %
1237% %
1238% G e t S t r i n g I n f o N a m e %
1239% %
1240% %
1241% %
1242%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1243%
1244% GetStringInfoName() returns the name associated with the string.
1245%
1246% The format of the GetStringInfoName method is:
1247%
1248% const char *GetStringInfoName(const StringInfo *string_info)
1249%
1250% A description of each parameter follows:
1251%
1252% o string_info: the string info.
1253%
1254*/
1255MagickExport const char *GetStringInfoName(const StringInfo *string_info)
1256{
1257 assert(string_info != (StringInfo *) NULL);
1258 assert(string_info->signature == MagickCoreSignature);
1259 return(string_info->name);
1260}
1261
1262/*
1263%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1264% %
1265% %
1266% %
1267% G e t S t r i n g I n f o P a t h %
1268% %
1269% %
1270% %
1271%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1272%
1273% GetStringInfoPath() returns the path associated with the string.
1274%
1275% The format of the GetStringInfoPath method is:
1276%
1277% const char *GetStringInfoPath(const StringInfo *string_info)
1278%
1279% A description of each parameter follows:
1280%
1281% o string_info: the string info.
1282%
1283*/
1284MagickExport const char *GetStringInfoPath(const StringInfo *string_info)
1285{
1286 assert(string_info != (StringInfo *) NULL);
1287 assert(string_info->signature == MagickCoreSignature);
1288 return(string_info->path);
1289}
1290
1291/*
1292%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1293% %
1294% %
1295% %
1296+ I n t e r p r e t S i P r e f i x V a l u e %
1297% %
1298% %
1299% %
1300%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1301%
1302% InterpretSiPrefixValue() converts the initial portion of the string to a
1303% double representation. It also recognizes SI prefixes (e.g. B, KB, MiB,
1304% etc.).
1305%
1306% The format of the InterpretSiPrefixValue method is:
1307%
1308% double InterpretSiPrefixValue(const char *value,char **sentinel)
1309%
1310% A description of each parameter follows:
1311%
1312% o value: the string value.
1313%
1314% o sentinel: if sentinel is not NULL, return a pointer to the character
1315% after the last character used in the conversion.
1316%
1317*/
1318MagickExport double InterpretSiPrefixValue(const char *magick_restrict string,
1319 char **magick_restrict sentinel)
1320{
1321 char
1322 *q;
1323
1324 double
1325 value;
1326
1327 value=InterpretLocaleValue(string,&q);
1328 if (q != string)
1329 {
1330 if ((*q >= 'E') && (*q <= 'z'))
1331 {
1332 double
1333 e;
1334
1335 switch ((int) ((unsigned char) *q))
1336 {
1337 case 'q': e=(-30.0); break;
1338 case 'r': e=(-27.0); break;
1339 case 'y': e=(-24.0); break;
1340 case 'z': e=(-21.0); break;
1341 case 'a': e=(-18.0); break;
1342 case 'f': e=(-15.0); break;
1343 case 'p': e=(-12.0); break;
1344 case 'n': e=(-9.0); break;
1345 case 'u': e=(-6.0); break;
1346 case 'm': e=(-3.0); break;
1347 case 'c': e=(-2.0); break;
1348 case 'd': e=(-1.0); break;
1349 case 'h': e=2.0; break;
1350 case 'k': e=3.0; break;
1351 case 'K': e=3.0; break;
1352 case 'M': e=6.0; break;
1353 case 'G': e=9.0; break;
1354 case 'T': e=12.0; break;
1355 case 'P': e=15.0; break;
1356 case 'E': e=18.0; break;
1357 case 'Z': e=21.0; break;
1358 case 'Y': e=24.0; break;
1359 case 'R': e=27.0; break;
1360 case 'Q': e=30.0; break;
1361 default: e=0.0; break;
1362 }
1363 if (e >= MagickEpsilon)
1364 {
1365 if (q[1] == 'i')
1366 {
1367 value*=pow(2.0,e/0.3);
1368 q+=(ptrdiff_t) 2;
1369 }
1370 else
1371 {
1372 value*=pow(10.0,e);
1373 q++;
1374 }
1375 }
1376 }
1377 if ((*q == 'B') || (*q == 'P'))
1378 q++;
1379 }
1380 if (sentinel != (char **) NULL)
1381 *sentinel=q;
1382 return(value);
1383}
1384
1385/*
1386%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1387% %
1388% %
1389% %
1390% I s S t r i n g T r u e %
1391% %
1392% %
1393% %
1394%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1395%
1396% IsStringTrue() returns MagickTrue if the value is "true", "on", "yes" or
1397% "1". Any other string or undefined returns MagickFalse.
1398%
1399% Typically this is used to look at strings (options or artifacts) which
1400% has a default value of "false", when not defined.
1401%
1402% The format of the IsStringTrue method is:
1403%
1404% MagickBooleanType IsStringTrue(const char *value)
1405%
1406% A description of each parameter follows:
1407%
1408% o value: Specifies a pointer to a character array.
1409%
1410*/
1411MagickExport MagickBooleanType IsStringTrue(const char *value)
1412{
1413 if (value == (const char *) NULL)
1414 return(MagickFalse);
1415 if (LocaleCompare(value,"true") == 0)
1416 return(MagickTrue);
1417 if (LocaleCompare(value,"on") == 0)
1418 return(MagickTrue);
1419 if (LocaleCompare(value,"yes") == 0)
1420 return(MagickTrue);
1421 if (LocaleCompare(value,"1") == 0)
1422 return(MagickTrue);
1423 return(MagickFalse);
1424}
1425
1426/*
1427%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1428% %
1429% %
1430% %
1431% I s S t r i n g F a l s e %
1432% %
1433% %
1434% %
1435%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1436%
1437% IsStringFalse() returns MagickTrue if the value is "false", "off", "no" or
1438% "0". Any other string or undefined returns MagickFalse.
1439%
1440% Typically this is used to look at strings (options or artifacts) which
1441% has a default value of "true", when it has not been defined.
1442%
1443% The format of the IsStringFalse method is:
1444%
1445% MagickBooleanType IsStringFalse(const char *value)
1446%
1447% A description of each parameter follows:
1448%
1449% o value: Specifies a pointer to a character array.
1450%
1451*/
1452MagickExport MagickBooleanType IsStringFalse(const char *value)
1453{
1454 if (value == (const char *) NULL)
1455 return(MagickFalse);
1456 if (LocaleCompare(value,"false") == 0)
1457 return(MagickTrue);
1458 if (LocaleCompare(value,"off") == 0)
1459 return(MagickTrue);
1460 if (LocaleCompare(value,"no") == 0)
1461 return(MagickTrue);
1462 if (LocaleCompare(value,"0") == 0)
1463 return(MagickTrue);
1464 return(MagickFalse);
1465}
1466
1467/*
1468%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1469% %
1470% %
1471% %
1472% P r i n t S t r i n g I n f o %
1473% %
1474% %
1475% %
1476%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1477%
1478% PrintStringInfo() prints the string.
1479%
1480% The format of the PrintStringInfo method is:
1481%
1482% void PrintStringInfo(FILE *file,const char *id,
1483% const StringInfo *string_info)
1484%
1485% A description of each parameter follows:
1486%
1487% o file: the file, typically stdout.
1488%
1489% o id: the string id.
1490%
1491% o string_info: the string info.
1492%
1493*/
1494MagickExport void PrintStringInfo(FILE *file,const char *id,
1495 const StringInfo *string_info)
1496{
1497 const unsigned char
1498 *p;
1499
1500 size_t
1501 i,
1502 j;
1503
1504 /*
1505 Check if string is printable.
1506 */
1507 assert(id != (const char *) NULL);
1508 assert(string_info != (StringInfo *) NULL);
1509 assert(string_info->signature == MagickCoreSignature);
1510 p=(const unsigned char *) string_info->datum;
1511 for (i=0; i < string_info->length; i++)
1512 if ((p[i] < 32) && (isspace((int)p[i]) == 0))
1513 break;
1514 (void) FormatLocaleFile(file,"%s(%.20g):\n",id,(double) string_info->length);
1515 if (i == string_info->length)
1516 {
1517 for (i = 0; i < string_info->length; i++)
1518 (void) fputc(p[i],file);
1519 (void) fputc('\n',file);
1520 return;
1521 }
1522 /*
1523 Convert string to a HEX list.
1524 */
1525 for (i=0; i < string_info->length; i+=CharsPerLine)
1526 {
1527 (void) FormatLocaleFile(file,"0x%08lx: ",(unsigned long) i);
1528 for (j = 0; j < MagickMin(string_info->length-i, CharsPerLine); j++)
1529 {
1530 (void) FormatLocaleFile(file,"%02lx",(unsigned long) (p[i+j]) & 0xff);
1531 if (((j+1) % 0x04) == 0)
1532 (void) fputc(' ',file);
1533 }
1534 /*
1535 Padding.
1536 */
1537 for ( ; j < CharsPerLine; j++)
1538 {
1539 (void) fputc(' ',file);
1540 (void) fputc(' ',file);
1541 if (((j+1) % 0x04) == 0)
1542 (void) fputc(' ',file);
1543 }
1544 (void) fputc(' ',file);
1545 /*
1546 ASCII section.
1547 */
1548 for (j=0; j < MagickMin(string_info->length-i,CharsPerLine); j++)
1549 {
1550 unsigned char c = p[i+j];
1551 if (isprint((int) c) != 0)
1552 (void) fputc(c,file);
1553 else
1554 (void) fputc('-',file);
1555 }
1556 (void) fputc('\n',file);
1557 }
1558}
1559
1560/*
1561%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1562% %
1563% %
1564% %
1565% R e s e t S t r i n g I n f o %
1566% %
1567% %
1568% %
1569%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1570%
1571% ResetStringInfo() reset the string to all null bytes.
1572%
1573% The format of the ResetStringInfo method is:
1574%
1575% void ResetStringInfo(StringInfo *string_info)
1576%
1577% A description of each parameter follows:
1578%
1579% o string_info: the string info.
1580%
1581*/
1582MagickExport void ResetStringInfo(StringInfo *string_info)
1583{
1584 assert(string_info != (StringInfo *) NULL);
1585 assert(string_info->signature == MagickCoreSignature);
1586 (void) memset(string_info->datum,0,string_info->length);
1587}
1588
1589/*
1590%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1591% %
1592% %
1593% %
1594% S a n t i z e S t r i n g %
1595% %
1596% %
1597% %
1598%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1599%
1600% SanitizeString() returns a new string with all characters removed except
1601% letters, digits and !#$%&'*+-=?^_`{|}~@.[].
1602%
1603% Free the sanitized string with DestroyString().
1604%
1605% The format of the SanitizeString method is:
1606%
1607% char *SanitizeString(const char *source)
1608%
1609% A description of each parameter follows:
1610%
1611% o source: A character string.
1612%
1613*/
1614MagickExport char *SanitizeString(const char *source)
1615{
1616 char
1617 *sanitize_source;
1618
1619 const char
1620 *q;
1621
1622 char
1623 *p;
1624
1625 static char
1626 allowlist[] =
1627 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 "
1628 "$-_.+!*'(),{}|\\^~[]`\"><#%;/?:@&=";
1629
1630 sanitize_source=AcquireString(source);
1631 p=sanitize_source;
1632 q=sanitize_source+strlen(sanitize_source);
1633 for (p+=strspn(p,allowlist); p != q; p+=(ptrdiff_t) strspn(p,allowlist))
1634 *p='_';
1635 return(sanitize_source);
1636}
1637
1638/*
1639%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1640% %
1641% %
1642% %
1643% S e t S t r i n g I n f o %
1644% %
1645% %
1646% %
1647%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1648%
1649% SetStringInfo() copies the source string to the destination string.
1650%
1651% The format of the SetStringInfo method is:
1652%
1653% void SetStringInfo(StringInfo *string_info,const StringInfo *source)
1654%
1655% A description of each parameter follows:
1656%
1657% o string_info: the string info.
1658%
1659% o source: the source string.
1660%
1661*/
1662MagickExport void SetStringInfo(StringInfo *string_info,
1663 const StringInfo *source)
1664{
1665 assert(string_info != (StringInfo *) NULL);
1666 assert(string_info->signature == MagickCoreSignature);
1667 assert(source != (StringInfo *) NULL);
1668 assert(source->signature == MagickCoreSignature);
1669 if (string_info->length == 0)
1670 return;
1671 (void) memset(string_info->datum,0,string_info->length);
1672 (void) memcpy(string_info->datum,source->datum,MagickMin(string_info->length,
1673 source->length));
1674}
1675
1676/*
1677%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1678% %
1679% %
1680% %
1681% S e t S t r i n g I n f o D a t u m %
1682% %
1683% %
1684% %
1685%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1686%
1687% SetStringInfoDatum() copies bytes from the source string for the length of
1688% the destination string.
1689%
1690% The format of the SetStringInfoDatum method is:
1691%
1692% void SetStringInfoDatum(StringInfo *string_info,
1693% const unsigned char *source)
1694%
1695% A description of each parameter follows:
1696%
1697% o string_info: the string info.
1698%
1699% o source: the source string.
1700%
1701*/
1702MagickExport void SetStringInfoDatum(StringInfo *string_info,
1703 const unsigned char *source)
1704{
1705 assert(string_info != (StringInfo *) NULL);
1706 assert(string_info->signature == MagickCoreSignature);
1707 if (string_info->length != 0)
1708 (void) memcpy(string_info->datum,source,string_info->length);
1709}
1710
1711/*
1712%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1713% %
1714% %
1715% %
1716% S e t S t r i n g I n f o L e n g t h %
1717% %
1718% %
1719% %
1720%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1721%
1722% SetStringInfoLength() set the string length to the specified value.
1723%
1724% The format of the SetStringInfoLength method is:
1725%
1726% void SetStringInfoLength(StringInfo *string_info,const size_t length)
1727%
1728% A description of each parameter follows:
1729%
1730% o string_info: the string info.
1731%
1732% o length: the string length.
1733%
1734*/
1735MagickExport void SetStringInfoLength(StringInfo *string_info,
1736 const size_t length)
1737{
1738 assert(string_info != (StringInfo *) NULL);
1739 assert(string_info->signature == MagickCoreSignature);
1740 if (string_info->length == length)
1741 return;
1742 if (~length < MagickPathExtent)
1743 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1744 string_info->length=length;
1745 if (string_info->datum == (unsigned char *) NULL)
1746 string_info->datum=(unsigned char *) AcquireQuantumMemory(length+
1747 MagickPathExtent,sizeof(*string_info->datum));
1748 else
1749 string_info->datum=(unsigned char *) ResizeQuantumMemory(string_info->datum,
1750 length+MagickPathExtent,sizeof(*string_info->datum));
1751 if (string_info->datum == (unsigned char *) NULL)
1752 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1753}
1754
1755/*
1756%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1757% %
1758% %
1759% %
1760% S e t S t r i n g I n f o N a m e %
1761% %
1762% %
1763% %
1764%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1765%
1766% SetStringInfoName() sets the name associated with the string.
1767%
1768% The format of the SetStringInfoName method is:
1769%
1770% void SetStringInfoName(StringInfo *string_info,const char *name)
1771%
1772% A description of each parameter follows:
1773%
1774% o string_info: the string info.
1775%
1776% o name: the name.
1777%
1778*/
1779MagickExport void SetStringInfoName(StringInfo *string_info,const char *name)
1780{
1781 assert(string_info != (StringInfo *) NULL);
1782 assert(string_info->signature == MagickCoreSignature);
1783 assert(name != (const char *) NULL);
1784 string_info->name=ConstantString(name);
1785}
1786
1787/*
1788%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1789% %
1790% %
1791% %
1792% S e t S t r i n g I n f o P a t h %
1793% %
1794% %
1795% %
1796%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1797%
1798% SetStringInfoPath() sets the path associated with the string.
1799%
1800% The format of the SetStringInfoPath method is:
1801%
1802% void SetStringInfoPath(StringInfo *string_info,const char *path)
1803%
1804% A description of each parameter follows:
1805%
1806% o string_info: the string info.
1807%
1808% o path: the path.
1809%
1810*/
1811MagickExport void SetStringInfoPath(StringInfo *string_info,const char *path)
1812{
1813 assert(string_info != (StringInfo *) NULL);
1814 assert(string_info->signature == MagickCoreSignature);
1815 assert(path != (const char *) NULL);
1816 string_info->path=ConstantString(path);
1817}
1818
1819/*
1820%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1821% %
1822% %
1823% %
1824% S p l i t S t r i n g I n f o %
1825% %
1826% %
1827% %
1828%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1829%
1830% SplitStringInfo() splits a string into two and returns it.
1831%
1832% The format of the SplitStringInfo method is:
1833%
1834% StringInfo *SplitStringInfo(StringInfo *string_info,const size_t offset)
1835%
1836% A description of each parameter follows:
1837%
1838% o string_info: the string info.
1839%
1840*/
1841MagickExport StringInfo *SplitStringInfo(StringInfo *string_info,
1842 const size_t offset)
1843{
1845 *split_info;
1846
1847 assert(string_info != (StringInfo *) NULL);
1848 assert(string_info->signature == MagickCoreSignature);
1849 if (offset > string_info->length)
1850 return((StringInfo *) NULL);
1851 split_info=AcquireStringInfo(offset);
1852 SetStringInfo(split_info,string_info);
1853 (void) memmove(string_info->datum,string_info->datum+offset,
1854 string_info->length-offset+MagickPathExtent);
1855 SetStringInfoLength(string_info,string_info->length-offset);
1856 return(split_info);
1857}
1858
1859/*
1860%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1861% %
1862% %
1863% %
1864% S t r i n g I n f o T o D i g e s t %
1865% %
1866% %
1867% %
1868%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1869%
1870% StringInfoToDigest() converts a string info string to a hex digest.
1871%
1872% The format of the StringInfoToString method is:
1873%
1874% char *StringInfoToDigest(const StringInfo *signature)
1875%
1876% A description of each parameter follows:
1877%
1878% o string_info: the string.
1879%
1880*/
1881MagickExport char *StringInfoToDigest(const StringInfo *signature)
1882{
1883 char
1884 *digest;
1885
1887 *signature_info;
1888
1889 signature_info=AcquireSignatureInfo();
1890 UpdateSignature(signature_info,signature);
1891 FinalizeSignature(signature_info);
1892 digest=StringInfoToHexString(GetSignatureDigest(signature_info));
1893 signature_info=DestroySignatureInfo(signature_info);
1894 return(digest);
1895}
1896
1897/*
1898%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1899% %
1900% %
1901% %
1902% S t r i n g I n f o T o H e x S t r i n g %
1903% %
1904% %
1905% %
1906%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1907%
1908% StringInfoToHexString() converts a string info string to a C string.
1909%
1910% The format of the StringInfoToHexString method is:
1911%
1912% char *StringInfoToHexString(const StringInfo *string_info)
1913%
1914% A description of each parameter follows:
1915%
1916% o string_info: the string.
1917%
1918*/
1919MagickExport char *StringInfoToHexString(const StringInfo *string_info)
1920{
1921 char
1922 *string;
1923
1924 const unsigned char
1925 *p;
1926
1927 ssize_t
1928 i;
1929
1930 unsigned char
1931 *q;
1932
1933 size_t
1934 length;
1935
1936 unsigned char
1937 hex_digits[16];
1938
1939 length=string_info->length;
1940 if (~length < MagickPathExtent)
1941 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
1942 string=(char *) AcquireQuantumMemory(length+MagickPathExtent,2*
1943 sizeof(*string));
1944 if (string == (char *) NULL)
1945 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
1946 hex_digits[0]='0';
1947 hex_digits[1]='1';
1948 hex_digits[2]='2';
1949 hex_digits[3]='3';
1950 hex_digits[4]='4';
1951 hex_digits[5]='5';
1952 hex_digits[6]='6';
1953 hex_digits[7]='7';
1954 hex_digits[8]='8';
1955 hex_digits[9]='9';
1956 hex_digits[10]='a';
1957 hex_digits[11]='b';
1958 hex_digits[12]='c';
1959 hex_digits[13]='d';
1960 hex_digits[14]='e';
1961 hex_digits[15]='f';
1962 p=string_info->datum;
1963 q=(unsigned char *) string;
1964 for (i=0; i < (ssize_t) string_info->length; i++)
1965 {
1966 *q++=hex_digits[(*p >> 4) & 0x0f];
1967 *q++=hex_digits[*p & 0x0f];
1968 p++;
1969 }
1970 *q='\0';
1971 return(string);
1972}
1973
1974/*
1975%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1976% %
1977% %
1978% %
1979% S t r i n g I n f o T o S t r i n g %
1980% %
1981% %
1982% %
1983%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1984%
1985% StringInfoToString() converts a string info string to a C string.
1986%
1987% The format of the StringInfoToString method is:
1988%
1989% char *StringInfoToString(const StringInfo *string_info)
1990%
1991% A description of each parameter follows:
1992%
1993% o string_info: the string.
1994%
1995*/
1996MagickExport char *StringInfoToString(const StringInfo *string_info)
1997{
1998 char
1999 *string;
2000
2001 size_t
2002 length;
2003
2004 string=(char *) NULL;
2005 length=string_info->length;
2006 if (~length >= (MagickPathExtent-1))
2007 string=(char *) AcquireQuantumMemory(length+MagickPathExtent,
2008 sizeof(*string));
2009 if (string == (char *) NULL)
2010 return((char *) NULL);
2011 (void) memcpy(string,(char *) string_info->datum,length*sizeof(*string));
2012 string[length]='\0';
2013 return(string);
2014}
2015
2016/*
2017%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2018% %
2019% %
2020% %
2021% S t r i n g T o A r g v %
2022% %
2023% %
2024% %
2025%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2026%
2027% StringToArgv() converts a text string into command line arguments.
2028% The 'argv' array of arguments, is returned while the number of arguments
2029% is returned via the provided integer variable pointer.
2030%
2031% Simple 'word' tokenizer, which allows for each word to be optionally
2032% quoted. However it will not allow use of partial quotes, or escape
2033% characters.
2034%
2035% The format of the StringToArgv method is:
2036%
2037% char **StringToArgv(const char *text,int *argc)
2038%
2039% A description of each parameter follows:
2040%
2041% o argv: Method StringToArgv returns the string list unless an error
2042% occurs, otherwise NULL.
2043%
2044% o text: Specifies the string to segment into a list.
2045%
2046% o argc: This integer pointer returns the number of arguments in the
2047% list.
2048%
2049*/
2050MagickExport char **StringToArgv(const char *text,int *argc)
2051{
2052 char
2053 **argv;
2054
2055 const char
2056 *p,
2057 *q;
2058
2059 ssize_t
2060 i;
2061
2062 *argc=0;
2063 if (text == (char *) NULL)
2064 return((char **) NULL);
2065 /*
2066 Determine the number of arguments.
2067 */
2068 for (p=text; *p != '\0'; )
2069 {
2070 while (isspace((int) ((unsigned char) *p)) != 0)
2071 p++;
2072 if (*p == '\0')
2073 break;
2074 (*argc)++;
2075 if (*p == '"')
2076 for (p++; (*p != '"') && (*p != '\0'); p++) ;
2077 if (*p == '\'')
2078 for (p++; (*p != '\'') && (*p != '\0'); p++) ;
2079 while ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '\0'))
2080 p++;
2081 }
2082 (*argc)++;
2083 argv=(char **) AcquireQuantumMemory((size_t) *argc+1UL,sizeof(*argv));
2084 if (argv == (char **) NULL)
2085 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertStringToARGV");
2086 /*
2087 Convert string to an ASCII list.
2088 */
2089 argv[0]=AcquireString("magick");
2090 p=text;
2091 for (i=1; i < (ssize_t) *argc; i++)
2092 {
2093 while (isspace((int) ((unsigned char) *p)) != 0)
2094 p++;
2095 q=p;
2096 if (*q == '"')
2097 {
2098 p++;
2099 for (q++; (*q != '"') && (*q != '\0'); q++) ;
2100 }
2101 else
2102 if (*q == '\'')
2103 {
2104 p++;
2105 for (q++; (*q != '\'') && (*q != '\0'); q++) ;
2106 }
2107 else
2108 while ((isspace((int) ((unsigned char) *q)) == 0) && (*q != '\0'))
2109 q++;
2110 argv[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+MagickPathExtent,
2111 sizeof(**argv));
2112 if (argv[i] == (char *) NULL)
2113 {
2114 for (i--; i >= 0; i--)
2115 argv[i]=DestroyString(argv[i]);
2116 argv=(char **) RelinquishMagickMemory(argv);
2117 ThrowFatalException(ResourceLimitFatalError,
2118 "UnableToConvertStringToARGV");
2119 }
2120 (void) memcpy(argv[i],p,(size_t) (q-p));
2121 argv[i][q-p]='\0';
2122 p=q;
2123 while ((isspace((int) ((unsigned char) *p)) == 0) && (*p != '\0'))
2124 p++;
2125 }
2126 argv[i]=(char *) NULL;
2127 return(argv);
2128}
2129
2130/*
2131%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2132% %
2133% %
2134% %
2135% S t r i n g T o A r r a y O f D o u b l e s %
2136% %
2137% %
2138% %
2139%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2140%
2141% StringToArrayOfDoubles() converts a string of space or comma separated
2142% numbers into array of floating point numbers (doubles). Any number that
2143% fails to parse properly will produce a syntax error. As will two commas
2144% without a number between them. However a final comma at the end will
2145% not be regarded as an error so as to simplify automatic list generation.
2146%
2147% A NULL value is returned on syntax or memory errors.
2148%
2149% Use RelinquishMagickMemory() to free returned array when finished.
2150%
2151% The format of the StringToArrayOfDoubles method is:
2152%
2153% double *StringToArrayOfDoubles(const char *string,size_t *count,
2154% ExceptionInfo *exception)
2155%
2156% A description of each parameter follows:
2157%
2158% o string: the string containing the comma/space separated values.
2159%
2160% o count: returns number of arguments in returned array
2161%
2162% o exception: return any errors or warnings in this structure.
2163%
2164*/
2165MagickExport double *StringToArrayOfDoubles(const char *string,ssize_t *count,
2166 ExceptionInfo *exception)
2167{
2168 char
2169 *q;
2170
2171 const char
2172 *p;
2173
2174 double
2175 *array;
2176
2177 ssize_t
2178 i;
2179
2180 /*
2181 Determine count of values, and check syntax.
2182 */
2183 assert(exception != (ExceptionInfo *) NULL);
2184 assert(exception->signature == MagickCoreSignature);
2185 *count=0;
2186 if (string == (char *) NULL)
2187 return((double *) NULL); /* no value found */
2188 i=0;
2189 p=string;
2190 while (*p != '\0')
2191 {
2192 (void) StringToDouble(p,&q); /* get value - ignores leading space */
2193 if (p == q)
2194 return((double *) NULL); /* no value found */
2195 p=q;
2196 i++; /* increment value count */
2197 while (isspace((int) ((unsigned char) *p)) != 0)
2198 p++; /* skip spaces */
2199 if (*p == ',')
2200 p++; /* skip comma */
2201 while (isspace((int) ((unsigned char) *p)) != 0)
2202 p++; /* and more spaces */
2203 }
2204 /*
2205 Allocate floating point argument list.
2206 */
2207 *count=i;
2208 array=(double *) AcquireQuantumMemory((size_t) i,sizeof(*array));
2209 if (array == (double *) NULL)
2210 {
2211 (void) ThrowMagickException(exception,GetMagickModule(),
2212 ResourceLimitError,"MemoryAllocationFailed","`%s'","");
2213 return((double *) NULL);
2214 }
2215 /*
2216 Fill in the floating point values.
2217 */
2218 i=0;
2219 p=string;
2220 while ((*p != '\0') && (i < *count))
2221 {
2222 array[i++]=StringToDouble(p,&q);
2223 p=q;
2224 while ((isspace((int) ((unsigned char) *p)) != 0) || (*p == ','))
2225 p++;
2226 }
2227 return(array);
2228}
2229
2230/*
2231%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2232% %
2233% %
2234% %
2235+ S t r i n g T o k e n %
2236% %
2237% %
2238% %
2239%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2240%
2241% StringToken() looks for any one of given delimiters and splits the string
2242% into two separate strings by replacing the delimiter character found with a
2243% null character.
2244%
2245% The given string pointer is changed to point to the string following the
2246% delimiter character found, or NULL. A pointer to the start of the
2247% string is returned, representing the token before the delimiter.
2248%
2249% StringToken() is similar to the strtok() C library method, but with
2250% multiple delimiter characters rather than a delimiter string.
2251%
2252% The format of the StringToken method is:
2253%
2254% char *StringToken(const char *delimiters,char **string)
2255%
2256% A description of each parameter follows:
2257%
2258% o delimiters: one or more delimiters.
2259%
2260% o string: return the first token in the string. If none is found, return
2261% NULL.
2262%
2263*/
2264MagickExport char *StringToken(const char *delimiters,char **string)
2265{
2266 char
2267 *q;
2268
2269 char
2270 *p;
2271
2272 const char
2273 *r;
2274
2275 int
2276 c,
2277 d;
2278
2279 p=(*string);
2280 if (p == (char *) NULL)
2281 return((char *) NULL);
2282 q=p;
2283 for ( ; ; )
2284 {
2285 c=(*p++);
2286 r=delimiters;
2287 do
2288 {
2289 d=(*r++);
2290 if (c == d)
2291 {
2292 if (c == '\0')
2293 p=(char *) NULL;
2294 else
2295 p[-1]='\0';
2296 *string=p;
2297 return(q);
2298 }
2299 } while (d != '\0');
2300 }
2301}
2302
2303/*
2304%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2305% %
2306% %
2307% %
2308% S t r i n g T o L i s t %
2309% %
2310% %
2311% %
2312%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2313%
2314% StringToList() converts a text string into a list by segmenting the text
2315% string at each carriage return discovered. The list is converted to HEX
2316% characters if any control characters are discovered within the text string.
2317%
2318% The format of the StringToList method is:
2319%
2320% char **StringToList(const char *text)
2321%
2322% A description of each parameter follows:
2323%
2324% o text: Specifies the string to segment into a list.
2325%
2326*/
2327MagickExport char **StringToList(const char *text)
2328{
2329 return(StringToStrings(text,(size_t *) NULL));
2330}
2331
2332/*
2333%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2334% %
2335% %
2336% %
2337% S t r i n g T o S t r i n g s %
2338% %
2339% %
2340% %
2341%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2342%
2343% StringToStrings() converts a text string into a list by segmenting the text
2344% string at each carriage return discovered. The list is converted to HEX
2345% characters if any control characters are discovered within the text string.
2346%
2347% The format of the StringToList method is:
2348%
2349% char **StringToList(const char *text,size_t *lines)
2350%
2351% A description of each parameter follows:
2352%
2353% o text: Specifies the string to segment into a list.
2354%
2355% o count: Return value for the number of items in the list.
2356%
2357*/
2358MagickExport char **StringToStrings(const char *text,size_t *count)
2359{
2360 char
2361 **textlist;
2362
2363 const char
2364 *p;
2365
2366 ssize_t
2367 i;
2368
2369 size_t
2370 lines;
2371
2372 if (text == (char *) NULL)
2373 {
2374 if (count != (size_t *) NULL)
2375 *count=0;
2376 return((char **) NULL);
2377 }
2378 for (p=text; *p != '\0'; p++)
2379 if (((int) ((unsigned char) *p) < 32) &&
2380 (isspace((int) ((unsigned char) *p)) == 0))
2381 break;
2382 if (*p == '\0')
2383 {
2384 const char
2385 *q;
2386
2387 /*
2388 Convert string to an ASCII list.
2389 */
2390 lines=1;
2391 for (p=text; *p != '\0'; p++)
2392 if (*p == '\n')
2393 lines++;
2394 textlist=(char **) AcquireQuantumMemory((size_t) lines+1UL,
2395 sizeof(*textlist));
2396 if (textlist == (char **) NULL)
2397 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2398 p=text;
2399 for (i=0; i < (ssize_t) lines; i++)
2400 {
2401 for (q=p; *q != '\0'; q++)
2402 if ((*q == '\r') || (*q == '\n'))
2403 break;
2404 textlist[i]=(char *) AcquireQuantumMemory((size_t) (q-p)+1,
2405 sizeof(**textlist));
2406 if (textlist[i] == (char *) NULL)
2407 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2408 (void) memcpy(textlist[i],p,(size_t) (q-p));
2409 textlist[i][q-p]='\0';
2410 if (*q == '\r')
2411 q++;
2412 p=q+1;
2413 }
2414 }
2415 else
2416 {
2417 char
2418 hex_string[MagickPathExtent];
2419
2420 char
2421 *q;
2422
2423 ssize_t
2424 j;
2425
2426 /*
2427 Convert string to a HEX list.
2428 */
2429 lines=(size_t) (strlen(text)/CharsPerLine)+1;
2430 textlist=(char **) AcquireQuantumMemory((size_t) lines+1UL,
2431 sizeof(*textlist));
2432 if (textlist == (char **) NULL)
2433 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2434 p=text;
2435 for (i=0; i < (ssize_t) lines; i++)
2436 {
2437 size_t
2438 length;
2439
2440 textlist[i]=(char *) AcquireQuantumMemory(2UL*MagickPathExtent,
2441 sizeof(**textlist));
2442 if (textlist[i] == (char *) NULL)
2443 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2444 (void) FormatLocaleString(textlist[i],MagickPathExtent,"0x%08lx: ",
2445 (long) (CharsPerLine*i));
2446 q=textlist[i]+strlen(textlist[i]);
2447 length=strlen(p);
2448 for (j=1; j <= (ssize_t) MagickMin(length,CharsPerLine); j++)
2449 {
2450 (void) FormatLocaleString(hex_string,MagickPathExtent,"%02x",*(p+j));
2451 (void) CopyMagickString(q,hex_string,MagickPathExtent);
2452 q+=(ptrdiff_t) 2;
2453 if ((j % 0x04) == 0)
2454 *q++=' ';
2455 }
2456 for ( ; j <= CharsPerLine; j++)
2457 {
2458 *q++=' ';
2459 *q++=' ';
2460 if ((j % 0x04) == 0)
2461 *q++=' ';
2462 }
2463 *q++=' ';
2464 for (j=1; j <= (ssize_t) MagickMin(length,CharsPerLine); j++)
2465 {
2466 if (isprint((int) ((unsigned char) *p)) != 0)
2467 *q++=(*p);
2468 else
2469 *q++='-';
2470 p++;
2471 }
2472 *q='\0';
2473 textlist[i]=(char *) ResizeQuantumMemory(textlist[i],(size_t) (q-
2474 textlist[i]+1),sizeof(**textlist));
2475 if (textlist[i] == (char *) NULL)
2476 ThrowFatalException(ResourceLimitFatalError,"UnableToConvertText");
2477 }
2478 }
2479 if (count != (size_t *) NULL)
2480 *count=lines;
2481 textlist[i]=(char *) NULL;
2482 return(textlist);
2483}
2484
2485/*
2486%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2487% %
2488% %
2489% %
2490% S t r i n g T o S t r i n g I n f o %
2491% %
2492% %
2493% %
2494%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2495%
2496% StringToStringInfo() converts a string to a StringInfo type.
2497%
2498% The format of the StringToStringInfo method is:
2499%
2500% StringInfo *StringToStringInfo(const char *string)
2501%
2502% A description of each parameter follows:
2503%
2504% o string: The string.
2505%
2506*/
2507MagickExport StringInfo *StringToStringInfo(const char *string)
2508{
2510 *string_info;
2511
2512 assert(string != (const char *) NULL);
2513 string_info=AcquireStringInfo(strlen(string));
2514 SetStringInfoDatum(string_info,(const unsigned char *) string);
2515 return(string_info);
2516}
2517
2518/*
2519%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2520% %
2521% %
2522% %
2523% S t r i p M a g i c k S t r i n g %
2524% %
2525% %
2526% %
2527%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2528%
2529% StripMagickString() strips any whitespace or quotes from the beginning and
2530% end of a string of characters. It returns the stripped string length.
2531%
2532% The format of the StripMagickString method is:
2533%
2534% size_t StripMagickString(char *message)
2535%
2536% A description of each parameter follows:
2537%
2538% o message: Specifies an array of characters.
2539%
2540*/
2541
2542MagickExport void StripString(char *message)
2543{
2544 (void) StripMagickString(message);
2545}
2546
2547MagickExport size_t StripMagickString(char *message)
2548{
2549 char
2550 *p,
2551 *q;
2552
2553 size_t
2554 length;
2555
2556 assert(message != (char *) NULL);
2557 if (*message == '\0')
2558 return(0);
2559 length=strlen(message);
2560 if (length == 1)
2561 return(1);
2562 p=message;
2563 while (isspace((int) ((unsigned char) *p)) != 0)
2564 p++;
2565 if ((*p == '\'') || (*p == '"'))
2566 p++;
2567 q=message+length-1;
2568 while ((isspace((int) ((unsigned char) *q)) != 0) && (q > p))
2569 q--;
2570 if (q > p)
2571 if ((*q == '\'') || (*q == '"'))
2572 q--;
2573 (void) memmove(message,p,(size_t) (q-p+1));
2574 message[q-p+1]='\0';
2575 for (p=message; *p != '\0'; p++)
2576 if (*p == '\n')
2577 *p=' ';
2578 return((size_t) (q-p+1));
2579}
2580
2581/*
2582%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2583% %
2584% %
2585% %
2586% S u b s t i t u t e S t r i n g %
2587% %
2588% %
2589% %
2590%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2591%
2592% SubstituteString() performs string substitution on a string, replacing the
2593% string with the substituted version. Buffer must be allocated from the heap.
2594% If the string is matched and status, MagickTrue is returned otherwise
2595% MagickFalse.
2596%
2597% The format of the SubstituteString method is:
2598%
2599% MagickBooleanType SubstituteString(char **string,const char *search,
2600% const char *replace)
2601%
2602% A description of each parameter follows:
2603%
2604% o string: the string to perform replacements on; replaced with new
2605% allocation if a replacement is made.
2606%
2607% o search: search for this string.
2608%
2609% o replace: replace any matches with this string.
2610%
2611*/
2612MagickExport MagickBooleanType SubstituteString(char **string,
2613 const char *search,const char *replace)
2614{
2615 MagickBooleanType
2616 status;
2617
2618 char
2619 *p;
2620
2621 size_t
2622 extent,
2623 replace_extent,
2624 search_extent;
2625
2626 ssize_t
2627 offset;
2628
2629 status=MagickFalse;
2630 search_extent=0,
2631 replace_extent=0;
2632 for (p=strchr(*string,*search); p != (char *) NULL; p=strchr(p+1,*search))
2633 {
2634 if (search_extent == 0)
2635 search_extent=strlen(search);
2636 if (strncmp(p,search,search_extent) != 0)
2637 continue;
2638 /*
2639 We found a match.
2640 */
2641 status=MagickTrue;
2642 if (replace_extent == 0)
2643 replace_extent=strlen(replace);
2644 if (replace_extent > search_extent)
2645 {
2646 /*
2647 Make room for the replacement string.
2648 */
2649 offset=(ssize_t) (p-(*string));
2650 extent=strlen(*string)+replace_extent-search_extent+1;
2651 *string=(char *) ResizeQuantumMemory(*string,
2652 OverAllocateMemory(extent+MagickPathExtent),sizeof(*p));
2653 if (*string == (char *) NULL)
2654 ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
2655 p=(*string)+offset;
2656 }
2657 /*
2658 Replace string.
2659 */
2660 if (search_extent != replace_extent)
2661 (void) memmove(p+replace_extent,p+search_extent,
2662 strlen(p+search_extent)+1);
2663 (void) memcpy(p,replace,replace_extent);
2664 p+=(ptrdiff_t) replace_extent-1;
2665 }
2666 return(status);
2667}