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