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-2019 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 %    https://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       {
    161         pixels=(unsigned char *) RelinquishMagickMemory(pixels);
    162         ThrowReaderException(CorruptImageError,"UnableToReadImageData");
    163       }
    164     p=pixels;
    165     q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
    166     if (q == (Quantum *) NULL)
    167       break;
    168     for (x=0; x < (ssize_t) image->columns; x++)
    169     {
    170       SetPixelRed(image,ScaleCharToQuantum(4**p++),q);
    171       SetPixelGreen(image,ScaleCharToQuantum(4**p++),q);
    172       SetPixelBlue(image,ScaleCharToQuantum(4**p++),q);
    173       SetPixelAlpha(image,OpaqueAlpha,q);
    174       q+=GetPixelChannels(image);
    175     }
    176     if (SyncAuthenticPixels(image,exception) == MagickFalse)
    177       break;
    178     if (SetImageProgress(image,LoadImageTag,y,image->rows) == MagickFalse)
    179       break;
    180   }
    181   pixels=(unsigned char *) RelinquishMagickMemory(pixels);
    182   if (EOFBlob(image) != MagickFalse)
    183     ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
    184       image->filename);
    185   (void) CloseBlob(image);
    186   return(GetFirstImageInList(image));
    187 }
    188 
    189 /*
    191 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    192 %                                                                             %
    193 %                                                                             %
    194 %                                                                             %
    195 %   R e g i s t e r H R Z I m a g e                                           %
    196 %                                                                             %
    197 %                                                                             %
    198 %                                                                             %
    199 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    200 %
    201 %  RegisterHRZImage() adds attributes for the HRZ X image format to the list
    202 %  of supported formats.  The attributes include the image format tag, a
    203 %  method to read and/or write the format, whether the format supports the
    204 %  saving of more than one frame to the same file or blob, whether the format
    205 %  supports native in-memory I/O, and a brief description of the format.
    206 %
    207 %  The format of the RegisterHRZImage method is:
    208 %
    209 %      size_t RegisterHRZImage(void)
    210 %
    211 */
    212 ModuleExport size_t RegisterHRZImage(void)
    213 {
    214   MagickInfo
    215     *entry;
    216 
    217   entry=AcquireMagickInfo("HRZ","HRZ","Slow Scan TeleVision");
    218   entry->decoder=(DecodeImageHandler *) ReadHRZImage;
    219   entry->encoder=(EncodeImageHandler *) WriteHRZImage;
    220   entry->flags^=CoderAdjoinFlag;
    221   (void) RegisterMagickInfo(entry);
    222   return(MagickImageCoderSignature);
    223 }
    224 
    225 /*
    227 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    228 %                                                                             %
    229 %                                                                             %
    230 %                                                                             %
    231 %   U n r e g i s t e r H R Z I m a g e                                       %
    232 %                                                                             %
    233 %                                                                             %
    234 %                                                                             %
    235 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    236 %
    237 %  UnregisterHRZImage() removes format registrations made by the
    238 %  HRZ module from the list of supported formats.
    239 %
    240 %  The format of the UnregisterHRZImage method is:
    241 %
    242 %      UnregisterHRZImage(void)
    243 %
    244 */
    245 ModuleExport void UnregisterHRZImage(void)
    246 {
    247   (void) UnregisterMagickInfo("HRZ");
    248 }
    249 
    250 /*
    252 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    253 %                                                                             %
    254 %                                                                             %
    255 %                                                                             %
    256 %   W r i t e H R Z I m a g e                                                 %
    257 %                                                                             %
    258 %                                                                             %
    259 %                                                                             %
    260 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    261 %
    262 %  WriteHRZImage() writes an image to a file in HRZ X image format.
    263 %
    264 %  The format of the WriteHRZImage method is:
    265 %
    266 %      MagickBooleanType WriteHRZImage(const ImageInfo *image_info,
    267 %        Image *image,ExceptionInfo *exception)
    268 %
    269 %  A description of each parameter follows.
    270 %
    271 %    o image_info: the image info.
    272 %
    273 %    o image:  The image.
    274 %
    275 %    o exception: return any errors or warnings in this structure.
    276 %
    277 */
    278 static MagickBooleanType WriteHRZImage(const ImageInfo *image_info,Image *image,
    279   ExceptionInfo *exception)
    280 {
    281   Image
    282     *hrz_image;
    283 
    284   MagickBooleanType
    285     status;
    286 
    287   register const Quantum
    288     *p;
    289 
    290   register ssize_t
    291     x,
    292     y;
    293 
    294   register unsigned char
    295     *q;
    296 
    297   ssize_t
    298     count;
    299 
    300   unsigned char
    301     *pixels;
    302 
    303   /*
    304     Open output image file.
    305   */
    306   assert(image_info != (const ImageInfo *) NULL);
    307   assert(image_info->signature == MagickCoreSignature);
    308   assert(image != (Image *) NULL);
    309   assert(image->signature == MagickCoreSignature);
    310   if (image->debug != MagickFalse)
    311     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
    312   assert(exception != (ExceptionInfo *) NULL);
    313   assert(exception->signature == MagickCoreSignature);
    314   status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
    315   if (status == MagickFalse)
    316     return(status);
    317   hrz_image=ResizeImage(image,256,240,image->filter,exception);
    318   if (hrz_image == (Image *) NULL)
    319     return(MagickFalse);
    320   (void) TransformImageColorspace(hrz_image,sRGBColorspace,exception);
    321   /*
    322     Allocate memory for pixels.
    323   */
    324   pixels=(unsigned char *) AcquireQuantumMemory((size_t) hrz_image->columns,
    325     3*sizeof(*pixels));
    326   if (pixels == (unsigned char *) NULL)
    327     {
    328       hrz_image=DestroyImage(hrz_image);
    329       ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
    330     }
    331   /*
    332     Convert MIFF to HRZ raster pixels.
    333   */
    334   for (y=0; y < (ssize_t) hrz_image->rows; y++)
    335   {
    336     p=GetVirtualPixels(hrz_image,0,y,hrz_image->columns,1,exception);
    337     if (p == (const Quantum *) NULL)
    338       break;
    339     q=pixels;
    340     for (x=0; x < (ssize_t) hrz_image->columns; x++)
    341     {
    342       *q++=ScaleQuantumToChar(GetPixelRed(hrz_image,p)/4);
    343       *q++=ScaleQuantumToChar(GetPixelGreen(hrz_image,p)/4);
    344       *q++=ScaleQuantumToChar(GetPixelBlue(hrz_image,p)/4);
    345       p+=GetPixelChannels(hrz_image);
    346     }
    347     count=WriteBlob(image,(size_t) (q-pixels),pixels);
    348     if (count != (ssize_t) (q-pixels))
    349       break;
    350     status=SetImageProgress(image,SaveImageTag,y,hrz_image->rows);
    351     if (status == MagickFalse)
    352       break;
    353   }
    354   pixels=(unsigned char *) RelinquishMagickMemory(pixels);
    355   hrz_image=DestroyImage(hrz_image);
    356   (void) CloseBlob(image);
    357   return(MagickTrue);
    358 }
    359