root / ImageMagick / trunk / coders / rla.c

Revision 12035, 15.3 kB (checked in by cristy, 6 days ago)
Line 
1/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3%                                                                             %
4%                                                                             %
5%                                                                             %
6%                            RRRR   L       AAA                               %
7%                            R   R  L      A   A                              %
8%                            RRRR   L      AAAAA                              %
9%                            R R    L      A   A                              %
10%                            R  R   LLLLL  A   A                              %
11%                                                                             %
12%                                                                             %
13%                      Read Alias/Wavefront Image Format.                     %
14%                                                                             %
15%                              Software Design                                %
16%                                John Cristy                                  %
17%                                 July 1992                                   %
18%                                                                             %
19%                                                                             %
20%  Copyright 1999-2008 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 "magick/studio.h"
43#include "magick/property.h"
44#include "magick/blob.h"
45#include "magick/blob-private.h"
46#include "magick/exception.h"
47#include "magick/exception-private.h"
48#include "magick/image.h"
49#include "magick/image-private.h"
50#include "magick/list.h"
51#include "magick/magick.h"
52#include "magick/memory_.h"
53#include "magick/monitor.h"
54#include "magick/monitor-private.h"
55#include "magick/quantum-private.h"
56#include "magick/static.h"
57#include "magick/string_.h"
58#include "magick/module.h"
59
60/*
61%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
62%                                                                             %
63%                                                                             %
64%                                                                             %
65%   R e a d R L A I m a g e                                                   %
66%                                                                             %
67%                                                                             %
68%                                                                             %
69%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
70%
71%  ReadRLAImage() reads a run-length encoded Wavefront RLA image file
72%  and returns it.  It allocates the memory necessary for the new Image
73%  structure and returns a pointer to the new image.
74%
75%  Note:  This module was contributed by Lester Vecsey (master@internexus.net).
76%
77%  The format of the ReadRLAImage method is:
78%
79%      Image *ReadRLAImage(const ImageInfo *image_info,ExceptionInfo *exception)
80%
81%  A description of each parameter follows:
82%
83%    o image_info: the image info.
84%
85%    o exception: return any errors or warnings in this structure.
86%
87*/
88static Image *ReadRLAImage(const ImageInfo *image_info,ExceptionInfo *exception)
89{
90  typedef struct _WindowFrame
91  {
92    short
93      left,
94      right,
95      bottom,
96      top;
97  } WindowFrame;
98
99  typedef struct _RLAInfo
100  {
101    WindowFrame
102      window,
103      active_window;
104
105    short
106      frame,
107      storage_type,
108      number_channels,
109      number_matte_channels,
110      number_auxiliary_channels,
111      revision;
112
113    char
114      gamma[16],
115      red_primary[24],
116      green_primary[24],
117      blue_primary[24],
118      white_point[24];
119
120    long
121      job_number;
122
123    char
124      name[128],
125      description[128],
126      program[64],
127      machine[32],
128      user[32],
129      date[20],
130      aspect[24],
131      aspect_ratio[8],
132      chan[32];
133
134    short
135      field;
136
137    char
138      time[12],
139      filter[32];
140
141    short
142      bits_per_channel,
143      matte_type,
144      matte_bits,
145      auxiliary_type,
146      auxiliary_bits;
147
148    char
149      auxiliary[32],
150      space[36];
151
152    long
153      next;
154  } RLAInfo;
155
156  Image
157    *image;
158
159  int
160    channel,
161    length,
162    runlength;
163
164  long
165    y;
166
167  long
168    *scanlines;
169
170  MagickBooleanType
171    status;
172
173  MagickOffsetType
174    offset;
175
176  register long
177    i,
178    x;
179
180  register PixelPacket
181    *q;
182
183  ssize_t
184    count;
185
186  RLAInfo
187    rla_info;
188
189  unsigned char
190    byte;
191
192  /*
193    Open image file.
194  */
195  assert(image_info != (const ImageInfo *) NULL);
196  assert(image_info->signature == MagickSignature);
197  if (image_info->debug != MagickFalse)
198    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
199      image_info->filename);
200  assert(exception != (ExceptionInfo *) NULL);
201  assert(exception->signature == MagickSignature);
202  image=AcquireImage(image_info);
203  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
204  if (status == MagickFalse)
205    {
206      image=DestroyImageList(image);
207      return((Image *) NULL);
208    }
209  rla_info.window.left=(short) ReadBlobMSBShort(image);
210  rla_info.window.right=(short) ReadBlobMSBShort(image);
211  rla_info.window.bottom=(short) ReadBlobMSBShort(image);
212  rla_info.window.top=(short) ReadBlobMSBShort(image);
213  rla_info.active_window.left=(short) ReadBlobMSBShort(image);
214  rla_info.active_window.right=(short) ReadBlobMSBShort(image);
215  rla_info.active_window.bottom=(short) ReadBlobMSBShort(image);
216  rla_info.active_window.top=(short) ReadBlobMSBShort(image);
217  rla_info.frame=(short) ReadBlobMSBShort(image);
218  rla_info.storage_type=(short) ReadBlobMSBShort(image);
219  rla_info.number_channels=(short) ReadBlobMSBShort(image);
220  rla_info.number_matte_channels=(short) ReadBlobMSBShort(image);
221  if (rla_info.number_channels == 0)
222    rla_info.number_channels=3;
223  rla_info.number_channels+=rla_info.number_matte_channels;
224  rla_info.number_auxiliary_channels=(short) ReadBlobMSBShort(image);
225  rla_info.revision=(short) ReadBlobMSBShort(image);
226  count=ReadBlob(image,16,(unsigned char *) rla_info.gamma);
227  count=ReadBlob(image,24,(unsigned char *) rla_info.red_primary);
228  count=ReadBlob(image,24,(unsigned char *) rla_info.green_primary);
229  count=ReadBlob(image,24,(unsigned char *) rla_info.blue_primary);
230  count=ReadBlob(image,24,(unsigned char *) rla_info.white_point);
231  rla_info.job_number=(long) ReadBlobMSBLong(image);
232  count=ReadBlob(image,128,(unsigned char *) rla_info.name);
233  count=ReadBlob(image,128,(unsigned char *) rla_info.description);
234  count=ReadBlob(image,64,(unsigned char *) rla_info.program);
235  count=ReadBlob(image,32,(unsigned char *) rla_info.machine);
236  count=ReadBlob(image,32,(unsigned char *) rla_info.user);
237  count=ReadBlob(image,20,(unsigned char *) rla_info.date);
238  count=ReadBlob(image,24,(unsigned char *) rla_info.aspect);
239  count=ReadBlob(image,8,(unsigned char *) rla_info.aspect_ratio);
240  count=ReadBlob(image,32,(unsigned char *) rla_info.chan);
241  rla_info.field=(short) ReadBlobMSBShort(image);
242  count=ReadBlob(image,12,(unsigned char *) rla_info.time);
243  count=ReadBlob(image,32,(unsigned char *) rla_info.filter);
244  rla_info.bits_per_channel=(short) ReadBlobMSBShort(image);
245  rla_info.matte_type=(short) ReadBlobMSBShort(image);
246  rla_info.matte_bits=(short) ReadBlobMSBShort(image);
247  rla_info.auxiliary_type=(short) ReadBlobMSBShort(image);
248  rla_info.auxiliary_bits=(short) ReadBlobMSBShort(image);
249  count=ReadBlob(image,32,(unsigned char *) rla_info.auxiliary);
250  count=ReadBlob(image,36,(unsigned char *) rla_info.space);
251  if ((size_t) count != 36)
252    ThrowReaderException(CorruptImageError,"UnableToReadImageData");
253  rla_info.next=(long) ReadBlobMSBLong(image);
254  /*
255    Initialize image structure.
256  */
257  image->matte=rla_info.number_matte_channels != 0 ? MagickTrue : MagickFalse;
258  image->columns=1UL*rla_info.active_window.right-rla_info.active_window.left+1;
259  image->rows=1UL*rla_info.active_window.top-rla_info.active_window.bottom+1;
260  if (image_info->ping != MagickFalse)
261    {
262      (void) CloseBlob(image);
263      return(GetFirstImageInList(image));
264    }
265  if (SetImageExtent(image,0,0) == MagickFalse)
266    {
267      InheritException(exception,&image->exception);
268      return(DestroyImageList(image));
269    }
270  scanlines=(long *) AcquireQuantumMemory(image->rows,sizeof(*scanlines));
271  if (scanlines == (long *) NULL)
272    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
273  if (*rla_info.description != '\0')
274    (void) SetImageProperty(image,"comment",rla_info.description);
275  /*
276    Read offsets to each scanline data.
277  */
278  for (i=0; i < (long) image->rows; i++)
279    scanlines[i]=(long) ReadBlobMSBLong(image);
280  /*
281    Read image data.
282  */
283  x=0;
284  for (y=0; y < (long) image->rows; y++)
285  {
286    offset=SeekBlob(image,scanlines[image->rows-y-1],SEEK_SET);
287    if (offset < 0)
288      ThrowReaderException(CorruptImageError,"ImproperImageHeader");
289    for (channel=0; channel < (int) rla_info.number_channels; channel++)
290    {
291      length=(int) ReadBlobMSBShort(image);
292      while (length > 0)
293      {
294        byte=(unsigned char) ReadBlobByte(image);
295        runlength=byte;
296        if (byte > 127)
297          runlength=byte-256;
298        length--;
299        if (length == 0)
300          break;
301        if (runlength < 0)
302          {
303            while (runlength < 0)
304            {
305              q=GetImagePixels(image,(long) (x % image->columns),
306                (long) (y % image->rows),1,1);
307              if (q == (PixelPacket *) NULL)
308                break;
309              byte=(unsigned char) ReadBlobByte(image);
310              length--;
311              switch (channel)
312              {
313                case 0:
314                {
315                  q->red=ScaleCharToQuantum(byte);
316                  break;
317                }
318                case 1:
319                {
320                  q->green=ScaleCharToQuantum(byte);
321                  break;
322                }
323                case 2:
324                {
325                  q->blue=ScaleCharToQuantum(byte);
326                  break;
327                }
328                case 3:
329                default:
330                {
331                  q->opacity=(Quantum) (QuantumRange-ScaleCharToQuantum(byte));
332                  break;
333                }
334              }
335              if (SyncImagePixels(image) == MagickFalse)
336                break;
337              x++;
338              runlength++;
339            }
340            continue;
341          }
342        byte=(unsigned char) ReadBlobByte(image);
343        length--;
344        runlength++;
345        do
346        {
347          q=GetImagePixels(image,(long) (x % image->columns),
348            (long) (y % image->rows),1,1);
349          if (q == (PixelPacket *) NULL)
350            break;
351          switch (channel)
352          {
353            case 0:
354            {
355              q->red=ScaleCharToQuantum(byte);
356              break;
357            }
358            case 1:
359            {
360              q->green=ScaleCharToQuantum(byte);
361              break;
362            }
363            case 2:
364            {
365              q->blue=ScaleCharToQuantum(byte);
366              break;
367            }
368            case 3:
369            default:
370            {
371              q->opacity=(Quantum) (QuantumRange-ScaleCharToQuantum(byte));
372              break;
373            }
374          }
375          if (SyncImagePixels(image) == MagickFalse)
376            break;
377          x++;
378          runlength--;
379        }
380        while (runlength > 0);
381      }
382    }
383    status=SetImageProgress(image,LoadImageTag,y,image->rows);
384    if (status == MagickFalse)
385      break;
386  }
387  if (EOFBlob(image) != MagickFalse)
388    ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
389      image->filename);
390  (void) CloseBlob(image);
391  return(GetFirstImageInList(image));
392}
393
394/*
395%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
396%                                                                             %
397%                                                                             %
398%                                                                             %
399%   R e g i s t e r R L A I m a g e                                           %
400%                                                                             %
401%                                                                             %
402%                                                                             %
403%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
404%
405%  RegisterRLAImage() adds attributes for the RLA image format to
406%  the list of supported formats.  The attributes include the image format
407%  tag, a method to read and/or write the format, whether the format
408%  supports the saving of more than one frame to the same file or blob,
409%  whether the format supports native in-memory I/O, and a brief
410%  description of the format.
411%
412%  The format of the RegisterRLAImage method is:
413%
414%      unsigned long RegisterRLAImage(void)
415%
416*/
417ModuleExport unsigned long RegisterRLAImage(void)
418{
419  MagickInfo
420    *entry;
421
422  entry=SetMagickInfo("RLA");
423  entry->decoder=(DecodeImageHandler *) ReadRLAImage;
424  entry->adjoin=MagickFalse;
425  entry->description=ConstantString("Alias/Wavefront image");
426  entry->module=ConstantString("RLA");
427  (void) RegisterMagickInfo(entry);
428  return(MagickImageCoderSignature);
429}
430
431/*
432%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
433%                                                                             %
434%                                                                             %
435%                                                                             %
436%   U n r e g i s t e r R L A I m a g e                                       %
437%                                                                             %
438%                                                                             %
439%                                                                             %
440%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
441%
442%  UnregisterRLAImage() removes format registrations made by the
443%  RLA module from the list of supported formats.
444%
445%  The format of the UnregisterRLAImage method is:
446%
447%      UnregisterRLAImage(void)
448%
449*/
450ModuleExport void UnregisterRLAImage(void)
451{
452  (void) UnregisterMagickInfo("RLA");
453}
Note: See TracBrowser for help on using the browser.