blob: 9e15233b62c31fdd4774d2847e1c6127edc7da05 [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% CCCC AAA L SSSSS %
7% C A A L SS %
8% C AAAAA L SSS %
9% C A A L SS %
10% CCCC A A LLLLL SSSSS %
11% %
12% %
cristy47b838c2009-09-19 16:09:30 +000013% Read/Write CALS Raster Group 1 Image Format %
cristy3ed852e2009-09-05 21:47:34 +000014% %
15% Software Design %
cristyde984cd2013-12-01 14:49:27 +000016% Cristy %
cristy3ed852e2009-09-05 21:47:34 +000017% July 1992 %
18% %
19% %
Cristy7ce65e72015-12-12 18:03:16 -050020% Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization %
cristy3ed852e2009-09-05 21:47:34 +000021% dedicated to making software imaging solutions freely available. %
22% %
23% You may not use this file except in compliance with the License. You may %
24% obtain a copy of the License at %
25% %
26% http://www.imagemagick.org/script/license.php %
27% %
28% Unless required by applicable law or agreed to in writing, software %
29% distributed under the License is distributed on an "AS IS" BASIS, %
30% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31% See the License for the specific language governing permissions and %
32% limitations under the License. %
33% %
34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35%
36% The CALS raster format is a standard developed by the Computer Aided
37% Acquisition and Logistics Support (CALS) office of the United States
38% Department of Defense to standardize graphics data interchange for
39% electronic publishing, especially in the areas of technical graphics,
40% CAD/CAM, and image processing applications.
41%
42*/
43
44/*
45 Include declarations.
46*/
cristy4c08aed2011-07-01 19:47:50 +000047#include "MagickCore/studio.h"
48#include "MagickCore/blob.h"
49#include "MagickCore/blob-private.h"
50#include "MagickCore/cache.h"
51#include "MagickCore/colorspace.h"
cristy3f858f42012-01-07 00:03:25 +000052#include "MagickCore/constitute.h"
cristy4c08aed2011-07-01 19:47:50 +000053#include "MagickCore/exception.h"
54#include "MagickCore/exception-private.h"
55#include "MagickCore/geometry.h"
56#include "MagickCore/image.h"
57#include "MagickCore/image-private.h"
58#include "MagickCore/list.h"
59#include "MagickCore/magick.h"
60#include "MagickCore/memory_.h"
61#include "MagickCore/monitor.h"
62#include "MagickCore/monitor-private.h"
63#include "MagickCore/option.h"
64#include "MagickCore/quantum-private.h"
65#include "MagickCore/resource_.h"
66#include "MagickCore/static.h"
67#include "MagickCore/string_.h"
68#include "MagickCore/module.h"
cristy3ed852e2009-09-05 21:47:34 +000069
cristy20a78b22010-04-05 01:22:12 +000070#if defined(MAGICKCORE_TIFF_DELEGATE)
cristy3ed852e2009-09-05 21:47:34 +000071/*
cristy03117002009-09-19 02:10:44 +000072 Forward declarations.
73*/
74static MagickBooleanType
cristy1e178e72011-08-28 19:44:34 +000075 WriteCALSImage(const ImageInfo *,Image *,ExceptionInfo *);
cristy20a78b22010-04-05 01:22:12 +000076#endif
cristy03117002009-09-19 02:10:44 +000077
78/*
cristy3ed852e2009-09-05 21:47:34 +000079%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
80% %
81% %
82% %
83% I s C A L S %
84% %
85% %
86% %
87%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
88%
89% IsCALS() returns MagickTrue if the image format type, identified by the
cristy47b838c2009-09-19 16:09:30 +000090% magick string, is CALS Raster Group 1.
cristy3ed852e2009-09-05 21:47:34 +000091%
92% The format of the IsCALS method is:
93%
94% MagickBooleanType IsCALS(const unsigned char *magick,const size_t length)
95%
96% A description of each parameter follows:
97%
98% o magick: compare image format pattern against these bytes.
99%
100% o length: Specifies the length of the magick string.
101%
102*/
103static MagickBooleanType IsCALS(const unsigned char *magick,const size_t length)
104{
105 if (length < 128)
106 return(MagickFalse);
cristy03117002009-09-19 02:10:44 +0000107 if (LocaleNCompare((const char *) magick,"version: MIL-STD-1840",21) == 0)
cristy3ed852e2009-09-05 21:47:34 +0000108 return(MagickTrue);
cristy03117002009-09-19 02:10:44 +0000109 if (LocaleNCompare((const char *) magick,"srcdocid:",9) == 0)
cristy3ed852e2009-09-05 21:47:34 +0000110 return(MagickTrue);
cristy03117002009-09-19 02:10:44 +0000111 if (LocaleNCompare((const char *) magick,"rorient:",8) == 0)
cristy3ed852e2009-09-05 21:47:34 +0000112 return(MagickTrue);
113 return(MagickFalse);
114}
115
116/*
117%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
118% %
119% %
120% %
121% R e a d C A L S I m a g e %
122% %
123% %
124% %
125%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
126%
cristy47b838c2009-09-19 16:09:30 +0000127% ReadCALSImage() reads an CALS Raster Group 1 image format image file and
128% returns it. It allocates the memory necessary for the new Image structure
129% and returns a pointer to the new image.
cristy3ed852e2009-09-05 21:47:34 +0000130%
131% The format of the ReadCALSImage method is:
132%
133% Image *ReadCALSImage(const ImageInfo *image_info,
134% ExceptionInfo *exception)
135%
136% A description of each parameter follows:
137%
138% o image_info: the image info.
139%
140% o exception: return any errors or warnings in this structure.
141%
142*/
cristy2d6ccc32009-09-25 03:18:25 +0000143static Image *ReadCALSImage(const ImageInfo *image_info,
cristy3ed852e2009-09-05 21:47:34 +0000144 ExceptionInfo *exception)
145{
146 char
cristy151b66d2015-04-15 10:50:31 +0000147 filename[MagickPathExtent],
148 header[MagickPathExtent],
149 message[MagickPathExtent];
cristy3ed852e2009-09-05 21:47:34 +0000150
151 FILE
152 *file;
153
154 Image
cristy2d6ccc32009-09-25 03:18:25 +0000155 *image;
cristy3ed852e2009-09-05 21:47:34 +0000156
157 ImageInfo
158 *read_info;
159
160 int
161 c,
162 unique_file;
163
cristy47b838c2009-09-19 16:09:30 +0000164 MagickBooleanType
165 status;
166
cristybb503372010-05-27 20:51:26 +0000167 register ssize_t
cristy47b838c2009-09-19 16:09:30 +0000168 i;
169
cristyb5af3b02011-04-24 03:01:28 +0000170 unsigned long
cristy3ed852e2009-09-05 21:47:34 +0000171 density,
172 direction,
173 height,
174 orientation,
175 pel_path,
176 type,
177 width;
178
179 /*
180 Open image file.
181 */
182 assert(image_info != (const ImageInfo *) NULL);
cristye1c94d92015-06-28 12:16:33 +0000183 assert(image_info->signature == MagickCoreSignature);
cristy3ed852e2009-09-05 21:47:34 +0000184 if (image_info->debug != MagickFalse)
185 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
186 image_info->filename);
187 assert(exception != (ExceptionInfo *) NULL);
cristye1c94d92015-06-28 12:16:33 +0000188 assert(exception->signature == MagickCoreSignature);
cristy9950d572011-10-01 18:22:35 +0000189 image=AcquireImage(image_info,exception);
cristy3ed852e2009-09-05 21:47:34 +0000190 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
191 if (status == MagickFalse)
192 {
193 image=DestroyImageList(image);
194 return((Image *) NULL);
195 }
196 /*
197 Read CALS header.
198 */
199 (void) ResetMagickMemory(header,0,sizeof(header));
200 density=0;
201 direction=0;
202 orientation=1;
203 pel_path=0;
204 type=1;
205 width=0;
206 height=0;
207 for (i=0; i < 16; i++)
208 {
209 if (ReadBlob(image,128,(unsigned char *) header) != 128)
210 break;
211 switch (*header)
212 {
213 case 'R':
214 case 'r':
215 {
216 if (LocaleNCompare(header,"rdensty:",8) == 0)
217 {
cristy47b838c2009-09-19 16:09:30 +0000218 (void) sscanf(header+8,"%lu",&density);
cristy3ed852e2009-09-05 21:47:34 +0000219 break;
220 }
221 if (LocaleNCompare(header,"rpelcnt:",8) == 0)
222 {
cristy47b838c2009-09-19 16:09:30 +0000223 (void) sscanf(header+8,"%lu,%lu",&width,&height);
cristy3ed852e2009-09-05 21:47:34 +0000224 break;
225 }
226 if (LocaleNCompare(header,"rorient:",8) == 0)
227 {
cristy47b838c2009-09-19 16:09:30 +0000228 (void) sscanf(header+8,"%lu,%lu",&pel_path,&direction);
cristy3ed852e2009-09-05 21:47:34 +0000229 if (pel_path == 90)
230 orientation=5;
231 else
cristy2e68c0c2010-04-06 13:10:46 +0000232 if (pel_path == 180)
cristy3ed852e2009-09-05 21:47:34 +0000233 orientation=3;
234 else
235 if (pel_path == 270)
236 orientation=7;
237 if (direction == 90)
238 orientation++;
239 break;
240 }
241 if (LocaleNCompare(header,"rtype:",6) == 0)
242 {
cristy47b838c2009-09-19 16:09:30 +0000243 (void) sscanf(header+6,"%lu",&type);
cristy3ed852e2009-09-05 21:47:34 +0000244 break;
245 }
246 break;
247 }
248 }
249 }
cristy2d6ccc32009-09-25 03:18:25 +0000250 /*
251 Read CALS pixels.
252 */
253 file=(FILE *) NULL;
254 unique_file=AcquireUniqueFileResource(filename);
255 if (unique_file != -1)
256 file=fdopen(unique_file,"wb");
257 if ((unique_file == -1) || (file == (FILE *) NULL))
258 ThrowImageException(FileOpenError,"UnableToCreateTemporaryFile");
259 while ((c=ReadBlobByte(image)) != EOF)
260 (void) fputc(c,file);
261 (void) fclose(file);
262 (void) CloseBlob(image);
cristy3ed852e2009-09-05 21:47:34 +0000263 image=DestroyImage(image);
cristy2d6ccc32009-09-25 03:18:25 +0000264 read_info=CloneImageInfo(image_info);
265 SetImageInfoBlob(read_info,(void *) NULL,0);
cristy151b66d2015-04-15 10:50:31 +0000266 (void) FormatLocaleString(read_info->filename,MagickPathExtent,"group4:%s",
cristy2d6ccc32009-09-25 03:18:25 +0000267 filename);
cristy151b66d2015-04-15 10:50:31 +0000268 (void) FormatLocaleString(message,MagickPathExtent,"%lux%lu",width,height);
cristya2fdc912011-10-21 11:36:39 +0000269 (void) CloneString(&read_info->size,message);
cristy151b66d2015-04-15 10:50:31 +0000270 (void) FormatLocaleString(message,MagickPathExtent,"%lu",density);
cristya2fdc912011-10-21 11:36:39 +0000271 (void) CloneString(&read_info->density,message);
cristy2d6ccc32009-09-25 03:18:25 +0000272 read_info->orientation=(OrientationType) orientation;
273 image=ReadImage(read_info,exception);
274 if (image != (Image *) NULL)
275 {
276 (void) CopyMagickString(image->filename,image_info->filename,
cristy151b66d2015-04-15 10:50:31 +0000277 MagickPathExtent);
cristy2d6ccc32009-09-25 03:18:25 +0000278 (void) CopyMagickString(image->magick_filename,image_info->filename,
cristy151b66d2015-04-15 10:50:31 +0000279 MagickPathExtent);
280 (void) CopyMagickString(image->magick,"CALS",MagickPathExtent);
cristy2d6ccc32009-09-25 03:18:25 +0000281 }
282 read_info=DestroyImageInfo(read_info);
283 (void) RelinquishUniqueFileResource(filename);
284 return(image);
cristy3ed852e2009-09-05 21:47:34 +0000285}
286
287/*
288%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
289% %
290% %
291% %
292% R e g i s t e r C A L S I m a g e %
293% %
294% %
295% %
296%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
297%
cristy47b838c2009-09-19 16:09:30 +0000298% RegisterCALSImage() adds attributes for the CALS Raster Group 1 image file
299% image format to the list of supported formats. The attributes include the
300% image format tag, a method to read and/or write the format, whether the
301% format supports the saving of more than one frame to the same file or blob,
302% whether the format supports native in-memory I/O, and a brief description
303% of the format.
cristy3ed852e2009-09-05 21:47:34 +0000304%
305% The format of the RegisterCALSImage method is:
306%
cristybb503372010-05-27 20:51:26 +0000307% size_t RegisterCALSImage(void)
cristy3ed852e2009-09-05 21:47:34 +0000308%
309*/
cristybb503372010-05-27 20:51:26 +0000310ModuleExport size_t RegisterCALSImage(void)
cristy3ed852e2009-09-05 21:47:34 +0000311{
dirk06b627a2015-04-06 18:59:17 +0000312#define CALSDescription "Continuous Acquisition and Life-cycle Support Type 1"
313#define CALSNote "Specified in MIL-R-28002 and MIL-PRF-28002"
314
cristy3ed852e2009-09-05 21:47:34 +0000315 MagickInfo
316 *entry;
317
dirk06b627a2015-04-06 18:59:17 +0000318 entry=AcquireMagickInfo("CALS","CAL",CALSDescription);
cristy3ed852e2009-09-05 21:47:34 +0000319 entry->decoder=(DecodeImageHandler *) ReadCALSImage;
cristy9ca59552009-09-23 13:40:25 +0000320#if defined(MAGICKCORE_TIFF_DELEGATE)
cristy03117002009-09-19 02:10:44 +0000321 entry->encoder=(EncodeImageHandler *) WriteCALSImage;
cristy9ca59552009-09-23 13:40:25 +0000322#endif
dirk08e9a112015-02-22 01:51:41 +0000323 entry->flags^=CoderAdjoinFlag;
cristy3ed852e2009-09-05 21:47:34 +0000324 entry->magick=(IsImageFormatHandler *) IsCALS;
cristy9ca59552009-09-23 13:40:25 +0000325 entry->note=ConstantString(CALSNote);
cristy9ca59552009-09-23 13:40:25 +0000326 (void) RegisterMagickInfo(entry);
dirk06b627a2015-04-06 18:59:17 +0000327 entry=AcquireMagickInfo("CALS","CALS",CALSDescription);
cristy9ca59552009-09-23 13:40:25 +0000328 entry->decoder=(DecodeImageHandler *) ReadCALSImage;
329#if defined(MAGICKCORE_TIFF_DELEGATE)
330 entry->encoder=(EncodeImageHandler *) WriteCALSImage;
331#endif
dirk08e9a112015-02-22 01:51:41 +0000332 entry->flags^=CoderAdjoinFlag;
cristy9ca59552009-09-23 13:40:25 +0000333 entry->magick=(IsImageFormatHandler *) IsCALS;
cristy9ca59552009-09-23 13:40:25 +0000334 entry->note=ConstantString(CALSNote);
cristy3ed852e2009-09-05 21:47:34 +0000335 (void) RegisterMagickInfo(entry);
336 return(MagickImageCoderSignature);
337}
338
339/*
340%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
341% %
342% %
343% %
344% U n r e g i s t e r C A L S I m a g e %
345% %
346% %
347% %
348%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
349%
350% UnregisterCALSImage() removes format registrations made by the
351% CALS module from the list of supported formats.
352%
353% The format of the UnregisterCALSImage method is:
354%
355% UnregisterCALSImage(void)
356%
357*/
358ModuleExport void UnregisterCALSImage(void)
359{
cristy9ca59552009-09-23 13:40:25 +0000360 (void) UnregisterMagickInfo("CAL");
cristy3ed852e2009-09-05 21:47:34 +0000361 (void) UnregisterMagickInfo("CALS");
362}
cristy03117002009-09-19 02:10:44 +0000363
cristy316dac12009-12-07 17:19:28 +0000364#if defined(MAGICKCORE_TIFF_DELEGATE)
cristy03117002009-09-19 02:10:44 +0000365/*
366%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
367% %
368% %
369% %
370% W r i t e C A L S I m a g e %
371% %
372% %
373% %
374%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
375%
cristy47b838c2009-09-19 16:09:30 +0000376% WriteCALSImage() writes an image to a file in CALS Raster Group 1 image
377% format.
cristy03117002009-09-19 02:10:44 +0000378%
379% The format of the WriteCALSImage method is:
380%
381% MagickBooleanType WriteCALSImage(const ImageInfo *image_info,
cristy1e178e72011-08-28 19:44:34 +0000382% Image *image,ExceptionInfo *exception)
cristy03117002009-09-19 02:10:44 +0000383%
384% A description of each parameter follows.
385%
386% o image_info: the image info.
387%
388% o image: The image.
389%
cristy1e178e72011-08-28 19:44:34 +0000390% o exception: return any errors or warnings in this structure.
391%
cristy03117002009-09-19 02:10:44 +0000392*/
393
cristy47b838c2009-09-19 16:09:30 +0000394static ssize_t WriteCALSRecord(Image *image,const char *data)
cristy03117002009-09-19 02:10:44 +0000395{
396 char
397 pad[128];
398
cristy03117002009-09-19 02:10:44 +0000399 register const char
400 *p;
401
cristybb503372010-05-27 20:51:26 +0000402 register ssize_t
cristy03117002009-09-19 02:10:44 +0000403 i;
404
cristy4e82e512011-04-24 01:33:42 +0000405 ssize_t
406 count;
407
cristy03117002009-09-19 02:10:44 +0000408 i=0;
cristy564a5692012-01-20 23:56:26 +0000409 count=0;
cristy03117002009-09-19 02:10:44 +0000410 if (data != (const char *) NULL)
411 {
412 p=data;
413 for (i=0; (i < 128) && (p[i] != '\0'); i++);
cristy47b838c2009-09-19 16:09:30 +0000414 count=WriteBlob(image,(size_t) i,(const unsigned char *) data);
cristy03117002009-09-19 02:10:44 +0000415 }
416 if (i < 128)
417 {
cristy03117002009-09-19 02:10:44 +0000418 i=128-i;
cristy9f027d12011-09-21 01:17:17 +0000419 (void) ResetMagickMemory(pad,' ',(size_t) i);
cristy47b838c2009-09-19 16:09:30 +0000420 count=WriteBlob(image,(size_t) i,(const unsigned char *) pad);
cristy03117002009-09-19 02:10:44 +0000421 }
422 return(count);
423}
424
425static MagickBooleanType WriteCALSImage(const ImageInfo *image_info,
cristy1e178e72011-08-28 19:44:34 +0000426 Image *image,ExceptionInfo *exception)
cristy03117002009-09-19 02:10:44 +0000427{
428 char
cristy2d6ccc32009-09-25 03:18:25 +0000429 header[129];
430
431 Image
432 *group4_image;
433
434 ImageInfo
435 *write_info;
cristy03117002009-09-19 02:10:44 +0000436
437 MagickBooleanType
438 status;
439
cristybb503372010-05-27 20:51:26 +0000440 register ssize_t
cristy03117002009-09-19 02:10:44 +0000441 i;
442
cristy4e82e512011-04-24 01:33:42 +0000443 size_t
444 density,
445 length,
446 orient_x,
447 orient_y;
448
cristy03117002009-09-19 02:10:44 +0000449 ssize_t
450 count;
451
cristy2d6ccc32009-09-25 03:18:25 +0000452 unsigned char
453 *group4;
454
cristy03117002009-09-19 02:10:44 +0000455 /*
456 Open output image file.
457 */
458 assert(image_info != (const ImageInfo *) NULL);
cristye1c94d92015-06-28 12:16:33 +0000459 assert(image_info->signature == MagickCoreSignature);
cristy03117002009-09-19 02:10:44 +0000460 assert(image != (Image *) NULL);
cristye1c94d92015-06-28 12:16:33 +0000461 assert(image->signature == MagickCoreSignature);
cristy03117002009-09-19 02:10:44 +0000462 if (image->debug != MagickFalse)
463 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
cristy3a37efd2011-08-28 20:31:03 +0000464 assert(exception != (ExceptionInfo *) NULL);
cristye1c94d92015-06-28 12:16:33 +0000465 assert(exception->signature == MagickCoreSignature);
cristy1e178e72011-08-28 19:44:34 +0000466 status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
cristy03117002009-09-19 02:10:44 +0000467 if (status == MagickFalse)
468 return(status);
469 /*
470 Create standard CALS header.
471 */
472 count=WriteCALSRecord(image,"srcdocid: NONE");
cristyda16f162011-02-19 23:52:17 +0000473 (void) count;
cristy03117002009-09-19 02:10:44 +0000474 count=WriteCALSRecord(image,"dstdocid: NONE");
475 count=WriteCALSRecord(image,"txtfilid: NONE");
476 count=WriteCALSRecord(image,"figid: NONE");
477 count=WriteCALSRecord(image,"srcgph: NONE");
dirkb69086d2016-01-21 12:53:52 +0100478 count=WriteCALSRecord(image,"doccls: NONE");
cristy03117002009-09-19 02:10:44 +0000479 count=WriteCALSRecord(image,"rtype: 1");
cristy43b2de02009-09-19 16:19:31 +0000480 orient_x=0;
481 orient_y=0;
cristy03117002009-09-19 02:10:44 +0000482 switch (image->orientation)
483 {
484 case TopRightOrientation:
485 {
486 orient_x=180;
487 orient_y=270;
488 break;
489 }
490 case BottomRightOrientation:
491 {
492 orient_x=180;
493 orient_y=90;
494 break;
495 }
496 case BottomLeftOrientation:
cristy43b2de02009-09-19 16:19:31 +0000497 {
cristy03117002009-09-19 02:10:44 +0000498 orient_y=90;
499 break;
cristy43b2de02009-09-19 16:19:31 +0000500 }
cristy03117002009-09-19 02:10:44 +0000501 case LeftTopOrientation:
502 {
503 orient_x=270;
cristy03117002009-09-19 02:10:44 +0000504 break;
505 }
506 case RightTopOrientation:
507 {
508 orient_x=270;
509 orient_y=180;
510 break;
511 }
512 case RightBottomOrientation:
513 {
514 orient_x=90;
515 orient_y=180;
516 break;
517 }
518 case LeftBottomOrientation:
519 {
520 orient_x=90;
cristy03117002009-09-19 02:10:44 +0000521 break;
522 }
523 default:
524 {
cristy03117002009-09-19 02:10:44 +0000525 orient_y=270;
cristyf2a82ee2014-05-26 17:49:54 +0000526 break;
cristy03117002009-09-19 02:10:44 +0000527 }
528 }
cristyf2a82ee2014-05-26 17:49:54 +0000529 (void) FormatLocaleString(header,sizeof(header),"rorient: %03ld,%03ld",
cristyf2faecf2010-05-28 19:19:36 +0000530 (long) orient_x,(long) orient_y);
cristy2d6ccc32009-09-25 03:18:25 +0000531 count=WriteCALSRecord(image,header);
cristyf2a82ee2014-05-26 17:49:54 +0000532 (void) FormatLocaleString(header,sizeof(header),"rpelcnt: %06lu,%06lu",
cristyf2faecf2010-05-28 19:19:36 +0000533 (unsigned long) image->columns,(unsigned long) image->rows);
cristy2d6ccc32009-09-25 03:18:25 +0000534 count=WriteCALSRecord(image,header);
cristy03117002009-09-19 02:10:44 +0000535 density=200;
536 if (image_info->density != (char *) NULL)
537 {
538 GeometryInfo
539 geometry_info;
540
541 (void) ParseGeometry(image_info->density,&geometry_info);
cristybb503372010-05-27 20:51:26 +0000542 density=(size_t) floor(geometry_info.rho+0.5);
cristy03117002009-09-19 02:10:44 +0000543 }
cristyf2a82ee2014-05-26 17:49:54 +0000544 (void) FormatLocaleString(header,sizeof(header),"rdensty: %04lu",
cristyf2faecf2010-05-28 19:19:36 +0000545 (unsigned long) density);
cristy2d6ccc32009-09-25 03:18:25 +0000546 count=WriteCALSRecord(image,header);
cristy03117002009-09-19 02:10:44 +0000547 count=WriteCALSRecord(image,"notes: NONE");
cristy2d6ccc32009-09-25 03:18:25 +0000548 (void) ResetMagickMemory(header,' ',128);
cristy03117002009-09-19 02:10:44 +0000549 for (i=0; i < 5; i++)
cristy2d6ccc32009-09-25 03:18:25 +0000550 (void) WriteBlob(image,128,(unsigned char *) header);
551 /*
552 Write CALS pixels.
553 */
554 write_info=CloneImageInfo(image_info);
cristy151b66d2015-04-15 10:50:31 +0000555 (void) CopyMagickString(write_info->filename,"GROUP4:",MagickPathExtent);
556 (void) CopyMagickString(write_info->magick,"GROUP4",MagickPathExtent);
cristy1e178e72011-08-28 19:44:34 +0000557 group4_image=CloneImage(image,0,0,MagickTrue,exception);
cristy2d6ccc32009-09-25 03:18:25 +0000558 if (group4_image == (Image *) NULL)
559 {
560 (void) CloseBlob(image);
561 return(MagickFalse);
562 }
563 group4=(unsigned char *) ImageToBlob(write_info,group4_image,&length,
cristy1e178e72011-08-28 19:44:34 +0000564 exception);
cristy2d6ccc32009-09-25 03:18:25 +0000565 group4_image=DestroyImage(group4_image);
566 if (group4 == (unsigned char *) NULL)
567 {
568 (void) CloseBlob(image);
569 return(MagickFalse);
570 }
571 write_info=DestroyImageInfo(write_info);
572 if (WriteBlob(image,length,group4) != (ssize_t) length)
573 status=MagickFalse;
574 group4=(unsigned char *) RelinquishMagickMemory(group4);
cristy03117002009-09-19 02:10:44 +0000575 (void) CloseBlob(image);
576 return(status);
577}
cristy316dac12009-12-07 17:19:28 +0000578#endif