Coverage Report

Created: 2026-09-13 07:02

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/imagemagick/MagickCore/magick.c
Line
Count
Source
1
/*
2
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3
%                                                                             %
4
%                                                                             %
5
%                                                                             %
6
%                  M   M   AAA    GGGG  IIIII   CCCC  K   K                   %
7
%                  MM MM  A   A  G        I    C      K  K                    %
8
%                  M M M  AAAAA  G GGG    I    C      KKK                     %
9
%                  M   M  A   A  G   G    I    C      K  K                    %
10
%                  M   M  A   A   GGGG  IIIII   CCCC  K   K                   %
11
%                                                                             %
12
%                                                                             %
13
%               Methods to Read or List ImageMagick Image formats             %
14
%                                                                             %
15
%                            Software Design                                  %
16
%                            Bob Friesenhahn                                  %
17
%                                 Cristy                                      %
18
%                             November 1998                                   %
19
%                                                                             %
20
%                                                                             %
21
%  Copyright @ 1999 ImageMagick Studio LLC, a non-profit organization         %
22
%  dedicated to making software imaging solutions freely available.           %
23
%                                                                             %
24
%  You may not use this file except in compliance with the License.  You may  %
25
%  obtain a copy of the License at                                            %
26
%                                                                             %
27
%    https://imagemagick.org/license/                                         %
28
%                                                                             %
29
%  Unless required by applicable law or agreed to in writing, software        %
30
%  distributed under the License is distributed on an "AS IS" BASIS,          %
31
%  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
32
%  See the License for the specific language governing permissions and        %
33
%  limitations under the License.                                             %
34
%                                                                             %
35
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
36
%
37
%
38
*/
39

40
/*
41
  Include declarations.
42
*/
43
#include "MagickCore/studio.h"
44
#include "MagickCore/annotate-private.h"
45
#include "MagickCore/blob.h"
46
#include "MagickCore/blob-private.h"
47
#include "MagickCore/cache.h"
48
#include "MagickCore/cache-private.h"
49
#include "MagickCore/coder-private.h"
50
#include "MagickCore/client.h"
51
#include "MagickCore/color-private.h"
52
#include "MagickCore/configure-private.h"
53
#include "MagickCore/constitute-private.h"
54
#include "MagickCore/delegate-private.h"
55
#include "MagickCore/draw.h"
56
#include "MagickCore/exception.h"
57
#include "MagickCore/exception-private.h"
58
#include "MagickCore/locale-private.h"
59
#include "MagickCore/log-private.h"
60
#include "MagickCore/magic-private.h"
61
#include "MagickCore/magick.h"
62
#include "MagickCore/magick-private.h"
63
#include "MagickCore/memory_.h"
64
#include "MagickCore/mime-private.h"
65
#include "MagickCore/monitor-private.h"
66
#include "MagickCore/module.h"
67
#include "MagickCore/module-private.h"
68
#include "MagickCore/mutex.h"
69
#include "MagickCore/nt-base-private.h"
70
#include "MagickCore/nt-feature.h"
71
#include "MagickCore/opencl-private.h"
72
#include "MagickCore/option-private.h"
73
#include "MagickCore/random-private.h"
74
#include "MagickCore/registry.h"
75
#include "MagickCore/registry-private.h"
76
#include "MagickCore/resource_.h"
77
#include "MagickCore/resource-private.h"
78
#include "MagickCore/policy.h"
79
#include "MagickCore/policy-private.h"
80
#include "MagickCore/mutex.h"
81
#include "MagickCore/semaphore.h"
82
#include "MagickCore/semaphore-private.h"
83
#include "MagickCore/signature-private.h"
84
#include "MagickCore/splay-tree.h"
85
#include "MagickCore/static.h"
86
#include "MagickCore/string_.h"
87
#include "MagickCore/string-private.h"
88
#include "MagickCore/thread_.h"
89
#include "MagickCore/thread-private.h"
90
#include "MagickCore/timer-private.h"
91
#include "MagickCore/type-private.h"
92
#include "MagickCore/token.h"
93
#include "MagickCore/utility.h"
94
#include "MagickCore/utility-private.h"
95
#include "MagickCore/xwindow-private.h"
96

97
/*
98
  Define declarations.
99
*/
100
#if !defined(SIG_DFL)
101
# define SIG_DFL  ((SignalHandler *) 0)
102
#endif
103
#if !defined(SIG_ERR)
104
# define SIG_ERR  ((SignalHandler *) -1)
105
#endif
106
#if !defined(SIGMAX)
107
#define SIGMAX  64
108
#endif
109

110
/*
111
  Typedef declarations.
112
*/
113
typedef void SignalHandler(int);
114

115
/*
116
  Global declarations.
117
*/
118
static SemaphoreInfo
119
  *magick_semaphore = (SemaphoreInfo *) NULL;
120
121
static SignalHandler
122
  *signal_handlers[SIGMAX] = { (SignalHandler *) NULL };
123
124
static SplayTreeInfo
125
  *magick_list = (SplayTreeInfo *) NULL;
126
127
static volatile MagickBooleanType
128
  magickcore_instantiated = MagickFalse,
129
  magickcore_signal_in_progress = MagickFalse,
130
  magick_list_initialized = MagickFalse;
131
132
static int
133
  magick_precision = 0;
134

135
/*
136
  Forward declarations.
137
*/
138
static MagickBooleanType
139
  IsMagickTreeInstantiated(ExceptionInfo *);
140

141
/*
142
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
143
%                                                                             %
144
%                                                                             %
145
%                                                                             %
146
%    A c q u i r e M a g i c k I n f o                                        %
147
%                                                                             %
148
%                                                                             %
149
%                                                                             %
150
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
151
%
152
%  AcquireMagickInfo() allocates a MagickInfo structure and initializes the
153
%  members to default values.
154
%
155
%  The format of the AcquireMagickInfo method is:
156
%
157
%      MagickInfo *AcquireMagickInfo(const char *magick_module,
158
%        const char *name,const char *description)
159
%
160
%  A description of each parameter follows:
161
%
162
%    o magick_module: a character string that represents the module associated
163
%      with the MagickInfo structure.
164
%
165
%    o name: a character string that represents the image format associated
166
%      with the MagickInfo structure.
167
%
168
%    o description: a character string that represents the image format
169
%      associated with the MagickInfo structure.
170
%
171
*/
172
MagickExport MagickInfo *AcquireMagickInfo(const char *magick_module,
173
  const char *name,const char *description)
174
2.87k
{
175
2.87k
  MagickInfo
176
2.87k
    *magick_info;
177
178
2.87k
  assert(magick_module != (const char *) NULL);
179
2.87k
  assert(name != (const char *) NULL);
180
2.87k
  assert(description != (const char *) NULL);
181
2.87k
  if (IsEventLogging() != MagickFalse)
182
0
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",name);
183
2.87k
  magick_info=(MagickInfo *) AcquireCriticalMemory(sizeof(*magick_info));
184
2.87k
  (void) memset(magick_info,0,sizeof(*magick_info));
185
2.87k
  magick_info->magick_module=ConstantString(magick_module);
186
2.87k
  magick_info->name=ConstantString(name);
187
2.87k
  magick_info->description=ConstantString(description);
188
2.87k
  magick_info->flags=CoderAdjoinFlag | CoderBlobSupportFlag |
189
2.87k
    CoderDecoderThreadSupportFlag | CoderEncoderThreadSupportFlag |
190
2.87k
    CoderUseExtensionFlag;
191
2.87k
  magick_info->signature=MagickCoreSignature;
192
2.87k
  return(magick_info);
193
2.87k
}
194

195
/*
196
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
197
%                                                                             %
198
%                                                                             %
199
%                                                                             %
200
+   G e t I m a g e D e c o d e r                                             %
201
%                                                                             %
202
%                                                                             %
203
%                                                                             %
204
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
205
%
206
%  GetImageDecoder() returns the image decoder.
207
%
208
%  The format of the GetImageDecoder method is:
209
%
210
%      DecodeImageHandler *GetImageDecoder(const MagickInfo *magick_info)
211
%
212
%  A description of each parameter follows:
213
%
214
%    o magick_info:  The magick info.
215
%
216
*/
217
MagickExport DecodeImageHandler *GetImageDecoder(const MagickInfo *magick_info)
218
747k
{
219
747k
  if (magick_info == (MagickInfo *) NULL)
220
528
    return((DecodeImageHandler *) NULL);
221
747k
  assert(magick_info->signature == MagickCoreSignature);
222
746k
  return(magick_info->decoder);
223
746k
}
224

225
/*
226
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
227
%                                                                             %
228
%                                                                             %
229
%                                                                             %
230
+   G e t I m a g e E n c o d e r                                             %
231
%                                                                             %
232
%                                                                             %
233
%                                                                             %
234
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
235
%
236
%  GetImageEncoder() returns the image encoder.
237
%
238
%  The format of the GetImageEncoder method is:
239
%
240
%      EncodeImageHandler *GetImageEncoder(const MagickInfo *magick_info)
241
%
242
%  A description of each parameter follows:
243
%
244
%    o magick_info:  The magick info.
245
%
246
*/
247
MagickExport EncodeImageHandler *GetImageEncoder(const MagickInfo *magick_info)
248
61.5k
{
249
61.5k
  if (magick_info == (MagickInfo *) NULL)
250
0
    return((EncodeImageHandler *) NULL);
251
61.5k
  assert(magick_info->signature == MagickCoreSignature);
252
61.5k
  return(magick_info->encoder);
253
61.5k
}
254

255
/*
256
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
257
%                                                                             %
258
%                                                                             %
259
%                                                                             %
260
+   G e t I m a g e M a g i c k                                               %
261
%                                                                             %
262
%                                                                             %
263
%                                                                             %
264
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
265
%
266
%  GetImageMagick() searches for an image format that matches the specified
267
%  magick string.  If one is found, MagickTrue is returned otherwise
268
%  MagickFalse.
269
%
270
%  The format of the GetImageMagick method is:
271
%
272
%      MagickBooleanType GetImageMagick(const unsigned char *magick,
273
%        const size_t length,char *format)
274
%
275
%  A description of each parameter follows:
276
%
277
%    o magick: the image format we are searching for.
278
%
279
%    o length: the length of the binary string.
280
%
281
%    o format: the image format as determined by the magick bytes.
282
%
283
*/
284
MagickExport MagickBooleanType GetImageMagick(const unsigned char *magick,
285
  const size_t length,char *format)
286
0
{
287
0
  ExceptionInfo
288
0
    *exception;
289
290
0
  MagickBooleanType
291
0
    status;
292
293
0
  const MagickInfo
294
0
    *p;
295
296
0
  assert(magick != (const unsigned char *) NULL);
297
0
  if (IsEventLogging() != MagickFalse)
298
0
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
299
0
  exception=AcquireExceptionInfo();
300
0
  p=GetMagickInfo("*",exception);
301
0
  exception=DestroyExceptionInfo(exception);
302
0
  if (p == (const MagickInfo *) NULL)
303
0
    return(MagickFalse);
304
0
  status=MagickFalse;
305
0
  LockSemaphoreInfo(magick_semaphore);
306
0
  ResetSplayTreeIterator(magick_list);
307
0
  p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
308
0
  while (p != (const MagickInfo *) NULL)
309
0
  {
310
0
    if ((p->magick != (IsImageFormatHandler *) NULL) &&
311
0
        (p->magick(magick,length) != 0))
312
0
      {
313
0
        status=MagickTrue;
314
0
        (void) CopyMagickString(format,p->name,MagickPathExtent);
315
0
        break;
316
0
      }
317
0
    p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
318
0
  }
319
0
  UnlockSemaphoreInfo(magick_semaphore);
320
0
  return(status);
321
0
}
322

323
/*
324
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
325
%                                                                             %
326
%                                                                             %
327
%                                                                             %
328
+   G e t M a g i c k A d j o i n                                             %
329
%                                                                             %
330
%                                                                             %
331
%                                                                             %
332
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
333
%
334
%  GetMagickAdjoin() returns MagickTrue if the magick adjoin is MagickTrue.
335
%
336
%  The format of the GetMagickAdjoin method is:
337
%
338
%      MagickBooleanType GetMagickAdjoin(const MagickInfo *magick_info)
339
%
340
%  A description of each parameter follows:
341
%
342
%    o magick_info:  The magick info.
343
%
344
*/
345
MagickExport MagickBooleanType GetMagickAdjoin(const MagickInfo *magick_info)
346
717k
{
347
717k
  assert(magick_info != (MagickInfo *) NULL);
348
717k
  assert(magick_info->signature == MagickCoreSignature);
349
717k
  return(((magick_info->flags & CoderAdjoinFlag) == 0) ? MagickFalse :
350
717k
    MagickTrue);
351
717k
}
352

353
/*
354
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
355
%                                                                             %
356
%                                                                             %
357
%                                                                             %
358
+   G e t M a g i c k B l o b S u p p o r t                                   %
359
%                                                                             %
360
%                                                                             %
361
%                                                                             %
362
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
363
%
364
%  GetMagickBlobSupport() returns MagickTrue if the magick supports blobs.
365
%
366
%  The format of the GetMagickBlobSupport method is:
367
%
368
%      MagickBooleanType GetMagickBlobSupport(const MagickInfo *magick_info)
369
%
370
%  A description of each parameter follows:
371
%
372
%    o magick_info:  The magick info.
373
%
374
*/
375
MagickExport MagickBooleanType GetMagickBlobSupport(
376
  const MagickInfo *magick_info)
377
924k
{
378
924k
  assert(magick_info != (MagickInfo *) NULL);
379
924k
  assert(magick_info->signature == MagickCoreSignature);
380
924k
  return(((magick_info->flags & CoderBlobSupportFlag) == 0) ? MagickFalse :
381
924k
    MagickTrue);
382
924k
}
383

384
/*
385
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
386
%                                                                             %
387
%                                                                             %
388
%                                                                             %
389
+   G e t M a g i c k D e c o d e r S e e k a b l e S t r e a m               %
390
%                                                                             %
391
%                                                                             %
392
%                                                                             %
393
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
394
%
395
%  GetMagickDecoderSeekableStream() returns MagickTrue if the magick supports a
396
%  seekable stream in the decoder.
397
%
398
%  The format of the GetMagickDecoderSeekableStream method is:
399
%
400
%      MagickBooleanType GetMagickDecoderSeekableStream(
401
%        const MagickInfo *magick_info)
402
%
403
%  A description of each parameter follows:
404
%
405
%    o magick_info:  The magick info.
406
%
407
*/
408
MagickExport MagickBooleanType GetMagickDecoderSeekableStream(
409
  const MagickInfo *magick_info)
410
746k
{
411
746k
  assert(magick_info != (MagickInfo *) NULL);
412
746k
  assert(magick_info->signature == MagickCoreSignature);
413
746k
  if ((magick_info->flags & CoderDecoderSeekableStreamFlag) == 0)
414
135k
    return(MagickFalse);
415
611k
  return(MagickTrue);
416
746k
}
417

418
/*
419
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
420
%                                                                             %
421
%                                                                             %
422
%                                                                             %
423
+   G e t M a g i c k D e c o d e r T h r e a d S u p p o r t                 %
424
%                                                                             %
425
%                                                                             %
426
%                                                                             %
427
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
428
%
429
%  GetMagickDecoderThreadSupport() returns MagickTrue if the decoder supports
430
%  threads.
431
%
432
%  The format of the GetMagickDecoderThreadSupport method is:
433
%
434
%      MagickStatusType GetMagickDecoderThreadSupport(
435
%        const MagickInfo *magick_info)
436
%
437
%  A description of each parameter follows:
438
%
439
%    o magick_info:  The magick info.
440
%
441
*/
442
MagickExport MagickBooleanType GetMagickDecoderThreadSupport(
443
  const MagickInfo *magick_info)
444
1.49M
{
445
1.49M
  assert(magick_info != (MagickInfo *) NULL);
446
1.49M
  assert(magick_info->signature == MagickCoreSignature);
447
1.49M
  return(((magick_info->flags & CoderDecoderThreadSupportFlag) == 0) ?
448
1.49M
    MagickFalse : MagickTrue);
449
1.49M
}
450

451
/*
452
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
453
%                                                                             %
454
%                                                                             %
455
%                                                                             %
456
+   G e t M a g i c k D e s c r i p t i o n                                   %
457
%                                                                             %
458
%                                                                             %
459
%                                                                             %
460
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
461
%
462
%  GetMagickDescription() returns the magick description.
463
%
464
%  The format of the GetMagickDescription method is:
465
%
466
%      const char *GetMagickDescription(const MagickInfo *magick_info)
467
%
468
%  A description of each parameter follows:
469
%
470
%    o magick_info:  The magick info.
471
%
472
*/
473
MagickExport const char *GetMagickDescription(const MagickInfo *magick_info)
474
0
{
475
0
  assert(magick_info != (MagickInfo *) NULL);
476
0
  assert(magick_info->signature == MagickCoreSignature);
477
0
  return(magick_info->description);
478
0
}
479

480
/*
481
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
482
%                                                                             %
483
%                                                                             %
484
%                                                                             %
485
+   G e t M a g i c k E n c o d e r S e e k a b l e S t r e a m               %
486
%                                                                             %
487
%                                                                             %
488
%                                                                             %
489
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
490
%
491
%  GetMagickEncoderSeekableStream() returns MagickTrue if the magick supports a
492
%  seekable stream in the encoder.
493
%
494
%  The format of the GetMagickEncoderSeekableStream method is:
495
%
496
%      MagickBooleanType GetMagickEncoderSeekableStream(
497
%        const MagickInfo *magick_info)
498
%
499
%  A description of each parameter follows:
500
%
501
%    o magick_info:  The magick info.
502
%
503
*/
504
MagickExport MagickBooleanType GetMagickEncoderSeekableStream(
505
  const MagickInfo *magick_info)
506
61.5k
{
507
61.5k
  assert(magick_info != (MagickInfo *) NULL);
508
61.5k
  assert(magick_info->signature == MagickCoreSignature);
509
61.5k
  if ((magick_info->flags & CoderEncoderSeekableStreamFlag) == 0)
510
41.5k
    return(MagickFalse);
511
20.0k
  return(MagickTrue);
512
61.5k
}
513

514
/*
515
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
516
%                                                                             %
517
%                                                                             %
518
%                                                                             %
519
+   G e t M a g i c k E n c o d e r T h r e a d S u p p o r t                 %
520
%                                                                             %
521
%                                                                             %
522
%                                                                             %
523
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
524
%
525
%  GetMagickEncoderThreadSupport() returns MagickTrue if the encoder supports
526
%  threads.
527
%
528
%  The format of the GetMagickEncoderThreadSupport method is:
529
%
530
%      MagickStatusType GetMagickEncoderThreadSupport(
531
%        const MagickInfo *magick_info)
532
%
533
%  A description of each parameter follows:
534
%
535
%    o magick_info:  The magick info.
536
%
537
*/
538
MagickExport MagickBooleanType GetMagickEncoderThreadSupport(
539
  const MagickInfo *magick_info)
540
125k
{
541
125k
  assert(magick_info != (MagickInfo *) NULL);
542
125k
  assert(magick_info->signature == MagickCoreSignature);
543
125k
  return(((magick_info->flags & CoderEncoderThreadSupportFlag) == 0) ?
544
125k
    MagickFalse : MagickTrue);
545
125k
}
546

547
/*
548
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
549
%                                                                             %
550
%                                                                             %
551
%                                                                             %
552
+   G e t M a g i c k E n d i a n S u p p o r t                               %
553
%                                                                             %
554
%                                                                             %
555
%                                                                             %
556
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
557
%
558
%  GetMagickEndianSupport() returns the MagickTrue if the coder respects
559
%  endianness other than MSBEndian.
560
%
561
%  The format of the GetMagickEndianSupport method is:
562
%
563
%      MagickBooleanType GetMagickEndianSupport(const MagickInfo *magick_info)
564
%
565
%  A description of each parameter follows:
566
%
567
%    o magick_info:  The magick info.
568
%
569
*/
570
MagickExport MagickBooleanType GetMagickEndianSupport(
571
  const MagickInfo *magick_info)
572
2.40M
{
573
2.40M
  assert(magick_info != (MagickInfo *) NULL);
574
2.40M
  assert(magick_info->signature == MagickCoreSignature);
575
2.40M
  return(((magick_info->flags & CoderEndianSupportFlag) == 0) ? MagickFalse :
576
2.40M
    MagickTrue);
577
2.40M
}
578

579
/*
580
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
581
%                                                                             %
582
%                                                                             %
583
%                                                                             %
584
+   G e t M a g i c k I n f o                                                 %
585
%                                                                             %
586
%                                                                             %
587
%                                                                             %
588
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
589
%
590
%  GetMagickInfo() returns a pointer MagickInfo structure that matches
591
%  the specified name.  If name is NULL, the head of the image format list
592
%  is returned.
593
%
594
%  The format of the GetMagickInfo method is:
595
%
596
%      const MagickInfo *GetMagickInfo(const char *name,Exception *exception)
597
%
598
%  A description of each parameter follows:
599
%
600
%    o name: the image format we are looking for.
601
%
602
%    o exception: return any errors or warnings in this structure.
603
%
604
*/
605
MagickExport const MagickInfo *GetMagickInfo(const char *name,
606
  ExceptionInfo *exception)
607
4.24M
{
608
4.24M
  const MagickInfo
609
4.24M
    *magick_info;
610
611
  /*
612
    Find named module attributes.
613
  */
614
4.24M
  assert(exception != (ExceptionInfo *) NULL);
615
4.24M
  if (IsMagickTreeInstantiated(exception) == MagickFalse)
616
0
    return((const MagickInfo *) NULL);
617
4.24M
  magick_info=(const MagickInfo *) NULL;
618
4.24M
  if ((name != (const char *) NULL) && (*name != '\0'))
619
4.07M
    {
620
4.07M
      LockSemaphoreInfo(magick_semaphore);
621
4.07M
      if (LocaleCompare(name,"*") == 0)
622
#if defined(MAGICKCORE_BUILD_MODULES)
623
        (void) OpenModules(exception);
624
#else
625
88.7k
        RegisterStaticModules();
626
3.98M
#endif
627
3.98M
      else
628
3.98M
        {
629
3.98M
          magick_info=(const MagickInfo *) GetValueFromSplayTree(magick_list,
630
3.98M
            name);
631
3.98M
          if (magick_info == (const MagickInfo *) NULL)
632
#if defined(MAGICKCORE_BUILD_MODULES)
633
            (void) OpenModule(name,exception);
634
#else
635
28.2k
            (void) RegisterStaticModule(name,exception);
636
3.98M
#endif
637
3.98M
        }
638
4.07M
      UnlockSemaphoreInfo(magick_semaphore);
639
4.07M
    }
640
4.24M
  if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
641
88.7k
    return((const MagickInfo *) GetRootValueFromSplayTree(magick_list));
642
4.16M
  if (magick_info == (const MagickInfo *) NULL)
643
203k
    magick_info=(const MagickInfo *) GetValueFromSplayTree(magick_list,name);
644
4.16M
  return(magick_info);
645
4.24M
}
646

647
/*
648
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
649
%                                                                             %
650
%                                                                             %
651
%                                                                             %
652
+   G e t M a g i c k I n f o L i s t                                         %
653
%                                                                             %
654
%                                                                             %
655
%                                                                             %
656
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
657
%
658
%  GetMagickInfoList() returns any image formats that match the specified
659
%  pattern.
660
%
661
%  The format of the GetMagickInfoList function is:
662
%
663
%      const MagickInfo **GetMagickInfoList(const char *pattern,
664
%        size_t *number_formats,ExceptionInfo *exception)
665
%
666
%  A description of each parameter follows:
667
%
668
%    o pattern: Specifies a pointer to a text string containing a pattern.
669
%
670
%    o number_formats:  This integer returns the number of formats in the list.
671
%
672
%    o exception: return any errors or warnings in this structure.
673
%
674
*/
675
676
#if defined(__cplusplus) || defined(c_plusplus)
677
extern "C" {
678
#endif
679
680
static int MagickInfoCompare(const void *x,const void *y)
681
0
{
682
0
  const MagickInfo
683
0
    **p,
684
0
    **q;
685
686
0
  p=(const MagickInfo **) x,
687
0
  q=(const MagickInfo **) y;
688
0
  return(LocaleCompare((*p)->name,(*q)->name));
689
0
}
690
691
#if defined(__cplusplus) || defined(c_plusplus)
692
}
693
#endif
694
695
MagickExport const MagickInfo **GetMagickInfoList(const char *pattern,
696
  size_t *number_formats,ExceptionInfo *exception)
697
0
{
698
0
  const MagickInfo
699
0
    **formats;
700
701
0
  const MagickInfo
702
0
    *p;
703
704
0
  ssize_t
705
0
    i;
706
707
  /*
708
    Allocate magick list.
709
  */
710
0
  assert(pattern != (char *) NULL);
711
0
  assert(number_formats != (size_t *) NULL);
712
0
  if (IsEventLogging() != MagickFalse)
713
0
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
714
0
  *number_formats=0;
715
0
  p=GetMagickInfo("*",exception);
716
0
  if (p == (const MagickInfo *) NULL)
717
0
    return((const MagickInfo **) NULL);
718
0
  formats=(const MagickInfo **) AcquireQuantumMemory((size_t)
719
0
    GetNumberOfNodesInSplayTree(magick_list)+1UL,sizeof(*formats));
720
0
  if (formats == (const MagickInfo **) NULL)
721
0
    return((const MagickInfo **) NULL);
722
  /*
723
    Generate magick list.
724
  */
725
0
  LockSemaphoreInfo(magick_semaphore);
726
0
  ResetSplayTreeIterator(magick_list);
727
0
  p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
728
0
  for (i=0; p != (const MagickInfo *) NULL; )
729
0
  {
730
0
    if ((GetMagickStealth(p) == MagickFalse) &&
731
0
        (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
732
0
      formats[i++]=p;
733
0
    p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
734
0
  }
735
0
  UnlockSemaphoreInfo(magick_semaphore);
736
0
  qsort((void *) formats,(size_t) i,sizeof(*formats),MagickInfoCompare);
737
0
  formats[i]=(MagickInfo *) NULL;
738
0
  *number_formats=(size_t) i;
739
0
  return(formats);
740
0
}
741

742
/*
743
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
744
%                                                                             %
745
%                                                                             %
746
%                                                                             %
747
+   G e t M a g i c k L i s t                                                 %
748
%                                                                             %
749
%                                                                             %
750
%                                                                             %
751
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
752
%
753
%  GetMagickList() returns any image formats that match the specified pattern.
754
%
755
%  The format of the GetMagickList function is:
756
%
757
%      char **GetMagickList(const char *pattern,size_t *number_formats,
758
%        ExceptionInfo *exception)
759
%
760
%  A description of each parameter follows:
761
%
762
%    o pattern: Specifies a pointer to a text string containing a pattern.
763
%
764
%    o number_formats:  This integer returns the number of formats in the list.
765
%
766
%    o exception: return any errors or warnings in this structure.
767
%
768
*/
769
770
#if defined(__cplusplus) || defined(c_plusplus)
771
extern "C" {
772
#endif
773
774
static int MagickCompare(const void *x,const void *y)
775
0
{
776
0
  const char
777
0
    **p,
778
0
    **q;
779
780
0
  p=(const char **) x;
781
0
  q=(const char **) y;
782
0
  return(LocaleCompare(*p,*q));
783
0
}
784
785
#if defined(__cplusplus) || defined(c_plusplus)
786
}
787
#endif
788
789
MagickExport char **GetMagickList(const char *pattern,
790
  size_t *number_formats,ExceptionInfo *exception)
791
0
{
792
0
  char
793
0
    **formats;
794
795
0
  const MagickInfo
796
0
    *p;
797
798
0
  ssize_t
799
0
    i;
800
801
  /*
802
    Allocate magick list.
803
  */
804
0
  assert(pattern != (char *) NULL);
805
0
  assert(number_formats != (size_t *) NULL);
806
0
  if (IsEventLogging() != MagickFalse)
807
0
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
808
0
  *number_formats=0;
809
0
  p=GetMagickInfo("*",exception);
810
0
  if (p == (const MagickInfo *) NULL)
811
0
    return((char **) NULL);
812
0
  formats=(char **) AcquireQuantumMemory((size_t)
813
0
    GetNumberOfNodesInSplayTree(magick_list)+1UL,sizeof(*formats));
814
0
  if (formats == (char **) NULL)
815
0
    return((char **) NULL);
816
0
  LockSemaphoreInfo(magick_semaphore);
817
0
  ResetSplayTreeIterator(magick_list);
818
0
  p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
819
0
  for (i=0; p != (const MagickInfo *) NULL; )
820
0
  {
821
0
    if ((GetMagickStealth(p) == MagickFalse) &&
822
0
        (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
823
0
      formats[i++]=ConstantString(p->name);
824
0
    p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
825
0
  }
826
0
  UnlockSemaphoreInfo(magick_semaphore);
827
0
  qsort((void *) formats,(size_t) i,sizeof(*formats),MagickCompare);
828
0
  formats[i]=(char *) NULL;
829
0
  *number_formats=(size_t) i;
830
0
  return(formats);
831
0
}
832

833
/*
834
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
835
%                                                                             %
836
%                                                                             %
837
%                                                                             %
838
+   G e t M a g i c k M i m e T y p e                                         %
839
%                                                                             %
840
%                                                                             %
841
%                                                                             %
842
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
843
%
844
%  GetMagickMimeType() returns the magick mime type.
845
%
846
%  The format of the GetMagickMimeType method is:
847
%
848
%      const char *GetMagickMimeType(const MagickInfo *magick_info)
849
%
850
%  A description of each parameter follows:
851
%
852
%    o magick_info:  The magick info.
853
%
854
*/
855
MagickExport const char *GetMagickMimeType(const MagickInfo *magick_info)
856
0
{
857
0
  assert(magick_info != (MagickInfo *) NULL);
858
0
  assert(magick_info->signature == MagickCoreSignature);
859
0
  return(magick_info->mime_type);
860
0
}
861

862
/*
863
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
864
%                                                                             %
865
%                                                                             %
866
%                                                                             %
867
+   G e t M a g i c k M o d u l e N a m e                                     %
868
%                                                                             %
869
%                                                                             %
870
%                                                                             %
871
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
872
%
873
%  GetMagickModuleName() returns the magick module name.
874
%
875
%  The format of the GetMagickModuleName method is:
876
%
877
%      const char *GetMagickModuleName(const MagickInfo *magick_info)
878
%
879
%  A description of each parameter follows:
880
%
881
%    o magick_info:  The magick info.
882
%
883
*/
884
MagickExport const char *GetMagickModuleName(const MagickInfo *magick_info)
885
0
{
886
0
  assert(magick_info != (MagickInfo *) NULL);
887
0
  assert(magick_info->signature == MagickCoreSignature);
888
0
  return(magick_info->magick_module);
889
0
}
890

891
/*
892
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
893
%                                                                             %
894
%                                                                             %
895
%                                                                             %
896
+   G e t M a g i c k N a m e                                                 %
897
%                                                                             %
898
%                                                                             %
899
%                                                                             %
900
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
901
%
902
%  GetMagickName() returns the magick name.
903
%
904
%  The format of the GetMagickName method is:
905
%
906
%      const char *GetMagickName(const MagickInfo *magick_info)
907
%
908
%  A description of each parameter follows:
909
%
910
%    o magick_info:  The magick info.
911
%
912
*/
913
MagickExport const char *GetMagickName(const MagickInfo *magick_info)
914
0
{
915
0
  assert(magick_info != (MagickInfo *) NULL);
916
0
  assert(magick_info->signature == MagickCoreSignature);
917
0
  return(magick_info->name);
918
0
}
919

920
/*
921
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
922
%                                                                             %
923
%                                                                             %
924
%                                                                             %
925
%   G e t M a g i c k P r e c i s i o n                                       %
926
%                                                                             %
927
%                                                                             %
928
%                                                                             %
929
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
930
%
931
%  GetMagickPrecision() returns the maximum number of significant digits to be
932
%  printed.
933
%
934
%  The format of the GetMagickPrecision method is:
935
%
936
%      int GetMagickPrecision(void)
937
%
938
*/
939
MagickExport int GetMagickPrecision(void)
940
9.39k
{
941
9.39k
  if (IsEventLogging() != MagickFalse)
942
0
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
943
9.39k
  return(SetMagickPrecision(0));
944
9.39k
}
945

946
/*
947
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
948
%                                                                             %
949
%                                                                             %
950
%                                                                             %
951
+   G e t M a g i c k R a w S u p p o r t                                     %
952
%                                                                             %
953
%                                                                             %
954
%                                                                             %
955
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
956
%
957
%  GetMagickRawSupport() returns the MagickTrue if the coder is a raw format.
958
%
959
%  The format of the GetMagickRawSupport method is:
960
%
961
%      MagickBooleanType GetMagickRawSupport(const MagickInfo *magick_info)
962
%
963
%  A description of each parameter follows:
964
%
965
%    o magick_info:  The magick info.
966
%
967
*/
968
MagickExport MagickBooleanType GetMagickRawSupport(
969
  const MagickInfo *magick_info)
970
122k
{
971
122k
  assert(magick_info != (MagickInfo *) NULL);
972
122k
  assert(magick_info->signature == MagickCoreSignature);
973
122k
  return(((magick_info->flags & CoderRawSupportFlag) == 0) ? MagickFalse :
974
122k
    MagickTrue);
975
122k
}
976

977
/*
978
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
979
%                                                                             %
980
%                                                                             %
981
%                                                                             %
982
+   G e t M a g i c k S t e a l t h                                           %
983
%                                                                             %
984
%                                                                             %
985
%                                                                             %
986
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
987
%
988
%  GetMagickStealth() returns MagickTrue if the magick is a stealth coder.
989
%
990
%  The format of the GetMagickStealth method is:
991
%
992
%      MagickBooleanType GetMagickStealth(const MagickInfo *magick_info)
993
%
994
%  A description of each parameter follows:
995
%
996
%    o magick_info:  The magick info.
997
%
998
*/
999
MagickExport MagickBooleanType GetMagickStealth(const MagickInfo *magick_info)
1000
0
{
1001
0
  assert(magick_info != (MagickInfo *) NULL);
1002
0
  assert(magick_info->signature == MagickCoreSignature);
1003
0
  return(((magick_info->flags & CoderStealthFlag) == 0) ? MagickFalse :
1004
0
    MagickTrue);
1005
0
}
1006

1007
/*
1008
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1009
%                                                                             %
1010
%                                                                             %
1011
%                                                                             %
1012
+   G e t M a g i c k U s e E x t e n s i o n                                 %
1013
%                                                                             %
1014
%                                                                             %
1015
%                                                                             %
1016
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1017
%
1018
%  GetMagickUseExtension() returns MagickTrue if the magick can use the
1019
%  extension of the format if the format return by IsImageFormatHandler uses
1020
%  the same coder.
1021
%
1022
%  The format of the GetMagickUseExtension method is:
1023
%
1024
%      MagickBooleanType GetMagickUseExtension(const MagickInfo *magick_info)
1025
%
1026
%  A description of each parameter follows:
1027
%
1028
%    o magick_info:  The magick info.
1029
%
1030
*/
1031
MagickExport MagickBooleanType GetMagickUseExtension(
1032
  const MagickInfo *magick_info)
1033
4
{
1034
4
  assert(magick_info != (MagickInfo *) NULL);
1035
4
  assert(magick_info->signature == MagickCoreSignature);
1036
4
  return(((magick_info->flags & CoderUseExtensionFlag) == 0) ? MagickFalse :
1037
4
    MagickTrue);
1038
4
}
1039

1040
/*
1041
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1042
%                                                                             %
1043
%                                                                             %
1044
%                                                                             %
1045
+   I s M a g i c k T r e e I n s t a n t i a t e d                           %
1046
%                                                                             %
1047
%                                                                             %
1048
%                                                                             %
1049
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1050
%
1051
%  IsMagickTreeInstantiated() determines if the magick tree is instantiated.
1052
%  If not, it instantiates the tree and returns it.
1053
%
1054
%  The format of the IsMagickTreeInstantiated() method is:
1055
%
1056
%      IsMagickTreeInstantiated(Exceptioninfo *exception)
1057
%
1058
%  A description of each parameter follows.
1059
%
1060
%    o exception: return any errors or warnings in this structure.
1061
%
1062
*/
1063
1064
static void *DestroyMagickNode(void *magick_info)
1065
0
{
1066
0
  MagickInfo
1067
0
    *p;
1068
1069
0
  p=(MagickInfo *) magick_info;
1070
0
  if (p->magick_module != (char *) NULL)
1071
0
    p->magick_module=DestroyString(p->magick_module);
1072
0
  if (p->note != (char *) NULL)
1073
0
    p->note=DestroyString(p->note);
1074
0
  if (p->mime_type != (char *) NULL)
1075
0
    p->mime_type=DestroyString(p->mime_type);
1076
0
  if (p->version != (char *) NULL)
1077
0
    p->version=DestroyString(p->version);
1078
0
  if (p->description != (char *) NULL)
1079
0
    p->description=DestroyString(p->description);
1080
0
  if (p->name != (char *) NULL)
1081
0
    p->name=DestroyString(p->name);
1082
0
  if (p->semaphore != (SemaphoreInfo *) NULL)
1083
0
    RelinquishSemaphoreInfo(&p->semaphore);
1084
0
  return(RelinquishMagickMemory(p));
1085
0
}
1086
1087
static MagickBooleanType IsMagickTreeInstantiated(ExceptionInfo *exception)
1088
4.24M
{
1089
4.24M
  (void) exception;
1090
4.24M
  if (magick_list_initialized == MagickFalse)
1091
141
    {
1092
141
      if (magick_semaphore == (SemaphoreInfo *) NULL)
1093
0
        ActivateSemaphoreInfo(&magick_semaphore);
1094
141
      LockSemaphoreInfo(magick_semaphore);
1095
141
      if (magick_list_initialized == MagickFalse)
1096
141
        {
1097
141
          magick_list=NewSplayTree(CompareSplayTreeString,(void *(*)(void *))
1098
141
            NULL,DestroyMagickNode);
1099
#if defined(MAGICKCORE_MODULES_SUPPORT)
1100
          (void) GetModuleInfo((char *) NULL,exception);
1101
#endif
1102
141
          magick_list_initialized=MagickTrue;
1103
141
        }
1104
141
      UnlockSemaphoreInfo(magick_semaphore);
1105
141
    }
1106
4.24M
  return(magick_list != (SplayTreeInfo *) NULL ? MagickTrue : MagickFalse);
1107
4.24M
}
1108

1109
/*
1110
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1111
%                                                                             %
1112
%                                                                             %
1113
%                                                                             %
1114
+   I s M a g i c k C o n f l i c t                                           %
1115
%                                                                             %
1116
%                                                                             %
1117
%                                                                             %
1118
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1119
%
1120
%  IsMagickConflict() returns MagickTrue if the image format conflicts with a
1121
%  logical drive (.e.g. X:).
1122
%
1123
%  The format of the IsMagickConflict method is:
1124
%
1125
%      MagickBooleanType IsMagickConflict(const char *magick)
1126
%
1127
%  A description of each parameter follows:
1128
%
1129
%    o magick: Specifies the image format.
1130
%
1131
*/
1132
MagickPrivate MagickBooleanType IsMagickConflict(const char *magick)
1133
6.66M
{
1134
6.66M
  assert(magick != (char *) NULL);
1135
#if defined(vms)
1136
  return(VMSIsMagickConflict(magick));
1137
#elif defined(MAGICKCORE_WINDOWS_SUPPORT)
1138
  return(NTIsMagickConflict(magick));
1139
#else
1140
6.66M
  return(MagickFalse);
1141
6.66M
#endif
1142
6.66M
}
1143

1144
/*
1145
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1146
%                                                                             %
1147
%                                                                             %
1148
%                                                                             %
1149
+  L i s t M a g i c k I n f o                                                %
1150
%                                                                             %
1151
%                                                                             %
1152
%                                                                             %
1153
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1154
%
1155
%  ListMagickInfo() lists the image formats to a file.
1156
%
1157
%  The format of the ListMagickInfo method is:
1158
%
1159
%      MagickBooleanType ListMagickInfo(FILE *file,ExceptionInfo *exception)
1160
%
1161
%  A description of each parameter follows.
1162
%
1163
%    o file: A file handle.
1164
%
1165
%    o exception: return any errors or warnings in this structure.
1166
%
1167
*/
1168
MagickExport MagickBooleanType ListMagickInfo(FILE *file,
1169
  ExceptionInfo *exception)
1170
0
{
1171
0
  const MagickInfo
1172
0
    **magick_info;
1173
1174
0
  ssize_t
1175
0
    i;
1176
1177
0
  size_t
1178
0
    number_formats;
1179
1180
0
  ssize_t
1181
0
    j;
1182
1183
0
  if (file == (FILE *) NULL)
1184
0
    file=stdout;
1185
0
  magick_info=GetMagickInfoList("*",&number_formats,exception);
1186
0
  if (magick_info == (const MagickInfo **) NULL)
1187
0
    return(MagickFalse);
1188
0
  ClearMagickException(exception);
1189
0
#if !defined(MAGICKCORE_MODULES_SUPPORT)
1190
0
  (void) FormatLocaleFile(file,"   Format  Mode  Description\n");
1191
#else
1192
  (void) FormatLocaleFile(file,"   Format  Module    Mode  Description\n");
1193
#endif
1194
0
  (void) FormatLocaleFile(file,
1195
0
    "--------------------------------------------------------"
1196
0
    "-----------------------\n");
1197
0
  for (i=0; i < (ssize_t) number_formats; i++)
1198
0
  {
1199
0
    if (GetMagickStealth(magick_info[i]) != MagickFalse)
1200
0
      continue;
1201
0
    (void) FormatLocaleFile(file,"%9s%c ",
1202
0
      magick_info[i]->name != (char *) NULL ? magick_info[i]->name : "",
1203
0
      GetMagickBlobSupport(magick_info[i]) != MagickFalse ? '*' : ' ');
1204
#if defined(MAGICKCORE_MODULES_SUPPORT)
1205
    {
1206
      char
1207
        magick_module[MagickPathExtent];
1208
1209
      *magick_module='\0';
1210
      if (magick_info[i]->magick_module != (char *) NULL)
1211
        (void) CopyMagickString(magick_module,magick_info[i]->magick_module,
1212
          MagickPathExtent);
1213
      (void) ConcatenateMagickString(magick_module,"          ",
1214
        MagickPathExtent);
1215
      magick_module[9]='\0';
1216
      (void) FormatLocaleFile(file,"%9s ",magick_module);
1217
    }
1218
#endif
1219
0
    (void) FormatLocaleFile(file,"%c%c%c ",magick_info[i]->decoder ? 'r' : '-',
1220
0
      magick_info[i]->encoder ? 'w' : '-',magick_info[i]->encoder != NULL &&
1221
0
      GetMagickAdjoin(magick_info[i]) != MagickFalse ? '+' : '-');
1222
0
    if (magick_info[i]->description != (char *) NULL)
1223
0
      (void) FormatLocaleFile(file,"  %s",magick_info[i]->description);
1224
0
    if (magick_info[i]->version != (char *) NULL)
1225
0
      (void) FormatLocaleFile(file," (%s)",magick_info[i]->version);
1226
0
    (void) FormatLocaleFile(file,"\n");
1227
0
    if (magick_info[i]->note != (char *) NULL)
1228
0
      {
1229
0
        char
1230
0
          **text;
1231
1232
0
        text=StringToList(magick_info[i]->note);
1233
0
        if (text != (char **) NULL)
1234
0
          {
1235
0
            for (j=0; text[j] != (char *) NULL; j++)
1236
0
            {
1237
0
              (void) FormatLocaleFile(file,"             %s\n",text[j]);
1238
0
              text[j]=DestroyString(text[j]);
1239
0
            }
1240
0
            text=(char **) RelinquishMagickMemory(text);
1241
0
          }
1242
0
      }
1243
0
  }
1244
0
  (void) FormatLocaleFile(file,"\n* native blob support\n");
1245
0
  (void) FormatLocaleFile(file,"r read support\n");
1246
0
  (void) FormatLocaleFile(file,"w write support\n");
1247
0
  (void) FormatLocaleFile(file,"+ support for multiple images\n");
1248
0
  (void) fflush(file);
1249
0
  magick_info=(const MagickInfo **) RelinquishMagickMemory((void *)
1250
0
    magick_info);
1251
0
  return(MagickTrue);
1252
0
}
1253

1254
/*
1255
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1256
%                                                                             %
1257
%                                                                             %
1258
%                                                                             %
1259
%  I s M a g i c k C o r e I n s t a n t i a t e d                            %
1260
%                                                                             %
1261
%                                                                             %
1262
%                                                                             %
1263
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1264
%
1265
%  IsMagickCoreInstantiated() returns MagickFalse if the ImageMagick
1266
%  environment has not been instantiated; the ImageMagick environment
1267
%  has been instantiated when MagickCoreGenesis() has been called but
1268
%  MagickDestroy() has not been called.
1269
%
1270
%  The format of the IsMagickCoreInstantiated method is:
1271
%
1272
%      MagickBooleanType IsMagickCoreInstantiated(void)
1273
%
1274
*/
1275
MagickExport MagickBooleanType IsMagickCoreInstantiated(void)
1276
0
{
1277
0
  return(magickcore_instantiated);
1278
0
}
1279

1280
/*
1281
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1282
%                                                                             %
1283
%                                                                             %
1284
%                                                                             %
1285
+   M a g i c k C o m p o n e n t G e n e s i s                               %
1286
%                                                                             %
1287
%                                                                             %
1288
%                                                                             %
1289
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1290
%
1291
%  MagickComponentGenesis() instantiates the magick component.
1292
%
1293
%  The format of the MagickComponentGenesis method is:
1294
%
1295
%      MagickBooleanType MagickComponentGenesis(void)
1296
%
1297
*/
1298
MagickPrivate MagickBooleanType MagickComponentGenesis(void)
1299
294
{
1300
294
  if (magick_semaphore == (SemaphoreInfo *) NULL)
1301
294
    magick_semaphore=AcquireSemaphoreInfo();
1302
294
  return(MagickTrue);
1303
294
}
1304

1305
/*
1306
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1307
%                                                                             %
1308
%                                                                             %
1309
%                                                                             %
1310
+   M a g i c k C o m p o n e n t T e r m i n u s                             %
1311
%                                                                             %
1312
%                                                                             %
1313
%                                                                             %
1314
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1315
%
1316
%  MagickComponentTerminus() destroys the magick component.
1317
%
1318
%  The format of the MagickComponentTerminus method is:
1319
%
1320
%      void MagickComponentTerminus(void)
1321
%
1322
*/
1323
MagickPrivate void MagickComponentTerminus(void)
1324
0
{
1325
0
  if (magick_semaphore == (SemaphoreInfo *) NULL)
1326
0
    ActivateSemaphoreInfo(&magick_semaphore);
1327
0
  LockSemaphoreInfo(magick_semaphore);
1328
0
  if (magick_list != (SplayTreeInfo *) NULL)
1329
0
    {
1330
0
      magick_list=DestroySplayTree(magick_list);
1331
0
      magick_list_initialized=MagickFalse;
1332
0
    }
1333
0
  UnlockSemaphoreInfo(magick_semaphore);
1334
0
  RelinquishSemaphoreInfo(&magick_semaphore);
1335
0
}
1336

1337
/*
1338
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1339
%                                                                             %
1340
%                                                                             %
1341
%                                                                             %
1342
%   M a g i c k C o r e G e n e s i s                                         %
1343
%                                                                             %
1344
%                                                                             %
1345
%                                                                             %
1346
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1347
%
1348
%  MagickCoreGenesis() initializes the MagickCore environment.
1349
%
1350
%  The format of the MagickCoreGenesis function is:
1351
%
1352
%      void MagickCoreGenesis(const char *path,
1353
%        const MagickBooleanType establish_signal_handlers)
1354
%
1355
%  A description of each parameter follows:
1356
%
1357
%    o path: the execution path of the current ImageMagick client.
1358
%
1359
%    o establish_signal_handlers: set to MagickTrue to use MagickCore's own
1360
%      signal handlers for common signals.
1361
%
1362
*/
1363
1364
static SignalHandler *SetMagickSignalHandler(int signal_number,
1365
  SignalHandler *handler)
1366
0
{
1367
0
#if defined(MAGICKCORE_HAVE_SIGACTION) && defined(MAGICKCORE_HAVE_SIGEMPTYSET)
1368
0
  int
1369
0
    status;
1370
1371
0
  sigset_t
1372
0
    mask;
1373
1374
0
  struct sigaction
1375
0
    action,
1376
0
    previous_action;
1377
1378
0
  sigemptyset(&mask);
1379
0
  sigaddset(&mask,signal_number);
1380
0
  sigprocmask(SIG_BLOCK,&mask,NULL);
1381
0
  action.sa_mask=mask;
1382
0
  action.sa_handler=handler;
1383
0
  action.sa_flags=0;
1384
0
#if defined(SA_INTERRUPT)
1385
0
  action.sa_flags|=SA_INTERRUPT;
1386
0
#endif
1387
0
#if defined(SA_ONSTACK)
1388
0
  action.sa_flags|=SA_ONSTACK;
1389
0
#endif
1390
0
  previous_action.sa_handler=SIG_DFL;
1391
0
  status=sigaction(signal_number,&action,&previous_action);
1392
0
  if (status < 0)
1393
0
    return(SIG_ERR);
1394
0
  sigprocmask(SIG_UNBLOCK,&mask,NULL);
1395
0
  return(previous_action.sa_handler);
1396
#else
1397
  return(signal(signal_number,handler));
1398
#endif
1399
0
}
1400
1401
static void MagickSignalHandler(int signal_number)
1402
0
{
1403
0
  if (magickcore_signal_in_progress != MagickFalse)
1404
0
    (void) SetMagickSignalHandler(signal_number,signal_handlers[signal_number]);
1405
0
  magickcore_signal_in_progress=MagickTrue;
1406
0
  AsynchronousResourceComponentTerminus();
1407
0
#if defined(SIGQUIT)
1408
0
  if (signal_number == SIGQUIT)
1409
0
    abort();
1410
0
#endif
1411
0
#if defined(SIGABRT)
1412
0
  if (signal_number == SIGABRT)
1413
0
    abort();
1414
0
#endif
1415
0
#if defined(SIGBUS)
1416
0
  if (signal_number == SIGBUS)
1417
0
    abort();
1418
0
#endif
1419
0
#if defined(SIGFPE)
1420
0
  if (signal_number == SIGFPE)
1421
0
    abort();
1422
0
#endif
1423
0
#if defined(SIGSEGV)
1424
0
  if (signal_number == SIGSEGV)
1425
0
    abort();
1426
0
#endif
1427
#if !defined(MAGICKCORE_HAVE__EXIT)
1428
  exit(signal_number);
1429
#else
1430
0
#if defined(SIGHUP)
1431
0
  if (signal_number == SIGHUP)
1432
0
    _exit(signal_number);
1433
0
#endif
1434
0
#if defined(SIGINT)
1435
0
  if (signal_number == SIGINT)
1436
0
    {
1437
0
      signal(SIGINT,SIG_DFL);
1438
0
      raise(SIGINT);
1439
0
      _exit(signal_number);
1440
0
    }
1441
0
#endif
1442
0
#if defined(MAGICKCORE_HAVE_RAISE)
1443
0
  if (signal_handlers[signal_number] != MagickSignalHandler)
1444
0
    raise(signal_number);
1445
0
#endif
1446
0
  _exit(signal_number);  /* do not invoke registered atexit() methods */
1447
0
#endif
1448
0
}
1449
1450
static SignalHandler *RegisterMagickSignalHandler(int signal_number)
1451
0
{
1452
0
  SignalHandler
1453
0
    *handler;
1454
1455
0
  handler=SetMagickSignalHandler(signal_number,MagickSignalHandler);
1456
0
  if (handler == SIG_ERR)
1457
0
    return(handler);
1458
0
  if (handler != SIG_DFL)
1459
0
    handler=SetMagickSignalHandler(signal_number,handler);
1460
0
  else
1461
0
    (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1462
0
      "Register handler for signal: %d",signal_number);
1463
0
  return(handler);
1464
0
}
1465
1466
static void SetClientNameAndPath(const char *path)
1467
294
{
1468
294
  char
1469
294
    execution_path[MagickPathExtent],
1470
294
    filename[MagickPathExtent];
1471
1472
#if defined(MAGICKCORE_WINDOWS_SUPPORT)
1473
  if ((path != (const char *) NULL) && (IsPathAccessible(path) != MagickFalse))
1474
#else
1475
294
  if ((path != (const char *) NULL) && (*path == *DirectorySeparator) &&
1476
0
      (IsPathAccessible(path) != MagickFalse))
1477
0
#endif
1478
0
    (void) CopyMagickString(execution_path,path,MagickPathExtent);
1479
294
  else
1480
294
    (void) GetExecutionPath(execution_path,MagickPathExtent);
1481
294
  GetPathComponent(execution_path,TailPath,filename);
1482
294
  (void) SetClientName(filename);
1483
294
  GetPathComponent(execution_path,HeadPath,execution_path);
1484
294
  (void) SetClientPath(execution_path);
1485
294
}
1486
1487
MagickExport void MagickCoreGenesis(const char *path,
1488
  const MagickBooleanType establish_signal_handlers)
1489
294
{
1490
294
  char
1491
294
    *events;
1492
1493
  /*
1494
    Initialize the Magick environment.
1495
  */
1496
294
#if defined(__has_feature)
1497
#if __has_feature(address_sanitizer)
1498
  (void) putenv("MAGICK_THREAD_LIMIT=1");
1499
#endif
1500
294
#endif
1501
294
  InitializeMagickMutex();
1502
294
  LockMagickMutex();
1503
294
  if (magickcore_instantiated != MagickFalse)
1504
0
    {
1505
0
      UnlockMagickMutex();
1506
0
      return;
1507
0
    }
1508
294
  (void) SemaphoreComponentGenesis();
1509
294
  (void) ExceptionComponentGenesis();
1510
294
  SetClientNameAndPath(path);
1511
294
  (void) LogComponentGenesis();
1512
294
  (void) LocaleComponentGenesis();
1513
294
  (void) RandomComponentGenesis();
1514
294
  events=GetEnvironmentValue("MAGICK_DEBUG");
1515
294
  if (events != (char *) NULL)
1516
0
    {
1517
0
      (void) SetLogEventMask(events);
1518
0
      events=DestroyString(events);
1519
0
    }
1520
#if defined(MAGICKCORE_WINDOWS_SUPPORT)
1521
  NTWindowsGenesis();
1522
#endif
1523
294
  if (establish_signal_handlers != MagickFalse)
1524
0
    {
1525
      /*
1526
        Set signal handlers.
1527
      */
1528
0
#if defined(SIGABRT)
1529
0
      if (signal_handlers[SIGABRT] == (SignalHandler *) NULL)
1530
0
        signal_handlers[SIGABRT]=RegisterMagickSignalHandler(SIGABRT);
1531
0
#endif
1532
0
#if defined(SIGBUS)
1533
0
      if (signal_handlers[SIGBUS] == (SignalHandler *) NULL)
1534
0
        signal_handlers[SIGBUS]=RegisterMagickSignalHandler(SIGBUS);
1535
0
#endif
1536
0
#if defined(SIGSEGV)
1537
0
      if (signal_handlers[SIGSEGV] == (SignalHandler *) NULL)
1538
0
        signal_handlers[SIGSEGV]=RegisterMagickSignalHandler(SIGSEGV);
1539
0
#endif
1540
0
#if defined(SIGFPE)
1541
0
      if (signal_handlers[SIGFPE] == (SignalHandler *) NULL)
1542
0
        signal_handlers[SIGFPE]=RegisterMagickSignalHandler(SIGFPE);
1543
0
#endif
1544
0
#if defined(SIGHUP)
1545
0
      if (signal_handlers[SIGHUP] == (SignalHandler *) NULL)
1546
0
        signal_handlers[SIGHUP]=RegisterMagickSignalHandler(SIGHUP);
1547
0
#endif
1548
0
#if defined(SIGINT)
1549
0
      if (signal_handlers[SIGINT] == (SignalHandler *) NULL)
1550
0
        signal_handlers[SIGINT]=RegisterMagickSignalHandler(SIGINT);
1551
0
#endif
1552
0
#if defined(SIGQUIT)
1553
0
      if (signal_handlers[SIGQUIT] == (SignalHandler *) NULL)
1554
0
        signal_handlers[SIGQUIT]=RegisterMagickSignalHandler(SIGQUIT);
1555
0
#endif
1556
0
#if defined(SIGTERM)
1557
0
      if (signal_handlers[SIGTERM] == (SignalHandler *) NULL)
1558
0
        signal_handlers[SIGTERM]=RegisterMagickSignalHandler(SIGTERM);
1559
0
#endif
1560
0
#if defined(SIGXCPU)
1561
0
      if (signal_handlers[SIGXCPU] == (SignalHandler *) NULL)
1562
0
        signal_handlers[SIGXCPU]=RegisterMagickSignalHandler(SIGXCPU);
1563
0
#endif
1564
0
#if defined(SIGXFSZ)
1565
0
      if (signal_handlers[SIGXFSZ] == (SignalHandler *) NULL)
1566
0
        signal_handlers[SIGXFSZ]=RegisterMagickSignalHandler(SIGXFSZ);
1567
0
#endif
1568
0
    }
1569
  /*
1570
    Instantiate magick resources.
1571
  */
1572
294
  (void) ConfigureComponentGenesis();
1573
294
  (void) PolicyComponentGenesis();
1574
#if MAGICKCORE_ZERO_CONFIGURATION_SUPPORT
1575
  (void) ZeroConfigurationPolicy;
1576
#endif
1577
294
  (void) CacheComponentGenesis();
1578
294
  (void) ResourceComponentGenesis();
1579
294
  (void) CoderComponentGenesis();
1580
294
  (void) MagickComponentGenesis();
1581
#if defined(MAGICKCORE_MODULES_SUPPORT)
1582
  (void) ModuleComponentGenesis();
1583
#endif
1584
294
  (void) DelegateComponentGenesis();
1585
294
  (void) MagicComponentGenesis();
1586
294
  (void) ColorComponentGenesis();
1587
294
  (void) TypeComponentGenesis();
1588
294
  (void) MimeComponentGenesis();
1589
294
  (void) AnnotateComponentGenesis();
1590
#if defined(MAGICKCORE_X11_DELEGATE)
1591
  (void) XComponentGenesis();
1592
#endif
1593
294
  (void) RegistryComponentGenesis();
1594
294
  (void) MonitorComponentGenesis();
1595
294
  magickcore_instantiated=MagickTrue;
1596
294
  UnlockMagickMutex();
1597
294
}
1598

1599
/*
1600
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1601
%                                                                             %
1602
%                                                                             %
1603
%                                                                             %
1604
%   M a g i c k C o r e T e r m i n u s                                       %
1605
%                                                                             %
1606
%                                                                             %
1607
%                                                                             %
1608
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1609
%
1610
%  MagickCoreTerminus() is a function in the ImageMagick library that is
1611
%  used to clean up and release resources when shutting down an application
1612
%  that uses ImageMagick. This function should be called in the primary thread
1613
%  of the application's process during the shutdown process. It's crucial that
1614
%  this function is invoked only after any threads that are using ImageMagick
1615
%  functions have terminated.
1616
%
1617
%  ImageMagick might internally use threads via OpenMP (a method for parallel
1618
%  programming). As a result, it's important to ensure that any function calls
1619
%  into ImageMagick have completed before calling MagickCoreTerminus(). This
1620
%  prevents issues with OpenMP worker threads accessing resources that are
1621
%  destroyed by this termination function.
1622
%
1623
%  If OpenMP is being used (starting from version 5.0), the OpenMP
1624
%  implementation itself handles starting and stopping worker threads and
1625
%  allocating and freeing resources using its own methods. This means that
1626
%  after calling MagickCoreTerminus(), some OpenMP resources and worker
1627
%  threads might still remain allocated. To address this, the function
1628
%  omp_pause_resource_all(omp_pause_hard) can be invoked. This function,
1629
%  introduced in OpenMP version 5.0, ensures that any resources allocated by
1630
%  OpenMP (such as threads and thread-specific memory) are freed. It's
1631
%  recommended to call this function after MagickCoreTerminus() has completed
1632
%  its execution.
1633
%
1634
%  The format of the MagickCoreTerminus function is:
1635
%
1636
%      void MagickCoreTerminus(void)
1637
%
1638
*/
1639
MagickExport void MagickCoreTerminus(void)
1640
0
{
1641
0
  InitializeMagickMutex();
1642
0
  LockMagickMutex();
1643
0
  if (magickcore_instantiated == MagickFalse)
1644
0
    {
1645
0
      UnlockMagickMutex();
1646
0
      return;
1647
0
    }
1648
0
  MonitorComponentTerminus();
1649
0
  RegistryComponentTerminus();
1650
0
  AnnotateComponentTerminus();
1651
0
  MimeComponentTerminus();
1652
0
  TypeComponentTerminus();
1653
#if defined(MAGICKCORE_OPENCL_SUPPORT)
1654
  OpenCLTerminus();
1655
#endif
1656
0
  ColorComponentTerminus();
1657
#if defined(MAGICKCORE_WINDOWS_SUPPORT)
1658
  NTWindowsTerminus();
1659
#endif
1660
0
  MagicComponentTerminus();
1661
0
  DelegateComponentTerminus();
1662
0
  MagickComponentTerminus();
1663
0
#if !defined(MAGICKCORE_BUILD_MODULES)
1664
0
  UnregisterStaticModules();
1665
0
#endif
1666
#if defined(MAGICKCORE_MODULES_SUPPORT)
1667
  ModuleComponentTerminus();
1668
#endif
1669
#if defined(MAGICKCORE_X11_DELEGATE)
1670
  XComponentTerminus();
1671
#endif
1672
0
  CoderComponentTerminus();
1673
0
  ResourceComponentTerminus();
1674
0
  CacheComponentTerminus();
1675
0
  PolicyComponentTerminus();
1676
0
  ConfigureComponentTerminus();
1677
0
  RandomComponentTerminus();
1678
0
  LocaleComponentTerminus();
1679
0
  LogComponentTerminus();
1680
0
  ExceptionComponentTerminus();
1681
0
  magickcore_instantiated=MagickFalse;
1682
0
  UnlockMagickMutex();
1683
0
  SemaphoreComponentTerminus();
1684
0
}
1685

1686
/*
1687
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1688
%                                                                             %
1689
%                                                                             %
1690
%                                                                             %
1691
+   R e g i s t e r M a g i c k I n f o                                       %
1692
%                                                                             %
1693
%                                                                             %
1694
%                                                                             %
1695
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1696
%
1697
%  RegisterMagickInfo() adds attributes for a particular image format to the
1698
%  list of supported formats.  The attributes include the image format name,
1699
%  a method to read and/or write the format, whether the format supports the
1700
%  saving of more than one frame to the same file or blob, whether the format
1701
%  supports native in-memory I/O, and a brief description of the format.
1702
%
1703
%  The format of the RegisterMagickInfo method is:
1704
%
1705
%      MagickInfo *RegisterMagickInfo(MagickInfo *magick_info)
1706
%
1707
%  A description of each parameter follows:
1708
%
1709
%    o magick_info: the magick info.
1710
%
1711
*/
1712
MagickExport MagickBooleanType RegisterMagickInfo(MagickInfo *magick_info)
1713
2.87k
{
1714
2.87k
  MagickBooleanType
1715
2.87k
    status;
1716
1717
  /*
1718
    Register a new image format.
1719
  */
1720
2.87k
  assert(magick_info != (MagickInfo *) NULL);
1721
2.87k
  assert(magick_info->signature == MagickCoreSignature);
1722
2.87k
  if (IsEventLogging() != MagickFalse)
1723
0
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",magick_info->name);
1724
2.87k
  if (magick_list == (SplayTreeInfo *) NULL)
1725
0
    return(MagickFalse);
1726
2.87k
  if ((GetMagickDecoderThreadSupport(magick_info) == MagickFalse) ||
1727
2.86k
      (GetMagickEncoderThreadSupport(magick_info) == MagickFalse))
1728
16
    magick_info->semaphore=AcquireSemaphoreInfo();
1729
2.87k
  status=AddValueToSplayTree(magick_list,magick_info->name,magick_info);
1730
2.87k
  return(status);
1731
2.87k
}
1732

1733
/*
1734
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1735
%                                                                             %
1736
%                                                                             %
1737
%                                                                             %
1738
+   R e s e t M a g i c k P r e c i s i o n                                   %
1739
%                                                                             %
1740
%                                                                             %
1741
%                                                                             %
1742
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1743
%
1744
%  ResetMagickPrecision() resets the magick_precision value.
1745
%
1746
%  The format of the ResetMagickPrecision method is:
1747
%
1748
%      void ResetMagickPrecision(void)
1749
%
1750
*/
1751
MagickPrivate void ResetMagickPrecision(void)
1752
0
{
1753
0
  magick_precision=0;
1754
0
}
1755

1756
/*
1757
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1758
%                                                                             %
1759
%                                                                             %
1760
%                                                                             %
1761
%   S e t M a g i c k P r e c i s i o n                                       %
1762
%                                                                             %
1763
%                                                                             %
1764
%                                                                             %
1765
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1766
%
1767
%  SetMagickPrecision() sets the maximum number of significant digits to be
1768
%  printed.
1769
%
1770
%  An input argument of 0 returns the current precision setting.
1771
%
1772
%  A negative value forces the precision to reset to a default value according
1773
%  to the environment variable "MAGICK_PRECISION", the current 'policy'
1774
%  configuration setting, or the default value of '6', in that order.
1775
%
1776
%  The format of the SetMagickPrecision method is:
1777
%
1778
%      int SetMagickPrecision(const int precision)
1779
%
1780
%  A description of each parameter follows:
1781
%
1782
%    o precision: set the maximum number of significant digits to be printed.
1783
%
1784
*/
1785
MagickExport int SetMagickPrecision(const int precision)
1786
9.39k
{
1787
9.39k
#define MagickPrecision  (MAGICKCORE_QUANTUM_DEPTH/8+4)
1788
1789
9.39k
  if (IsEventLogging() != MagickFalse)
1790
0
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
1791
9.39k
  if (precision > 0)
1792
0
    magick_precision=precision;
1793
9.39k
  if ((precision < 0) || (magick_precision == 0))
1794
3
    {
1795
3
      char
1796
3
        *limit;
1797
1798
3
      ExceptionInfo
1799
3
        *exception = AcquireExceptionInfo();
1800
1801
3
      magick_precision=MagickPrecision;
1802
3
      limit=(char *) GetImageRegistry(StringRegistryType,"precision",exception);
1803
3
      exception=DestroyExceptionInfo(exception);
1804
3
      if (limit == (char *) NULL)
1805
3
        limit=GetEnvironmentValue("MAGICK_PRECISION");
1806
3
      if (limit == (char *) NULL)
1807
3
        limit=GetPolicyValue("system:precision");  /* deprecated */
1808
3
      if (limit != (char *) NULL)
1809
0
        {
1810
0
          magick_precision=StringToInteger(limit);
1811
0
          limit=DestroyString(limit);
1812
0
        }
1813
3
    }
1814
9.39k
  return(magick_precision);
1815
9.39k
}
1816

1817
/*
1818
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1819
%                                                                             %
1820
%                                                                             %
1821
%                                                                             %
1822
+   U n r e g i s t e r M a g i c k I n f o                                   %
1823
%                                                                             %
1824
%                                                                             %
1825
%                                                                             %
1826
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1827
%
1828
%  UnregisterMagickInfo() removes a name from the magick info list.  It returns
1829
%  MagickFalse if the name does not exist in the list otherwise MagickTrue.
1830
%
1831
%  The format of the UnregisterMagickInfo method is:
1832
%
1833
%      MagickBooleanType UnregisterMagickInfo(const char *name)
1834
%
1835
%  A description of each parameter follows:
1836
%
1837
%    o name: a character string that represents the image format we are
1838
%      looking for.
1839
%
1840
*/
1841
MagickExport MagickBooleanType UnregisterMagickInfo(const char *name)
1842
0
{
1843
0
  const MagickInfo
1844
0
    *p;
1845
1846
0
  MagickBooleanType
1847
0
    status;
1848
1849
0
  assert(name != (const char *) NULL);
1850
0
  if (magick_list == (SplayTreeInfo *) NULL)
1851
0
    return(MagickFalse);
1852
0
  if (GetNumberOfNodesInSplayTree(magick_list) == 0)
1853
0
    return(MagickFalse);
1854
0
  LockSemaphoreInfo(magick_semaphore);
1855
0
  ResetSplayTreeIterator(magick_list);
1856
0
  p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
1857
0
  while (p != (const MagickInfo *) NULL)
1858
0
  {
1859
0
    if (LocaleCompare(p->name,name) == 0)
1860
0
      break;
1861
0
    p=(const MagickInfo *) GetNextValueInSplayTree(magick_list);
1862
0
  }
1863
0
  status=DeleteNodeByValueFromSplayTree(magick_list,p);
1864
0
  UnlockSemaphoreInfo(magick_semaphore);
1865
0
  return(status);
1866
0
}