Home | History | Annotate | Download | only in coders
      1 /*
      2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      3 %                                                                             %
      4 %                                                                             %
      5 %                                                                             %
      6 %                            H   H  RRRR   ZZZZZ                              %
      7 %                            H   H  R   R     ZZ                              %
      8 %                            HHHHH  RRRR     Z                                %
      9 %                            H   H  R R    ZZ                                 %
     10 %                            H   H  R  R   ZZZZZ                              %
     11 %                                                                             %
     12 %                                                                             %
     13 %                Read/Write Slow Scan TeleVision Image Format                 %
     14 %                                                                             %
     15 %                              Software Design                                %
     16 %                                   Cristy                                    %
     17 %                                 July 1992                                   %
     18 %                                                                             %
     19 %                                                                             %
     20 %  Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization      %
     21 %  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 %
     37 */
     38 
     39 /*
     41   Include declarations.
     42 */
     43 #include "MagickCore/studio.h"
     44 #include "MagickCore/blob.h"
     45 #include "MagickCore/blob-private.h"
     46 #include "MagickCore/cache.h"
     47 #include "MagickCore/colorspace.h"
     48 #include "MagickCore/colorspace-private.h"
     49 #include "MagickCore/exception.h"
     50 #include "MagickCore/exception-private.h"
     51 #include "MagickCore/image.h"
     52 #include "MagickCore/image-private.h"
     53 #include "MagickCore/list.h"
     54 #include "MagickCore/magick.h"
     55 #include "MagickCore/memory_.h"
     56 #include "MagickCore/monitor.h"
     57 #include "MagickCore/monitor-private.h"
     58 #include "MagickCore/pixel-accessor.h"
     59 #include "MagickCore/quantum-private.h"
     60 #include "MagickCore/static.h"
     61 #include "MagickCore/string_.h"
     62 #include "MagickCore/module.h"
     63 
     64 /*
     66   Forward declarations.
     67 */
     68 static MagickBooleanType
     69   WriteHRZImage(const ImageInfo *,Image *,ExceptionInfo *);
     70 
     71 /*
     73 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     74 %                                                                             %
     75 %                                                                             %
     76 %                                                                             %
     77 %   R e a d H R Z I m a g e                                                   %
     78 %                                                                             %
     79 %                                                                             %
     80 %                                                                             %
     81 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     82 %
     83 %  ReadHRZImage() reads a Slow Scan TeleVision image file and returns it.  It
     84 %  allocates the memory necessary for the new Image structure and returns a
     85 %  pointer to the new image.
     86 %
     87 %  The format of the ReadHRZImage method is:
     88 %
     89 %      Image *ReadHRZImage(const ImageInfo *image_info,ExceptionInfo *exception)
     90 %
     91 %  A description of each parameter follows:
     92 %
     93 %    o image_info: the image info.
     94 %
     95 %    o exception: return any errors or warnings in this structure.
     96 %
     97 */
     98 static Image *ReadHRZImage(const ImageInfo *image_info,ExceptionInfo *exception)
     99 {
    100   Image
    101     *image;
    102 
    103   MagickBooleanType
    104     status;
    105 
    106   register ssize_t
    107     x;
    108 
    109   register Quantum
    110     *q;
    111 
    112   register unsigned char
    113     *p;
    114 
    115   ssize_t
    116     count,
    117     y;
    118 
    119   size_t
    120     length;
    121 
    122   unsigned char
    123     *pixels;
    124 
    125   /*
    126     Open image file.
    127   */
    128   assert(image_info != (const ImageInfo *) NULL);
    129   assert(image_info->signature == MagickCoreSignature);
    130   if (image_info->debug != MagickFalse)
    131     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
    132       image_info->filename);
    133   assert(exception != (ExceptionInfo *) NULL);
    134   assert(exception->signature == MagickCoreSignature);
    135   image=AcquireImage(image_info,exception);
    136   status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
    137   if (status == MagickFalse)
    138     {
    139       image=DestroyImageList(image);
    140       return((Image *) NULL);
    141     }
    142   /*
    143     Convert HRZ raster image to pixel packets.
    144   */
    145   image->columns=256;
    146   image->rows=240;
    147   image->depth=8;
    148   status=SetImageExtent(image,image->columns,image->rows,exception);
    149   if (status == MagickFalse)
    150     return(DestroyImageList(image));
    151   pixels=(unsigned char *) AcquireQuantumMemory(image->columns,3*
    152     sizeof(*pixels));
    153   if (pixels == (unsigned char *) NULL)
    154     ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
    155   length=(size_t) (3*image->columns);
    156   for (y=0; y < (ssize_t) image->rows; y++)
    157   {
    158     count=ReadBlob(image,length,pixels);
    159     if ((size_t) count != length)
    160       ThrowReaderException(CorruptImageError,"UnableToReadImageData");
    161     p=pixels;
    162     q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
    163     if (q == (Quantum *) NULL)
    164       break;
    165     for (x=0; x < (ssize_t) image->columns; x++)
    166     {
    167       SetPixelRed(image,ScaleCharToQuantum(4**p++),q);
    168       SetPixelGreen(image,ScaleCharToQuantum(4**p++),q);
    169       SetPixelBlue(image,ScaleCharToQuantum(4**p++),q);
    170       SetPixelAlpha(image,OpaqueAlpha,q);
    171       q+=GetPixelChannels(image);
    172     }
    173     if (SyncAuthenticPixels(image,exception) == MagickFalse)
    174       break;
    175     if (SetImageProgress(image,LoadImageTag,y,image->rows) == MagickFalse)
    176       break;
    177   }
    178   pixels=(unsigned char *) RelinquishMagickMemory(pixels);
    179   if (EOFBlob(image) != MagickFalse)
    180     ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
    181       image->filename);
    182   (void) CloseBlob(image);
    183   return(GetFirstImageInList(image));
    184 }
    185 
    186 /*
    188 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    189 %                                                                             %
    190 %                                                                             %
    191 %                                                                             %
    192 %   R e g i s t e r H R Z I m a g e                                           %
    193 %                                                                             %
    194 %                                                                             %
    195 %                                                                             %
    196 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    197 %
    198 %  RegisterHRZImage() adds attributes for the HRZ X image format to the list
    199 %  of supported formats.  The attributes include the image format tag, a
    200 %  method to read and/or write the format, whether the format supports the
    201 %  saving of more than one frame to the same file or blob, whether the format
    202 %  supports native in-memory I/O, and a brief description of the format.
    203 %
    204 %  The format of the RegisterHRZImage method is:
    205 %
    206 %      size_t RegisterHRZImage(void)
    207 %
    208 */
    209 ModuleExport size_t RegisterHRZImage(void)
    210 {
    211   MagickInfo
    212     *entry;
    213 
    214   entry=AcquireMagickInfo("HRZ","HRZ","Slow Scan TeleVision");
    215   entry->decoder=(DecodeImageHandler *) ReadHRZImage;
    216   entry->encoder=(EncodeImageHandler *) WriteHRZImage;
    217   entry->flags^=CoderAdjoinFlag;
    218   (void) RegisterMagickInfo(entry);
    219   return(MagickImageCoderSignature);
    220 }
    221 
    222 /*
    224 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    225 %                                                                             %
    226 %                                                                             %
    227 %                                                                             %
    228 %   U n r e g i s t e r H R Z I m a g e                                       %
    229 %                                                                             %
    230 %                                                                             %
    231 %                                                                             %
    232 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    233 %
    234 %  UnregisterHRZImage() removes format registrations made by the
    235 %  HRZ module from the list of supported formats.
    236 %
    237 %  The format of the UnregisterHRZImage method is:
    238 %
    239 %      UnregisterHRZImage(void)
    240 %
    241 */
    242 ModuleExport void UnregisterHRZImage(void)
    243 {
    244   (void) UnregisterMagickInfo("HRZ");
    245 }
    246 
    247 /*
    249 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    250 %                                                                             %
    251 %                                                                             %
    252 %                                                                             %
    253 %   W r i t e H R Z I m a g e                                                 %
    254 %                                                                             %
    255 %                                                                             %
    256 %                                                                             %
    257 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    258 %
    259 %  WriteHRZImage() writes an image to a file in HRZ X image format.
    260 %
    261 %  The format of the WriteHRZImage method is:
    262 %
    263 %      MagickBooleanType WriteHRZImage(const ImageInfo *image_info,
    264 %        Image *image,ExceptionInfo *exception)
    265 %
    266 %  A description of each parameter follows.
    267 %
    268 %    o image_info: the image info.
    269 %
    270 %    o image:  The image.
    271 %
    272 %    o exception: return any errors or warnings in this structure.
    273 %
    274 */
    275 static MagickBooleanType WriteHRZImage(const ImageInfo *image_info,Image *image,
    276   ExceptionInfo *exception)
    277 {
    278   Image
    279     *hrz_image;
    280 
    281   MagickBooleanType
    282     status;
    283 
    284   register const Quantum
    285     *p;
    286 
    287   register ssize_t
    288     x,
    289     y;
    290 
    291   register unsigned char
    292     *q;
    293 
    294   ssize_t
    295     count;
    296 
    297   unsigned char
    298     *pixels;
    299 
    300   /*
    301     Open output image file.
    302   */
    303   assert(image_info != (const ImageInfo *) NULL);
    304   assert(image_info->signature == MagickCoreSignature);
    305   assert(image != (Image *) NULL);
    306   assert(image->signature == MagickCoreSignature);
    307   if (image->debug != MagickFalse)
    308     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
    309   assert(exception != (ExceptionInfo *) NULL);
    310   assert(exception->signature == MagickCoreSignature);
    311   status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
    312   if (status == MagickFalse)
    313     return(status);
    314   hrz_image=ResizeImage(image,256,240,image->filter,exception);
    315   if (hrz_image == (Image *) NULL)
    316     return(MagickFalse);
    317   (void) TransformImageColorspace(hrz_image,sRGBColorspace,exception);
    318   /*
    319     Allocate memory for pixels.
    320   */
    321   pixels=(unsigned char *) AcquireQuantumMemory((size_t) hrz_image->columns,
    322     3*sizeof(*pixels));
    323   if (pixels == (unsigned char *) NULL)
    324     {
    325       hrz_image=DestroyImage(hrz_image);
    326       ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
    327     }
    328   /*
    329     Convert MIFF to HRZ raster pixels.
    330   */
    331   for (y=0; y < (ssize_t) hrz_image->rows; y++)
    332   {
    333     p=GetVirtualPixels(hrz_image,0,y,hrz_image->columns,1,exception);
    334     if (p == (const Quantum *) NULL)
    335       break;
    336     q=pixels;
    337     for (x=0; x < (ssize_t) hrz_image->columns; x++)
    338     {
    339       *q++=ScaleQuantumToChar(GetPixelRed(hrz_image,p)/4);
    340       *q++=ScaleQuantumToChar(GetPixelGreen(hrz_image,p)/4);
    341       *q++=ScaleQuantumToChar(GetPixelBlue(hrz_image,p)/4);
    342       p+=GetPixelChannels(hrz_image);
    343     }
    344     count=WriteBlob(image,(size_t) (q-pixels),pixels);
    345     if (count != (ssize_t) (q-pixels))
    346       break;
    347     status=SetImageProgress(image,SaveImageTag,y,hrz_image->rows);
    348     if (status == MagickFalse)
    349       break;
    350   }
    351   pixels=(unsigned char *) RelinquishMagickMemory(pixels);
    352   hrz_image=DestroyImage(hrz_image);
    353   (void) CloseBlob(image);
    354   return(MagickTrue);
    355 }
    356