2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10 % CCCC A A LLLLL SSSSS %
13 % Read/Write CALS Image Format %
20 % Copyright 1999-2009 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
26 % http://www.imagemagick.org/script/license.php %
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. %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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.
47 #include "magick/studio.h"
48 #include "magick/blob.h"
49 #include "magick/blob-private.h"
50 #include "magick/cache.h"
51 #include "magick/colorspace.h"
52 #include "magick/exception.h"
53 #include "magick/exception-private.h"
54 #include "magick/image.h"
55 #include "magick/image-private.h"
56 #include "magick/list.h"
57 #include "magick/magick.h"
58 #include "magick/memory_.h"
59 #include "magick/monitor.h"
60 #include "magick/monitor-private.h"
61 #include "magick/quantum-private.h"
62 #include "magick/resource_.h"
63 #include "magick/static.h"
64 #include "magick/string_.h"
65 #include "magick/module.h"
68 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
76 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
78 % IsCALS() returns MagickTrue if the image format type, identified by the
79 % magick string, is CALS.
81 % The format of the IsCALS method is:
83 % MagickBooleanType IsCALS(const unsigned char *magick,const size_t length)
85 % A description of each parameter follows:
87 % o magick: compare image format pattern against these bytes.
89 % o length: Specifies the length of the magick string.
92 static MagickBooleanType IsCALS(const unsigned char *magick,const size_t length)
96 if (LocaleNCompare((char *) magick,"version: MIL-STD-1840",21) == 0)
98 if (LocaleNCompare((char *) magick,"srcdocid:",9) == 0)
100 if (LocaleNCompare((char *) magick,"rorient:",8) == 0)
106 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
110 % R e a d C A L S I m a g e %
114 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
116 % ReadCALSImage() reads an Automated Interchange of Technical Information,
117 % MIL-STD-1840A image file and returns it. It allocates the memory necessary
118 % for the new Image structure and returns a pointer to the new image.
120 % The format of the ReadCALSImage method is:
122 % Image *ReadCALSImage(const ImageInfo *image_info,
123 % ExceptionInfo *exception)
125 % A description of each parameter follows:
127 % o image_info: the image info.
129 % o exception: return any errors or warnings in this structure.
133 static inline size_t WriteCALSLSBLong(FILE *file,const unsigned int value)
138 buffer[0]=(unsigned char) value;
139 buffer[1]=(unsigned char) (value >> 8);
140 buffer[2]=(unsigned char) (value >> 16);
141 buffer[3]=(unsigned char) (value >> 24);
142 return(fwrite(buffer,1,4,file));
145 static Image *ReadCALSImage(const ImageInfo *image_info,
146 ExceptionInfo *exception)
149 filename[MaxTextExtent],
190 assert(image_info != (const ImageInfo *) NULL);
191 assert(image_info->signature == MagickSignature);
192 if (image_info->debug != MagickFalse)
193 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
194 image_info->filename);
195 assert(exception != (ExceptionInfo *) NULL);
196 assert(exception->signature == MagickSignature);
197 image=AcquireImage(image_info);
198 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
199 if (status == MagickFalse)
201 image=DestroyImageList(image);
202 return((Image *) NULL);
207 (void) ResetMagickMemory(header,0,sizeof(header));
215 for (i=0; i < 16; i++)
217 if (ReadBlob(image,128,(unsigned char *) header) != 128)
224 if (LocaleNCompare(header,"rdensty:",8) == 0)
226 (void) sscanf(header+8,"%u",&density);
229 if (LocaleNCompare(header,"rpelcnt:",8) == 0)
231 (void) sscanf(header+8,"%u,%u",&width,&height);
234 if (LocaleNCompare(header,"rorient:",8) == 0)
236 (void) sscanf(header+8,"%u,%u",&pel_path,&direction);
249 if (LocaleNCompare(header,"rtype:",6) == 0)
251 (void) sscanf(header+6,"%u",&type);
258 if ((width == 0) || (height == 0) || (type == 0))
259 ThrowReaderException(CorruptImageError,"ImproperImageHeader");
261 Write CALS facsimile document wrapped as a TIFF image file.
264 unique_file=AcquireUniqueFileResource(filename);
265 if (unique_file != -1)
266 file=fdopen(unique_file,"wb");
267 if ((unique_file == -1) || (file == (FILE *) NULL))
268 ThrowReaderException(FileOpenError,"UnableToCreateTemporaryFile");
269 length=fwrite("\111\111\052\000\010\000\000\000\016\000",1,10,file);
270 length=fwrite("\376\000\003\000\001\000\000\000\000\000\000\000",1,12,file);
271 length=fwrite("\000\001\004\000\001\000\000\000",1,8,file);
272 length=WriteCALSLSBLong(file,width);
273 length=fwrite("\001\001\004\000\001\000\000\000",1,8,file);
274 length=WriteCALSLSBLong(file,height);
275 length=fwrite("\002\001\003\000\001\000\000\000\001\000\000\000",1,12,file);
276 length=fwrite("\003\001\003\000\001\000\000\000\004\000\000\000",1,12,file);
277 length=fwrite("\006\001\003\000\001\000\000\000\000\000\000\000",1,12,file);
278 length=fwrite("\021\001\003\000\001\000\000\000",1,8,file);
279 strip_offset=10+(12*14)+4+8;
280 length=WriteCALSLSBLong(file,(unsigned int) strip_offset);
281 length=fwrite("\022\001\003\000\001\000\000\000",1,8,file);
282 length=WriteCALSLSBLong(file,orientation);
283 length=fwrite("\025\001\003\000\001\000\000\000\001\000\000\000",1,12,file);
284 length=fwrite("\026\001\004\000\001\000\000\000",1,8,file);
285 length=WriteCALSLSBLong(file,width);
286 length=fwrite("\027\001\004\000\001\000\000\000\000\000\000\000",1,12,file);
287 offset=(ssize_t) ftell(file)-4;
288 length=fwrite("\032\001\005\000\001\000\000\000",1,8,file);
289 length=WriteCALSLSBLong(file,(unsigned int) (strip_offset-8));
290 length=fwrite("\033\001\005\000\001\000\000\000",1,8,file);
291 length=WriteCALSLSBLong(file,(unsigned int) (strip_offset-8));
292 length=fwrite("\050\001\003\000\001\000\000\000\002\000\000\000",1,12,file);
293 length=fwrite("\000\000\000\000",1,4,file);
294 length=WriteCALSLSBLong(file,density);
295 length=WriteCALSLSBLong(file,1);
296 for (length=0; (c=ReadBlobByte(image)) != EOF; length++)
297 (void) fputc(c,file);
298 (void) CloseBlob(image);
299 image=DestroyImage(image);
300 offset=(ssize_t) fseek(file,(long) offset,SEEK_SET);
301 length=WriteCALSLSBLong(file,(unsigned int) length);
306 read_info=CloneImageInfo(image_info);
307 SetImageInfoBlob(read_info,(void *) NULL,0);
308 (void) FormatMagickString(read_info->filename,MaxTextExtent,"tiff:%.1024s",
310 image=ReadImage(read_info,exception);
311 read_info=DestroyImageInfo(read_info);
312 (void) RelinquishUniqueFileResource(filename);
313 if (image == (Image *) NULL)
315 return(GetFirstImageInList(image));
319 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
323 % R e g i s t e r C A L S I m a g e %
327 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
329 % RegisterCALSImage() adds attributes for the CALS X image format to the list
330 % of supported formats. The attributes include the image format tag, a
331 % method to read and/or write the format, whether the format supports the
332 % saving of more than one frame to the same file or blob, whether the format
333 % supports native in-memory I/O, and a brief description of the format.
335 % The format of the RegisterCALSImage method is:
337 % unsigned long RegisterCALSImage(void)
340 ModuleExport unsigned long RegisterCALSImage(void)
345 entry=SetMagickInfo("CALS");
346 entry->decoder=(DecodeImageHandler *) ReadCALSImage;
347 entry->adjoin=MagickFalse;
348 entry->magick=(IsImageFormatHandler *) IsCALS;
349 entry->description=ConstantString("Automated Interchange of Technical "
350 "Information, MIL-STD-1840A");
351 entry->module=ConstantString("CALS");
352 (void) RegisterMagickInfo(entry);
353 return(MagickImageCoderSignature);
357 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
361 % U n r e g i s t e r C A L S I m a g e %
365 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
367 % UnregisterCALSImage() removes format registrations made by the
368 % CALS module from the list of supported formats.
370 % The format of the UnregisterCALSImage method is:
372 % UnregisterCALSImage(void)
375 ModuleExport void UnregisterCALSImage(void)
377 (void) UnregisterMagickInfo("CALS");