blob: cf1292cf47f8a53db9df7f82715074769a2eb79d [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
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% John Cristy %
17% July 1992 %
18% %
19% %
cristy7e41fe82010-12-04 23:12:08 +000020% Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization %
cristy3ed852e2009-09-05 21:47:34 +000021% 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*/
cristy4c08aed2011-07-01 19:47:50 +000042#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/exception.h"
48#include "MagickCore/exception-private.h"
49#include "MagickCore/image.h"
50#include "MagickCore/image-private.h"
51#include "MagickCore/list.h"
52#include "MagickCore/magick.h"
53#include "MagickCore/memory_.h"
54#include "MagickCore/monitor.h"
55#include "MagickCore/monitor-private.h"
56#include "MagickCore/pixel-accessor.h"
57#include "MagickCore/quantum-private.h"
58#include "MagickCore/static.h"
59#include "MagickCore/string_.h"
60#include "MagickCore/module.h"
cristy3ed852e2009-09-05 21:47:34 +000061
62/*
63 Forward declarations.
64*/
65static MagickBooleanType
66 WriteHRZImage(const ImageInfo *,Image *);
67
68/*
69%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
70% %
71% %
72% %
73% R e a d H R Z I m a g e %
74% %
75% %
76% %
77%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
78%
79% ReadHRZImage() reads a Slow Scan TeleVision image file and returns it. It
80% allocates the memory necessary for the new Image structure and returns a
81% pointer to the new image.
82%
83% The format of the ReadHRZImage method is:
84%
85% Image *ReadHRZImage(const ImageInfo *image_info,ExceptionInfo *exception)
86%
87% A description of each parameter follows:
88%
89% o image_info: the image info.
90%
91% o exception: return any errors or warnings in this structure.
92%
93*/
94static Image *ReadHRZImage(const ImageInfo *image_info,ExceptionInfo *exception)
95{
96 Image
97 *image;
98
cristy3ed852e2009-09-05 21:47:34 +000099 MagickBooleanType
100 status;
101
cristybb503372010-05-27 20:51:26 +0000102 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000103 x;
104
cristy4c08aed2011-07-01 19:47:50 +0000105 register Quantum
cristy3ed852e2009-09-05 21:47:34 +0000106 *q;
107
108 register unsigned char
109 *p;
110
111 ssize_t
cristyebc891a2011-04-24 23:04:16 +0000112 count,
113 y;
cristy3ed852e2009-09-05 21:47:34 +0000114
115 size_t
116 length;
117
118 unsigned char
119 *pixels;
120
121 /*
122 Open image file.
123 */
124 assert(image_info != (const ImageInfo *) NULL);
125 assert(image_info->signature == MagickSignature);
126 if (image_info->debug != MagickFalse)
127 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
128 image_info->filename);
129 assert(exception != (ExceptionInfo *) NULL);
130 assert(exception->signature == MagickSignature);
131 image=AcquireImage(image_info);
132 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
133 if (status == MagickFalse)
134 {
135 image=DestroyImageList(image);
136 return((Image *) NULL);
137 }
138 /*
139 Convert HRZ raster image to pixel packets.
140 */
141 image->columns=256;
142 image->rows=240;
143 image->depth=8;
cristyebc891a2011-04-24 23:04:16 +0000144 pixels=(unsigned char *) AcquireQuantumMemory(image->columns,3*
145 sizeof(*pixels));
cristy3ed852e2009-09-05 21:47:34 +0000146 if (pixels == (unsigned char *) NULL)
147 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
148 length=(size_t) (3*image->columns);
cristybb503372010-05-27 20:51:26 +0000149 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +0000150 {
151 count=ReadBlob(image,length,pixels);
152 if ((size_t) count != length)
153 ThrowReaderException(CorruptImageError,"UnableToReadImageData");
154 p=pixels;
155 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
cristy4c08aed2011-07-01 19:47:50 +0000156 if (q == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000157 break;
cristybb503372010-05-27 20:51:26 +0000158 for (x=0; x < (ssize_t) image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +0000159 {
cristy4c08aed2011-07-01 19:47:50 +0000160 SetPixelRed(image,4*ScaleCharToQuantum(*p++),q);
161 SetPixelGreen(image,4*ScaleCharToQuantum(*p++),q);
162 SetPixelBlue(image,4*ScaleCharToQuantum(*p++),q);
163 SetPixelAlpha(image,OpaqueAlpha,q);
164 q+=GetPixelChannels(image);
cristy3ed852e2009-09-05 21:47:34 +0000165 }
166 if (SyncAuthenticPixels(image,exception) == MagickFalse)
167 break;
168 if (SetImageProgress(image,LoadImageTag,y,image->rows) == MagickFalse)
169 break;
170 }
171 pixels=(unsigned char *) RelinquishMagickMemory(pixels);
172 if (EOFBlob(image) != MagickFalse)
173 ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
174 image->filename);
175 (void) CloseBlob(image);
176 return(GetFirstImageInList(image));
177}
178
179/*
180%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
181% %
182% %
183% %
184% R e g i s t e r H R Z I m a g e %
185% %
186% %
187% %
188%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
189%
190% RegisterHRZImage() adds attributes for the HRZ X image format to the list
191% of supported formats. The attributes include the image format tag, a
192% method to read and/or write the format, whether the format supports the
193% saving of more than one frame to the same file or blob, whether the format
194% supports native in-memory I/O, and a brief description of the format.
195%
196% The format of the RegisterHRZImage method is:
197%
cristybb503372010-05-27 20:51:26 +0000198% size_t RegisterHRZImage(void)
cristy3ed852e2009-09-05 21:47:34 +0000199%
200*/
cristybb503372010-05-27 20:51:26 +0000201ModuleExport size_t RegisterHRZImage(void)
cristy3ed852e2009-09-05 21:47:34 +0000202{
203 MagickInfo
204 *entry;
205
206 entry=SetMagickInfo("HRZ");
207 entry->decoder=(DecodeImageHandler *) ReadHRZImage;
208 entry->encoder=(EncodeImageHandler *) WriteHRZImage;
209 entry->adjoin=MagickFalse;
210 entry->description=ConstantString("Slow Scan TeleVision");
211 entry->module=ConstantString("HRZ");
212 (void) RegisterMagickInfo(entry);
213 return(MagickImageCoderSignature);
214}
215
216/*
217%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
218% %
219% %
220% %
221% U n r e g i s t e r H R Z I m a g e %
222% %
223% %
224% %
225%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
226%
227% UnregisterHRZImage() removes format registrations made by the
228% HRZ module from the list of supported formats.
229%
230% The format of the UnregisterHRZImage method is:
231%
232% UnregisterHRZImage(void)
233%
234*/
235ModuleExport void UnregisterHRZImage(void)
236{
237 (void) UnregisterMagickInfo("HRZ");
238}
239
240/*
241%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
242% %
243% %
244% %
245% W r i t e H R Z I m a g e %
246% %
247% %
248% %
249%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
250%
251% WriteHRZImage() writes an image to a file in HRZ X image format.
252%
253% The format of the WriteHRZImage method is:
254%
255% MagickBooleanType WriteHRZImage(const ImageInfo *image_info,Image *image)
256%
257% A description of each parameter follows.
258%
259% o image_info: the image info.
260%
261% o image: The image.
262%
263*/
264static MagickBooleanType WriteHRZImage(const ImageInfo *image_info,Image *image)
265{
266 Image
267 *hrz_image;
268
269 MagickBooleanType
270 status;
271
cristy4c08aed2011-07-01 19:47:50 +0000272 register const Quantum
cristy3ed852e2009-09-05 21:47:34 +0000273 *p;
274
cristybb503372010-05-27 20:51:26 +0000275 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000276 x,
277 y;
278
279 register unsigned char
280 *q;
281
282 ssize_t
283 count;
284
285 unsigned char
286 *pixels;
287
288 /*
289 Open output image file.
290 */
291 assert(image_info != (const ImageInfo *) NULL);
292 assert(image_info->signature == MagickSignature);
293 assert(image != (Image *) NULL);
294 assert(image->signature == MagickSignature);
295 if (image->debug != MagickFalse)
296 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
297 status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
298 if (status == MagickFalse)
299 return(status);
300 hrz_image=ResizeImage(image,256,240,image->filter,image->blur,
301 &image->exception);
302 if (hrz_image == (Image *) NULL)
303 return(MagickFalse);
304 if (hrz_image->colorspace != RGBColorspace)
305 (void) TransformImageColorspace(hrz_image,RGBColorspace);
306 /*
307 Allocate memory for pixels.
308 */
309 pixels=(unsigned char *) AcquireQuantumMemory((size_t) hrz_image->columns,
310 3*sizeof(*pixels));
311 if (pixels == (unsigned char *) NULL)
312 {
313 hrz_image=DestroyImage(hrz_image);
314 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
315 }
316 /*
317 Convert MIFF to HRZ raster pixels.
318 */
cristybb503372010-05-27 20:51:26 +0000319 for (y=0; y < (ssize_t) hrz_image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +0000320 {
321 p=GetVirtualPixels(hrz_image,0,y,hrz_image->columns,1,&image->exception);
cristy4c08aed2011-07-01 19:47:50 +0000322 if (p == (const Quantum *) NULL)
cristy3ed852e2009-09-05 21:47:34 +0000323 break;
324 q=pixels;
cristybb503372010-05-27 20:51:26 +0000325 for (x=0; x < (ssize_t) hrz_image->columns; x++)
cristy3ed852e2009-09-05 21:47:34 +0000326 {
cristy4c08aed2011-07-01 19:47:50 +0000327 *q++=ScaleQuantumToChar(GetPixelRed(hrz_image,p))/4;
328 *q++=ScaleQuantumToChar(GetPixelGreen(hrz_image,p))/4;
329 *q++=ScaleQuantumToChar(GetPixelBlue(hrz_image,p))/4;
330 p+=GetPixelChannels(hrz_image);
cristy3ed852e2009-09-05 21:47:34 +0000331 }
332 count=WriteBlob(image,(size_t) (q-pixels),pixels);
333 if (count != (ssize_t) (q-pixels))
334 break;
335 status=SetImageProgress(image,SaveImageTag,y,hrz_image->rows);
336 if (status == MagickFalse)
337 break;
338 }
339 pixels=(unsigned char *) RelinquishMagickMemory(pixels);
340 hrz_image=DestroyImage(hrz_image);
341 (void) CloseBlob(image);
342 return(MagickTrue);
343}