]> granicus.if.org Git - imagemagick/blobdiff - coders/cals.c
(no commit message)
[imagemagick] / coders / cals.c
index 1e487352f53d890f475a65c8f93944decea71901..43bba845a23f86343df63ffe1d92b4170454a182 100644 (file)
 %                         CCCC  A   A  LLLLL  SSSSS                           %
 %                                                                             %
 %                                                                             %
-%                        Read/Write CALS Image Format                         %
+%                 Read/Write CALS Raster Group 1 Image Format                 %
 %                                                                             %
 %                              Software Design                                %
 %                                John Cristy                                  %
 %                                 July 1992                                   %
 %                                                                             %
 %                                                                             %
-%  Copyright 1999-2009 ImageMagick Studio LLC, a non-profit organization      %
+%  Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization      %
 %  dedicated to making software imaging solutions freely available.           %
 %                                                                             %
 %  You may not use this file except in compliance with the License.  You may  %
 /*
   Include declarations.
 */
-#include "magick/studio.h"
-#include "magick/blob.h"
-#include "magick/blob-private.h"
-#include "magick/cache.h"
-#include "magick/colorspace.h"
-#include "magick/exception.h"
-#include "magick/exception-private.h"
-#include "magick/geometry.h"
-#include "magick/image.h"
-#include "magick/image-private.h"
-#include "magick/list.h"
-#include "magick/magick.h"
-#include "magick/memory_.h"
-#include "magick/monitor.h"
-#include "magick/monitor-private.h"
-#include "magick/quantum-private.h"
-#include "magick/resource_.h"
-#include "magick/static.h"
-#include "magick/string_.h"
-#include "magick/module.h"
+#include "MagickCore/studio.h"
+#include "MagickCore/blob.h"
+#include "MagickCore/blob-private.h"
+#include "MagickCore/cache.h"
+#include "MagickCore/colorspace.h"
+#include "MagickCore/constitute.h"
+#include "MagickCore/exception.h"
+#include "MagickCore/exception-private.h"
+#include "MagickCore/geometry.h"
+#include "MagickCore/image.h"
+#include "MagickCore/image-private.h"
+#include "MagickCore/list.h"
+#include "MagickCore/magick.h"
+#include "MagickCore/memory_.h"
+#include "MagickCore/monitor.h"
+#include "MagickCore/monitor-private.h"
+#include "MagickCore/option.h"
+#include "MagickCore/quantum-private.h"
+#include "MagickCore/resource_.h"
+#include "MagickCore/static.h"
+#include "MagickCore/string_.h"
+#include "MagickCore/module.h"
 \f
+#if defined(MAGICKCORE_TIFF_DELEGATE)
 /*
  Forward declarations.
 */
 static MagickBooleanType
-  WriteCALSImage(const ImageInfo *,Image *);
+  WriteCALSImage(const ImageInfo *,Image *,ExceptionInfo *);
+#endif
 \f
 /*
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -83,7 +87,7 @@ static MagickBooleanType
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
 %  IsCALS() returns MagickTrue if the image format type, identified by the
-%  magick string, is CALS.
+%  magick string, is CALS Raster Group 1.
 %
 %  The format of the IsCALS method is:
 %
@@ -120,9 +124,9 @@ static MagickBooleanType IsCALS(const unsigned char *magick,const size_t length)
 %                                                                             %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
-%  ReadCALSImage() reads an Automated Interchange of Technical Information,
-%  MIL-STD-1840A image file and returns it.  It allocates the memorient_y necessary
-%  for the new Image structure and returns a pointer to the new image.
+%  ReadCALSImage() reads an CALS Raster Group 1 image format image file and
+%  returns it.  It allocates the memory necessary for the new Image structure
+%  and returns a pointer to the new image.
 %
 %  The format of the ReadCALSImage method is:
 %
@@ -136,25 +140,13 @@ static MagickBooleanType IsCALS(const unsigned char *magick,const size_t length)
 %    o exception: return any errors or warnings in this structure.
 %
 */
-
-static inline size_t WriteCALSLSBLong(FILE *file,const unsigned int value)
-{
-  unsigned char
-    buffer[4];
-
-  buffer[0]=(unsigned char) value;
-  buffer[1]=(unsigned char) (value >> 8);
-  buffer[2]=(unsigned char) (value >> 16);
-  buffer[3]=(unsigned char) (value >> 24);
-  return(fwrite(buffer,1,4,file));
-}
-
 static Image *ReadCALSImage(const ImageInfo *image_info,
   ExceptionInfo *exception)
 {
   char
     filename[MaxTextExtent],
-    header[129];
+    header[129],
+    message[MaxTextExtent];
 
   FILE
     *file;
@@ -172,17 +164,10 @@ static Image *ReadCALSImage(const ImageInfo *image_info,
   MagickBooleanType
     status;
 
-  register long
+  register ssize_t
     i;
 
-  size_t
-    length;
-
-  ssize_t
-    offset,
-    strip_offset;
-
-  unsigned int
+  unsigned long
     density,
     direction,
     height,
@@ -201,7 +186,7 @@ static Image *ReadCALSImage(const ImageInfo *image_info,
       image_info->filename);
   assert(exception != (ExceptionInfo *) NULL);
   assert(exception->signature == MagickSignature);
-  image=AcquireImage(image_info);
+  image=AcquireImage(image_info,exception);
   status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
   if (status == MagickFalse)
     {
@@ -230,21 +215,21 @@ static Image *ReadCALSImage(const ImageInfo *image_info,
       {
         if (LocaleNCompare(header,"rdensty:",8) == 0)
           {
-            (void) sscanf(header+8,"%u",&density);
+            (void) sscanf(header+8,"%lu",&density);
             break;
           }
         if (LocaleNCompare(header,"rpelcnt:",8) == 0)
           {
-            (void) sscanf(header+8,"%u,%u",&width,&height);
+            (void) sscanf(header+8,"%lu,%lu",&width,&height);
             break;
           }
         if (LocaleNCompare(header,"rorient:",8) == 0)
           {
-            (void) sscanf(header+8,"%u,%u",&pel_path,&direction);
+            (void) sscanf(header+8,"%lu,%lu",&pel_path,&direction);
             if (pel_path == 90)
               orientation=5;
             else
-              if (pel_path == 90)
+              if (pel_path == 180)
                 orientation=3;
               else
                 if (pel_path == 270)
@@ -255,71 +240,48 @@ static Image *ReadCALSImage(const ImageInfo *image_info,
           }
         if (LocaleNCompare(header,"rtype:",6) == 0)
           {
-            (void) sscanf(header+6,"%u",&type);
+            (void) sscanf(header+6,"%lu",&type);
             break;
           }
         break;
       }
     }
   }
-  if ((width == 0) || (height == 0) || (type == 0))
-    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
   /*
-    Write CALS facsimile document wrapped as a TIFF image file.
+    Read CALS pixels.
   */
   file=(FILE *) NULL;
   unique_file=AcquireUniqueFileResource(filename);
   if (unique_file != -1)
     file=fdopen(unique_file,"wb");
   if ((unique_file == -1) || (file == (FILE *) NULL))
-    ThrowReaderException(FileOpenError,"UnableToCreateTemporaryFile");
-  length=fwrite("\111\111\052\000\010\000\000\000\016\000",1,10,file);
-  length=fwrite("\376\000\003\000\001\000\000\000\000\000\000\000",1,12,file);
-  length=fwrite("\000\001\004\000\001\000\000\000",1,8,file);
-  length=WriteCALSLSBLong(file,width);
-  length=fwrite("\001\001\004\000\001\000\000\000",1,8,file);
-  length=WriteCALSLSBLong(file,height);
-  length=fwrite("\002\001\003\000\001\000\000\000\001\000\000\000",1,12,file);
-  length=fwrite("\003\001\003\000\001\000\000\000\004\000\000\000",1,12,file);
-  length=fwrite("\006\001\003\000\001\000\000\000\000\000\000\000",1,12,file);
-  length=fwrite("\021\001\003\000\001\000\000\000",1,8,file);
-  strip_offset=10+(12*14)+4+8;
-  length=WriteCALSLSBLong(file,(unsigned int) strip_offset);
-  length=fwrite("\022\001\003\000\001\000\000\000",1,8,file);
-  length=WriteCALSLSBLong(file,orientation);
-  length=fwrite("\025\001\003\000\001\000\000\000\001\000\000\000",1,12,file);
-  length=fwrite("\026\001\004\000\001\000\000\000",1,8,file);
-  length=WriteCALSLSBLong(file,width);
-  length=fwrite("\027\001\004\000\001\000\000\000\000\000\000\000",1,12,file);
-  offset=(ssize_t) ftell(file)-4;
-  length=fwrite("\032\001\005\000\001\000\000\000",1,8,file);
-  length=WriteCALSLSBLong(file,(unsigned int) (strip_offset-8));
-  length=fwrite("\033\001\005\000\001\000\000\000",1,8,file);
-  length=WriteCALSLSBLong(file,(unsigned int) (strip_offset-8));
-  length=fwrite("\050\001\003\000\001\000\000\000\002\000\000\000",1,12,file);
-  length=fwrite("\000\000\000\000",1,4,file);
-  length=WriteCALSLSBLong(file,density);
-  length=WriteCALSLSBLong(file,1);
-  for (length=0; (c=ReadBlobByte(image)) != EOF; length++)
+    ThrowImageException(FileOpenError,"UnableToCreateTemporaryFile");
+  while ((c=ReadBlobByte(image)) != EOF)
     (void) fputc(c,file);
+  (void) fclose(file);
   (void) CloseBlob(image);
   image=DestroyImage(image);
-  offset=(ssize_t) fseek(file,(long) offset,SEEK_SET);
-  length=WriteCALSLSBLong(file,(unsigned int) length);
-  (void) fclose(file);
-  /*
-    Read TIFF image.
-  */
   read_info=CloneImageInfo(image_info);
   SetImageInfoBlob(read_info,(void *) NULL,0);
-  (void) FormatMagickString(read_info->filename,MaxTextExtent,"tiff:%.1024s",
+  (void) FormatLocaleString(read_info->filename,MaxTextExtent,"group4:%s",
     filename);
+  (void) FormatLocaleString(message,MaxTextExtent,"%lux%lu",width,height);
+  (void) CloneString(&read_info->size,message);
+  (void) FormatLocaleString(message,MaxTextExtent,"%lu",density);
+  (void) CloneString(&read_info->density,message);
+  read_info->orientation=(OrientationType) orientation;
   image=ReadImage(read_info,exception);
+  if (image != (Image *) NULL)
+    {
+      (void) CopyMagickString(image->filename,image_info->filename,
+        MaxTextExtent);
+      (void) CopyMagickString(image->magick_filename,image_info->filename,
+        MaxTextExtent);
+      (void) CopyMagickString(image->magick,"CALS",MaxTextExtent);
+    }
   read_info=DestroyImageInfo(read_info);
   (void) RelinquishUniqueFileResource(filename);
-  if (image == (Image *) NULL)
-    return(image);
-  return(GetFirstImageInList(image));
+  return(image);
 }
 \f
 /*
@@ -333,29 +295,53 @@ static Image *ReadCALSImage(const ImageInfo *image_info,
 %                                                                             %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
-%  RegisterCALSImage() adds attributes for the CALS X image format to the list
-%  of supported formats.  The attributes include the image format tag, a
-%  method to read and/or write the format, whether the format supports the
-%  saving of more than one frame to the same file or blob, whether the format
-%  supports native in-memorient_y I/O, and a brief description of the format.
+%  RegisterCALSImage() adds attributes for the CALS Raster Group 1 image file
+%  image format to the list of supported formats.  The attributes include the
+%  image format tag, a method to read and/or write the format, whether the
+%  format supports the saving of more than one frame to the same file or blob,
+%  whether the format supports native in-memory I/O, and a brief description
+%  of the format.
 %
 %  The format of the RegisterCALSImage method is:
 %
-%      unsigned long RegisterCALSImage(void)
+%      size_t RegisterCALSImage(void)
 %
 */
-ModuleExport unsigned long RegisterCALSImage(void)
+ModuleExport size_t RegisterCALSImage(void)
 {
   MagickInfo
     *entry;
 
+  static const char
+    *CALSDescription=
+    {
+      "Continuous Acquisition and Life-cycle Support Type 1"
+    },
+    *CALSNote=
+    {
+      "Specified in MIL-R-28002 and MIL-PRF-28002"
+    };
+
+  entry=SetMagickInfo("CAL");
+  entry->decoder=(DecodeImageHandler *) ReadCALSImage;
+#if defined(MAGICKCORE_TIFF_DELEGATE)
+  entry->encoder=(EncodeImageHandler *) WriteCALSImage;
+#endif
+  entry->adjoin=MagickFalse;
+  entry->magick=(IsImageFormatHandler *) IsCALS;
+  entry->description=ConstantString(CALSDescription);
+  entry->note=ConstantString(CALSNote);
+  entry->module=ConstantString("CALS");
+  (void) RegisterMagickInfo(entry);
   entry=SetMagickInfo("CALS");
   entry->decoder=(DecodeImageHandler *) ReadCALSImage;
+#if defined(MAGICKCORE_TIFF_DELEGATE)
   entry->encoder=(EncodeImageHandler *) WriteCALSImage;
+#endif
   entry->adjoin=MagickFalse;
   entry->magick=(IsImageFormatHandler *) IsCALS;
-  entry->description=ConstantString("Automated Interchange of Technical "
-    "Information, MIL-STD-1840A");
+  entry->description=ConstantString(CALSDescription);
+  entry->note=ConstantString(CALSNote);
   entry->module=ConstantString("CALS");
   (void) RegisterMagickInfo(entry);
   return(MagickImageCoderSignature);
@@ -382,9 +368,11 @@ ModuleExport unsigned long RegisterCALSImage(void)
 */
 ModuleExport void UnregisterCALSImage(void)
 {
+  (void) UnregisterMagickInfo("CAL");
   (void) UnregisterMagickInfo("CALS");
 }
 \f
+#if defined(MAGICKCORE_TIFF_DELEGATE)
 /*
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %                                                                             %
@@ -396,12 +384,13 @@ ModuleExport void UnregisterCALSImage(void)
 %                                                                             %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
-%  WriteCALSImage() writes an image to a file in CALS type I image format.
+%  WriteCALSImage() writes an image to a file in CALS Raster Group 1 image
+%  format.
 %
 %  The format of the WriteCALSImage method is:
 %
 %      MagickBooleanType WriteCALSImage(const ImageInfo *image_info,
-%        Image *image)
+%        Image *image,ExceptionInfo *exception)
 %
 %  A description of each parameter follows.
 %
@@ -409,61 +398,71 @@ ModuleExport void UnregisterCALSImage(void)
 %
 %    o image:  The image.
 %
+%    o exception: return any errors or warnings in this structure.
+%
 */
 
-static MagickBooleanType WriteCALSRecord(Image *image,const char *data)
+static ssize_t WriteCALSRecord(Image *image,const char *data)
 {
   char
     pad[128];
 
-  ssize_t
-    count;
-
   register const char
     *p;
 
-  register long
+  register ssize_t
     i;
 
+  ssize_t
+    count;
+
   i=0;
+  count=0;
   if (data != (const char *) NULL)
     {
       p=data;
       for (i=0; (i < 128) && (p[i] != '\0'); i++);
-      count=WriteBlob(image,(size_t) i,(unsigned char *) data);
+      count=WriteBlob(image,(size_t) i,(const unsigned char *) data);
     }
   if (i < 128)
     {
-      /*
-        Pad CALS record.
-      */
       i=128-i;
       (void) ResetMagickMemory(pad,' ',(size_t) i);
-      count=WriteBlob(image,(size_t) i,(unsigned char *) pad);
+      count=WriteBlob(image,(size_t) i,(const unsigned char *) pad);
     }
   return(count);
 }
 
 static MagickBooleanType WriteCALSImage(const ImageInfo *image_info,
-  Image *image)
+  Image *image,ExceptionInfo *exception)
 {
   char
-    buffer[129];
+    header[129];
+
+  Image
+    *group4_image;
+
+  ImageInfo
+    *write_info;
 
   MagickBooleanType
     status;
 
-  register long
+  register ssize_t
     i;
 
-  ssize_t
-    count;
-
-  unsigned long
+  size_t
     density,
+    length,
     orient_x,
     orient_y;
 
+  ssize_t
+    count;
+
+  unsigned char
+    *group4;
+
   /*
     Open output image file.
   */
@@ -473,19 +472,24 @@ static MagickBooleanType WriteCALSImage(const ImageInfo *image_info,
   assert(image->signature == MagickSignature);
   if (image->debug != MagickFalse)
     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
-  status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
+  assert(exception != (ExceptionInfo *) NULL);
+  assert(exception->signature == MagickSignature);
+  status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
   if (status == MagickFalse)
     return(status);
   /*
     Create standard CALS header.
   */
   count=WriteCALSRecord(image,"srcdocid: NONE");
+  (void) count;
   count=WriteCALSRecord(image,"dstdocid: NONE");
   count=WriteCALSRecord(image,"txtfilid: NONE");
   count=WriteCALSRecord(image,"figid: NONE");
   count=WriteCALSRecord(image,"srcgph: NONE");
   count=WriteCALSRecord(image,"docls: NONE");
   count=WriteCALSRecord(image,"rtype: 1");
+  orient_x=0;
+  orient_y=0;
   switch (image->orientation)
   {
     case TopRightOrientation:
@@ -501,13 +505,13 @@ static MagickBooleanType WriteCALSImage(const ImageInfo *image_info,
       break;
     }
     case BottomLeftOrientation:
-      orient_x=0;
+    {
       orient_y=90;
       break;
+    }
     case LeftTopOrientation:
     {
       orient_x=270;
-      orient_y=0;
       break;
     }
     case RightTopOrientation:
@@ -525,21 +529,19 @@ static MagickBooleanType WriteCALSImage(const ImageInfo *image_info,
     case LeftBottomOrientation:
     {
       orient_x=90;
-      orient_y=0;
       break;
     }
     default:
     {
-      orient_x=0; 
       orient_y=270;
     }
   }
-  (void) FormatMagickString(buffer,MaxTextExtent,"rorient: %03ld,%03ld",
-    orient_x,orient_y);
-  count=WriteCALSRecord(image,buffer);
-  (void) FormatMagickString(buffer,MaxTextExtent,"rpelcnt: %06lu,%06lu",
-    image->columns,image->rows);
-  count=WriteCALSRecord(image,buffer);  
+  (void) FormatLocaleString(header,MaxTextExtent,"rorient: %03ld,%03ld",
+    (long) orient_x,(long) orient_y);
+  count=WriteCALSRecord(image,header);
+  (void) FormatLocaleString(header,MaxTextExtent,"rpelcnt: %06lu,%06lu",
+    (unsigned long) image->columns,(unsigned long) image->rows);
+  count=WriteCALSRecord(image,header);  
   density=200;
   if (image_info->density != (char *) NULL)
     {
@@ -547,15 +549,40 @@ static MagickBooleanType WriteCALSImage(const ImageInfo *image_info,
         geometry_info;
 
       (void) ParseGeometry(image_info->density,&geometry_info);
-      density=(unsigned long) (geometry_info.rho+0.5);
+      density=(size_t) floor(geometry_info.rho+0.5);
     }
-  (void) FormatMagickString(buffer,MaxTextExtent,"rdensty: %04lu",density);
-  count=WriteCALSRecord(image,buffer);
+  (void) FormatLocaleString(header,MaxTextExtent,"rdensty: %04lu",
+    (unsigned long) density);
+  count=WriteCALSRecord(image,header);
   count=WriteCALSRecord(image,"notes: NONE");
-  (void) ResetMagickMemory(buffer,' ',128);
+  (void) ResetMagickMemory(header,' ',128);
   for (i=0; i < 5; i++)
-    (void) WriteBlob(image,128,(unsigned char *) buffer);
-  status=Huffman2DEncodeImage(image_info,image,image);
+    (void) WriteBlob(image,128,(unsigned char *) header);
+  /*
+    Write CALS pixels.
+  */
+  write_info=CloneImageInfo(image_info);
+  (void) CopyMagickString(write_info->filename,"GROUP4:",MaxTextExtent);
+  (void) CopyMagickString(write_info->magick,"GROUP4",MaxTextExtent);
+  group4_image=CloneImage(image,0,0,MagickTrue,exception);
+  if (group4_image == (Image *) NULL)
+    {
+      (void) CloseBlob(image);
+      return(MagickFalse);
+    }
+  group4=(unsigned char *) ImageToBlob(write_info,group4_image,&length,
+    exception);
+  group4_image=DestroyImage(group4_image);
+  if (group4 == (unsigned char *) NULL)
+    {
+      (void) CloseBlob(image);
+      return(MagickFalse);
+    }
+  write_info=DestroyImageInfo(write_info);
+  if (WriteBlob(image,length,group4) != (ssize_t) length)
+    status=MagickFalse;
+  group4=(unsigned char *) RelinquishMagickMemory(group4);
   (void) CloseBlob(image);
   return(status);
 }
+#endif