Coverage Report

Created: 2026-06-16 07:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/graphicsmagick/coders/cals.c
Line
Count
Source
1
/*
2
% Copyright (C) 2009-2026 GraphicsMagick Group
3
%
4
% This program is covered by multiple licenses, which are described in
5
% Copyright.txt. You should have received a copy of Copyright.txt with this
6
% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
7
%
8
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
9
%                                                                             %
10
%                                                                             %
11
%                                                                             %
12
%                          CCCC   AAA   L     SSSSS                           %
13
%                         C      A   A  L     SS                              %
14
%                         C      AAAAA  L       SSS                           %
15
%                         C      A   A  L        SS                           %
16
%                          CCCC  A   A  LLLLL SSSSS                           %
17
%                                                                             %
18
%                                                                             %
19
%                 Read/Write CALS (CALS type 1) format                        %
20
%                                                                             %
21
%                                                                             %
22
%                              Software Design                                %
23
%                               John Sergeant                                 %
24
%                                  May 2009                                   %
25
%                                                                             %
26
%                                                                             %
27
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
28
%
29
%
30
*/
31

32
/*
33
  Include declarations.
34
*/
35
#include "magick/studio.h"
36
#include "magick/attribute.h"
37
#include "magick/blob.h"
38
#include "magick/compress.h"
39
#include "magick/constitute.h"
40
#include "magick/log.h"
41
#include "magick/magick.h"
42
#include "magick/monitor.h"
43
#include "magick/tempfile.h"
44
#include "magick/utility.h"
45
#include "magick/static.h"
46
/*
47
   Write an unsigned long to file with Intel/LSB ordering
48
*/
49
static void CALS_WriteIntelULong(FILE *file,unsigned long ul)
50
25.2k
{
51
25.2k
  fputc((unsigned char)ul,file);
52
25.2k
  fputc((unsigned char)(ul >> 8),file);
53
25.2k
  fputc((unsigned char)(ul >> 16),file);
54
25.2k
  fputc((unsigned char)(ul >> 24),file);
55
25.2k
}
56

57
/*
58
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
59
%                                                                             %
60
%                                                                             %
61
%                                                                             %
62
%   I s C A L S                                                               %
63
%                                                                             %
64
%                                                                             %
65
%                                                                             %
66
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
67
%
68
%  Method IsCALS returns MagickTrue if the image format type, identified by the
69
%  magick string, is CAL.
70
%
71
%  The format of the IsCALS method is:
72
%
73
%      unsigned int IsCALS(const unsigned char *magick,const size_t length)
74
%
75
%  A description of each parameter follows:
76
%
77
%    o status:  Method IsCALS returns MagickTrue if the image format type is CAL.
78
%
79
%    o magick: This string is generally the first few bytes of an image file
80
%      or blob.
81
%
82
%    o length: Specifies the length of the magick string.
83
%
84
%
85
*/
86
static MagickBool IsCALS(const unsigned char *magick,const size_t length)
87
0
{
88
0
  if (length < 132)
89
0
    return(MagickFalse);
90
0
  if (LocaleNCompare((char *) (magick),"version: MIL-STD-1840",21) == 0)
91
0
    return(MagickTrue);
92
0
  if (LocaleNCompare((char *) (magick),"srcdocid:",9) == 0)
93
0
    return(MagickTrue);
94
0
  if (LocaleNCompare((char *) (magick),"rorient:",8) == 0)
95
0
    return(MagickTrue);
96
0
  return(MagickFalse);
97
0
}
98

99
/*
100
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
101
%                                                                             %
102
%                                                                             %
103
%                                                                             %
104
%   R e a d C A L S I m a g e                                                 %
105
%                                                                             %
106
%                                                                             %
107
%                                                                             %
108
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
109
%
110
%  Method ReadCALSImage reads a CALS type 1 image file and returns it. It
111
%  allocates the memory necessary for the new Image structure and returns a
112
%  pointer to the new image.
113
%
114
%  The format of the ReadCALSImage method is:
115
%
116
%      Image *ReadCALSImage(const ImageInfo *image_info,ExceptionInfo *exception)
117
%
118
%  A description of each parameter follows:
119
%
120
%    o image:  Method ReadCALSImage returns a pointer to the image after
121
%      reading.  A null image is returned if there is a memory shortage or
122
%      if the image cannot be read.
123
%
124
%    o image_info: Specifies a pointer to a ImageInfo structure.
125
%
126
%    o exception: return any errors or warnings in this structure.
127
%
128
%
129
*/
130
static Image *ReadCALSImage(const ImageInfo *image_info,ExceptionInfo *exception)
131
6.68k
{
132
6.68k
  Image
133
6.68k
    *image;
134
135
6.68k
  long
136
6.68k
    y;
137
138
6.68k
  char
139
6.68k
    record[129];
140
141
6.68k
  unsigned long
142
6.68k
    status,
143
6.68k
    width,
144
6.68k
    height,
145
6.68k
    rtype,
146
6.68k
    orient,
147
6.68k
    density;
148
149
6.68k
  char
150
6.68k
    filename[MaxTextExtent];
151
152
6.68k
  FILE
153
6.68k
    *file;
154
155
6.68k
  TimerInfo
156
6.68k
    timer;
157
158
6.68k
  unsigned long
159
6.68k
    byte_count_pos,
160
6.68k
    strip_off_pos,
161
6.68k
    flen;
162
163
6.68k
  int
164
6.68k
    c;
165
166
6.68k
  ImageInfo
167
6.68k
    *clone_info;
168
169
6.68k
  MagickPassFail
170
6.68k
    file_write_status;
171
172
  /*
173
    Open image file.
174
  */
175
6.68k
  assert(image_info != (const ImageInfo *) NULL);
176
6.68k
  assert(image_info->signature == MagickSignature);
177
6.68k
  assert(exception != (ExceptionInfo *) NULL);
178
6.68k
  assert(exception->signature == MagickSignature);
179
6.68k
  GetTimerInfo(&timer);
180
6.68k
  image=AllocateImage(image_info);
181
6.68k
  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
182
6.68k
  if (status == MagickFail)
183
6.68k
    ThrowReaderException(FileOpenError,UnableToOpenFile,image);
184
185
  /*
186
    Scan CAL header, record by record, looking for mandatory fields
187
  */
188
6.68k
  rtype = 1;
189
6.68k
  width = height = 0;
190
6.68k
  orient = 1;
191
6.68k
  density = 200;
192
6.68k
  record[128]=0;
193
42.1k
  for (y = 0; y < 16; y++)
194
40.0k
    {
195
40.0k
      if (ReadBlob(image,128,(char *) record) != 128)
196
4.53k
        break;
197
35.5k
      if (LocaleNCompare(record,"rtype:",6) == 0)
198
130
        { /* rtype */
199
130
          if (sscanf(record+6,"%ld",&rtype) != 1)
200
1
            {
201
1
              rtype = 0;
202
1
              break;
203
1
            }
204
130
        }
205
35.3k
      else
206
35.3k
        if (LocaleNCompare(record,"rorient:",8) == 0)
207
459
          { /* rorient */
208
459
            unsigned long
209
459
              pel_path_rot,
210
459
              line_rot;
211
212
459
            pel_path_rot = line_rot = 0;
213
459
            if (sscanf(record+8,"%ld,%ld",&pel_path_rot,&line_rot) != 2)
214
5
              {
215
5
                orient = 0;
216
5
                break;
217
5
              }
218
454
            switch (pel_path_rot)
219
454
              {
220
48
              case 90:
221
48
                orient = 5;
222
48
                break;
223
54
              case 180:
224
54
                orient = 3;
225
54
                break;
226
102
              case 270:
227
102
                orient = 7;
228
102
                break;
229
250
              default:
230
250
                orient = 1;
231
454
              }
232
454
            if (line_rot == 90) orient++;
233
454
          }
234
34.9k
        else
235
34.9k
          if (LocaleNCompare(record,"rpelcnt:",8) == 0)
236
2.78k
            { /* replcnt */
237
2.78k
              if (sscanf(record+8,"%ld,%ld",&width,&height) != 2)
238
3
                {
239
3
                  width = 0;
240
3
                  height = 0;
241
3
                  break;
242
3
                }
243
2.78k
            }
244
32.1k
          else
245
32.1k
            if (LocaleNCompare(record,"rdensty:",8) == 0)
246
333
              { /* rdensty */
247
333
                if (sscanf(record+8,"%ld",&density) != 1)
248
3
                  {
249
3
                    density = 0;
250
3
                    break;
251
3
                  }
252
330
                if (!density) density = 200;
253
330
              }
254
35.5k
    }
255
6.68k
  if ((!width) || (!height) || (rtype != 1) || (!orient) || (!density) )
256
4.15k
    ThrowReaderException(CorruptImageError,ImproperImageHeader,image);
257
258
2.52k
  (void) LogMagickEvent(CoderEvent,GetMagickModule(),
259
2.52k
                        "Dimensions %lux%lu",width,height);
260
261
  /* Create TIFF wrapper to handle file data using TIFF library */
262
2.52k
  file=AcquireTemporaryFileStream(filename,BinaryFileIOMode);
263
2.52k
  if (file == (FILE *) NULL)
264
2.52k
    ThrowReaderTemporaryFileException(filename);
265
2.52k
  file_write_status=MagickFail;
266
2.52k
  do
267
2.52k
    {
268
      /* Intel TIFF with IFD at offset 8 - IFD has 14 records */
269
2.52k
      fwrite("\111\111\052\000\010\000\000\000\016\000",1,10,file);
270
      /* New sub image - normal type */
271
2.52k
      fwrite("\376\000\003\000\001\000\000\000\000\000\000\000",1,12,file);
272
      /* Image width */
273
2.52k
      fwrite("\000\001\004\000\001\000\000\000",1,8,file);
274
2.52k
      CALS_WriteIntelULong(file,width);
275
      /* Image height */
276
2.52k
      fwrite("\001\001\004\000\001\000\000\000",1,8,file);
277
2.52k
      CALS_WriteIntelULong(file,height);
278
      /* 1 bit per sample */
279
2.52k
      fwrite("\002\001\003\000\001\000\000\000\001\000\000\000",1,12,file);
280
      /* CCITT Group 4 compression */
281
2.52k
      fwrite("\003\001\003\000\001\000\000\000\004\000\000\000",1,12,file);
282
      /* Photometric interpretation MAX BLACK */
283
2.52k
      fwrite("\006\001\003\000\001\000\000\000\000\000\000\000",1,12,file);
284
      /* Strip offset */
285
2.52k
      fwrite("\021\001\003\000\001\000\000\000",1,8,file);
286
2.52k
      strip_off_pos = 10 + (12 * 14) + 4 + 8;
287
2.52k
      CALS_WriteIntelULong(file,strip_off_pos);
288
      /* Orientation */
289
2.52k
      fwrite("\022\001\003\000\001\000\000\000",1,8,file);
290
2.52k
      CALS_WriteIntelULong(file,orient);
291
      /* 1 sample per pixel */
292
2.52k
      fwrite("\025\001\003\000\001\000\000\000\001\000\000\000",1,12,file);
293
      /* Rows per strip (same as height) */
294
2.52k
      fwrite("\026\001\004\000\001\000\000\000",1,8,file);
295
2.52k
      CALS_WriteIntelULong(file,height);
296
      /* Strip byte count */
297
2.52k
      fwrite("\027\001\004\000\001\000\000\000\000\000\000\000",1,12,file);
298
2.52k
      byte_count_pos = ftell(file)-4;
299
      /* X resolution */
300
2.52k
      fwrite("\032\001\005\000\001\000\000\000",1,8,file);
301
2.52k
      CALS_WriteIntelULong(file,strip_off_pos-8);
302
      /* Y resolution */
303
2.52k
      fwrite("\033\001\005\000\001\000\000\000",1,8,file);
304
2.52k
      CALS_WriteIntelULong(file,strip_off_pos-8);
305
      /* Resolution unit is inch */
306
2.52k
      fwrite("\050\001\003\000\001\000\000\000\002\000\000\000",1,12,file);
307
      /* Offset to next IFD ie end of images */
308
2.52k
      fwrite("\000\000\000\000",1,4,file);
309
      /* Write X/Y resolution as rational data */
310
2.52k
      CALS_WriteIntelULong(file,density);
311
2.52k
      CALS_WriteIntelULong(file,1);
312
313
      /* Copy image stream data */
314
2.52k
      flen = 0;
315
2.52k
      c=ReadBlobByte(image);
316
27.6M
      while (c != EOF)
317
27.6M
        {
318
27.6M
          flen++;
319
27.6M
          (void) fputc(c,file);
320
27.6M
          c=ReadBlobByte(image);
321
27.6M
        }
322
323
      /* Return to correct location and output strip byte count */
324
2.52k
      if (fseek(file,byte_count_pos,SEEK_SET) != 0)
325
0
        break;
326
2.52k
      CALS_WriteIntelULong(file,flen);
327
2.52k
      fflush(file);
328
2.52k
      if (ferror(file))
329
0
        break;
330
2.52k
      file_write_status=MagickPass;
331
2.52k
    } while (0);
332
2.52k
  (void) fclose(file);
333
2.52k
  if (file_write_status != MagickPass)
334
0
    {
335
0
      (void) LiberateTemporaryFile(filename);
336
0
      ThrowReaderException(CoderError,UnableToWriteTemporaryFile,image);
337
0
    }
338
2.52k
  CloseBlob(image);
339
2.52k
  DestroyImage(image);
340
2.52k
  clone_info=CloneImageInfo((ImageInfo *) NULL);
341
2.52k
  MagickFormatString(clone_info->filename,sizeof(clone_info->filename),"tiff:%.1024s",filename);
342
2.52k
  image=ReadImage(clone_info,exception);
343
2.52k
  (void) LiberateTemporaryFile(filename);
344
2.52k
  DestroyImageInfo(clone_info);
345
2.52k
  if (image != (Image *) NULL)
346
1.89k
    {
347
1.89k
      (void) strlcpy(image->filename,image_info->filename,
348
1.89k
                     sizeof(image->filename));
349
1.89k
      (void) strlcpy(image->magick_filename,image_info->filename,
350
1.89k
                     sizeof(image->magick_filename));
351
1.89k
      (void) strlcpy(image->magick,"CALS",sizeof(image->magick));
352
1.89k
      StopTimer(&timer);
353
1.89k
      image->timer=timer;
354
1.89k
    }
355
626
  else
356
626
    {
357
626
      DestroyImage(image);
358
626
      image = (Image *) NULL;
359
626
    }
360
2.52k
  return(image);
361
2.52k
}
362

363
/*
364
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
365
%                                                                             %
366
%                                                                             %
367
%                                                                             %
368
%   W r i t e C A L S I m a g e                                               %
369
%                                                                             %
370
%                                                                             %
371
%                                                                             %
372
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
373
%
374
%  Method WriteCALSImage writes an image in the CALS type I image format
375
%
376
%  The format of the WriteCALSImage method is:
377
%
378
%      unsigned int WriteCALSImage(const ImageInfo *image_info,Image *image)
379
%
380
%  A description of each parameter follows.
381
%
382
%    o status: Method WriteCALSImage return MagickTrue if the image is written.
383
%      MagickFail is returned is there is a memory shortage or if the image file
384
%      fails to write.
385
%
386
%    o image_info: Specifies a pointer to a ImageInfo structure.
387
%
388
%    o image:  A pointer to an Image structure.
389
%
390
%
391
%
392
*/
393
static void WriteCALSRecord(Image *image,const char *data)
394
18.6k
{
395
18.6k
  int
396
18.6k
    i;
397
398
18.6k
  const char
399
18.6k
    *p;
400
401
18.6k
  char
402
18.6k
    pad[128];
403
404
18.6k
  i = 0;
405
18.6k
  if (data)
406
18.6k
    {
407
      /* Limit output to 128 chars */
408
18.6k
      p=data;
409
265k
      while ((i < 128) && (p[i])) i++;
410
18.6k
      WriteBlob(image,i,data);
411
18.6k
    }
412
18.6k
  if (i < 128)
413
18.6k
    {
414
      /* Pad record to 128 characters using trailing spaces */
415
18.6k
      i=128-i;
416
18.6k
      memset(pad,' ',i);
417
18.6k
      WriteBlob(image,i,pad);
418
18.6k
    }
419
18.6k
}
420
421
static MagickPassFail WriteCALSImage(const ImageInfo *image_info,Image *image)
422
1.69k
{
423
1.69k
  char
424
1.69k
    buffer[MaxTextExtent];
425
426
1.69k
  int
427
1.69k
    i;
428
429
1.69k
  long
430
1.69k
    sans;
431
432
1.69k
  unsigned long
433
1.69k
    density;
434
435
1.69k
  int
436
1.69k
    orx,
437
1.69k
    ory;
438
439
1.69k
  MagickPassFail
440
1.69k
    status=MagickPass;
441
442
  /*
443
    Validate input image
444
  */
445
1.69k
  assert(image_info != (const ImageInfo *) NULL);
446
1.69k
  assert(image_info->signature == MagickSignature);
447
1.69k
  assert(image != (Image *) NULL);
448
1.69k
  assert(image->signature == MagickSignature);
449
450
  /*
451
    Open output image file.
452
  */
453
1.69k
  if (OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception) == MagickFail)
454
1.69k
    ThrowWriterException(FileOpenError,UnableToOpenFile,image);
455
456
  /*
457
    Create standard header
458
  */
459
1.69k
  WriteCALSRecord(image,"srcdocid: NONE");
460
1.69k
  WriteCALSRecord(image,"dstdocid: NONE");
461
1.69k
  WriteCALSRecord(image,"txtfilid: NONE");
462
1.69k
  WriteCALSRecord(image,"figid: NONE");
463
1.69k
  WriteCALSRecord(image,"srcgph: NONE");
464
1.69k
  WriteCALSRecord(image,"docls: NONE");
465
1.69k
  WriteCALSRecord(image,"rtype: 1");
466
  /* orientation based on input or default of upright */
467
1.69k
  switch (image->orientation)
468
1.69k
  {
469
1
    case TopRightOrientation:
470
1
      orx=180;
471
1
      ory=270;
472
1
      break;
473
13
    case BottomRightOrientation:
474
13
      orx=180;
475
13
      ory=90;
476
13
      break;
477
0
    case BottomLeftOrientation:
478
0
      orx=0;
479
0
      ory=90;
480
0
      break;
481
3
    case LeftTopOrientation:
482
3
      orx=270;
483
3
      ory=0;
484
3
      break;
485
2
    case RightTopOrientation:
486
2
      orx=270;
487
2
      ory=180;
488
2
      break;
489
58
    case RightBottomOrientation:
490
58
      orx=90;
491
58
      ory=180;
492
58
      break;
493
0
    case LeftBottomOrientation:
494
0
      orx=90;
495
0
      ory=0;
496
0
      break;
497
1.61k
    default:
498
1.61k
      orx=0;
499
1.61k
      ory=270;
500
1.69k
  }
501
1.69k
  MagickFormatString(buffer,sizeof(buffer),"rorient: %03d,%03d",orx,ory);
502
1.69k
  WriteCALSRecord(image,buffer);
503
  /* pixel counts based on columns/rows of input */
504
1.69k
  MagickFormatString(buffer,sizeof(buffer),"rpelcnt: %06ld,%06ld",image->columns,image->rows);
505
1.69k
  WriteCALSRecord(image,buffer);
506
  /* density based on input density or default of 200 */
507
1.69k
  density=200;
508
1.69k
  if (image_info->density != (char *) NULL)
509
0
    (void) GetGeometry(image_info->density,&sans,&sans,&density,&density);
510
1.69k
  MagickFormatString(buffer,sizeof(buffer),"rdensty: %04ld",density);
511
1.69k
  WriteCALSRecord(image,buffer);
512
1.69k
  WriteCALSRecord(image,"notes: NONE");
513
514
  /*
515
    Pad header to make 16 records / 2048 bytes
516
  */
517
1.69k
  memset(buffer,' ',128);
518
10.1k
  for (i = 0; i < 5; i++)
519
8.46k
    if (WriteBlob(image,128,buffer) != 128)
520
0
      status=MagickFail;
521
522
  /*
523
    Encode data to Group 4
524
  */
525
1.69k
  if (MagickFail != status)
526
1.69k
  {
527
1.69k
    unsigned char
528
1.69k
      *blob;
529
530
1.69k
    size_t
531
1.69k
      blob_length;
532
533
1.69k
    blob=ImageToHuffman2DBlob(image,image_info,&blob_length,&image->exception);
534
1.69k
    if (blob == (unsigned char *) NULL)
535
0
      status=MagickFail;
536
537
1.69k
    if (MagickFail != status)
538
1.69k
      {
539
1.69k
        if (WriteBlob(image,blob_length,blob) != blob_length)
540
0
          status=MagickFail;
541
1.69k
      }
542
1.69k
    MagickFreeMemory(blob);
543
1.69k
  }
544
545
  /*
546
    Close output file and return image
547
  */
548
1.69k
  status &= CloseBlob(image);
549
1.69k
  return status;
550
1.69k
}
551

552
/*
553
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
554
%                                                                             %
555
%                                                                             %
556
%                                                                             %
557
%   R e g i s t e r C A L S I m a g e                                         %
558
%                                                                             %
559
%                                                                             %
560
%                                                                             %
561
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
562
%
563
%  Method RegisterCALSImage adds attributes for the CALS image format to
564
%  the list of supported formats.  The attributes include the image format
565
%  tag, a method to read and/or write the format, whether the format
566
%  supports the saving of more than one frame to the same file or blob,
567
%  whether the format supports native in-memory I/O, and a brief
568
%  description of the format.
569
%
570
%  The format of the RegisterCALSImage method is:
571
%
572
%      RegisterCALSImage(void)
573
%
574
*/
575
ModuleExport void RegisterCALSImage(void)
576
4
{
577
4
  MagickInfo
578
4
    *entry;
579
580
4
  const char
581
4
    *description = "Continuous Acquisition and Life-cycle Support Type 1 image",
582
4
    *module      = "CALS",
583
4
    *note        = "Specified in MIL-R-28002 and MIL-PRF-28002";
584
585
4
  entry=SetMagickInfo("CAL");
586
4
  entry->decoder=(DecoderHandler) ReadCALSImage;
587
4
  entry->encoder=(EncoderHandler) WriteCALSImage;
588
4
  entry->magick=(MagickHandler) IsCALS;
589
4
  entry->adjoin=MagickFalse;
590
4
  entry->seekable_stream=MagickTrue;
591
4
  entry->description=description;
592
4
  entry->note=note;
593
4
  entry->module=module;
594
4
  entry->stealth=MagickTrue; /* Don't list in '-list format' output */
595
4
  (void) RegisterMagickInfo(entry);
596
597
4
  entry=SetMagickInfo("CALS");
598
4
  entry->decoder=(DecoderHandler) ReadCALSImage;
599
4
  entry->encoder=(EncoderHandler) WriteCALSImage;
600
4
  entry->magick=(MagickHandler) IsCALS;
601
4
  entry->adjoin=MagickFalse;
602
4
  entry->seekable_stream=MagickTrue;
603
4
  entry->description=description;
604
4
  entry->note=note;
605
4
  entry->module=module;
606
4
  (void) RegisterMagickInfo(entry);
607
4
}
608

609
/*
610
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
611
%                                                                             %
612
%                                                                             %
613
%                                                                             %
614
%   U n r e g i s t e r C A L S I m a g e                                     %
615
%                                                                             %
616
%                                                                             %
617
%                                                                             %
618
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
619
%
620
%  Method UnregisterCALSImage removes format registrations made by the
621
%  CAL module from the list of supported formats.
622
%
623
%  The format of the UnregisterCALSImage method is:
624
%
625
%      UnregisterCALSImage(void)
626
%
627
*/
628
ModuleExport void UnregisterCALSImage(void)
629
0
{
630
0
  (void) UnregisterMagickInfo("CAL");
631
0
  (void) UnregisterMagickInfo("CALS");
632
0
}