root / ImageMagick / trunk / coders / avi.c

Revision 12035, 76.2 kB (checked in by cristy, 6 days ago)
Line 
1/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3%                                                                             %
4%                                                                             %
5%                                                                             %
6%                             AAA   V   V  IIIII                              %
7%                            A   A  V   V    I                                %
8%                            AAAAA  V   V    I                                %
9%                            A   A   V V     I                                %
10%                            A   A    V    IIIII                              %
11%                                                                             %
12%                                                                             %
13%            Read Microsoft Audio/Visual Interleaved Image Format.            %
14%                                                                             %
15%                              Software Design                                %
16%                                John Cristy                                  %
17%                                Nathan Brown                                 %
18%                                March  2004                                  %
19%                                                                             %
20%                                                                             %
21%  Copyright 1999-2008 ImageMagick Studio LLC, a non-profit organization      %
22%  dedicated to making software imaging solutions freely available.           %
23%                                                                             %
24%  You may not use this file except in compliance with the License.  You may  %
25%  obtain a copy of the License at                                            %
26%                                                                             %
27%    http://www.imagemagick.org/script/license.php                            %
28%                                                                             %
29%  Unless required by applicable law or agreed to in writing, software        %
30%  distributed under the License is distributed on an "AS IS" BASIS,          %
31%  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
32%  See the License for the specific language governing permissions and        %
33%  limitations under the License.                                             %
34%                                                                             %
35%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
36%
37%
38*/
39
40/*
41  Include declarations.
42*/
43#include <setjmp.h>
44#include "magick/studio.h"
45#include "magick/blob.h"
46#include "magick/blob-private.h"
47#include "magick/color-private.h"
48#include "magick/color-private.h"
49#include "magick/colorspace.h"
50#include "magick/constitute.h"
51#include "magick/delegate.h"
52#include "magick/exception.h"
53#include "magick/exception-private.h"
54#include "magick/geometry.h"
55#include "magick/image.h"
56#include "magick/image-private.h"
57#include "magick/list.h"
58#include "magick/log.h"
59#include "magick/magick.h"
60#include "magick/memory_.h"
61#include "magick/monitor.h"
62#include "magick/monitor-private.h"
63#include "magick/profile.h"
64#include "magick/property.h"
65#include "magick/quantum-private.h"
66#include "magick/resource_.h"
67#include "magick/static.h"
68#include "magick/string_.h"
69#include "magick/module.h"
70#include "magick/utility.h"
71
72#if defined(MAGICKCORE_JPEG_DELEGATE)
73#define JPEG_INTERNAL_OPTIONS
74#if defined(__MINGW32__)
75# define XMD_H 1  /* Avoid conflicting typedef for INT32 */
76#endif
77#undef HAVE_STDLIB_H
78#include "jpeglib.h"
79#include "jerror.h"
80#endif
81
82/*
83  Define declarations.
84*/
85#define ICC_MARKER  (JPEG_APP0+2)
86#define ICC_PROFILE  "ICC_PROFILE"
87#define IPTC_MARKER  (JPEG_APP0+13)
88#define XML_MARKER  (JPEG_APP0+1)
89#define MaxBufferExtent  8192
90
91/*
92  Typedef declarations.
93*/
94#if defined(MAGICKCORE_JPEG_DELEGATE)
95
96typedef struct _ErrorManager
97{
98  Image
99    *image;
100
101  jmp_buf
102    error_recovery;
103
104  boolean
105    verbose;
106} ErrorManager;
107
108typedef struct _SourceManager
109{
110  struct jpeg_source_mgr
111    manager;
112
113  Image
114    *image;
115
116  unsigned char
117    *source_data;
118
119  size_t
120    source_length;
121
122  JOCTET
123    *buffer;
124
125  boolean
126    start_of_blob;
127} SourceManager;
128#endif
129
130
131/*
132  Typedef declaractions.
133*/
134typedef struct _AVIInfo
135{
136  unsigned long
137    delay,
138    max_data_rate,
139    pad_granularity,
140    flags,
141    total_frames,
142    initial_frames,
143    number_streams,
144    buffer_size,
145    width,
146    height,
147    time_scale,
148    data_rate,
149    start_time,
150    data_length;
151} AVIInfo;
152
153typedef struct _BMPInfo
154{
155  unsigned long
156    size,
157    width,
158    height,
159    planes,
160    bits_per_pixel;
161
162  char
163    compression[5];
164
165  unsigned long
166    image_size,
167    x_pixels,
168    y_pixels,
169    number_colors,
170    important_colors;
171} BMPInfo;
172
173typedef struct _AVIStreamInfo
174{
175  char
176    data_type[5],
177    data_handler[5];
178
179  unsigned long
180    flags,
181    priority,
182    initial_frames,
183    time_scale,
184    data_rate,
185    start_time,
186    data_length,
187    buffer_size,
188    quality,
189    sample_size;
190} AVIStreamInfo;
191
192/*
193  MJPEG Information from Microsoft SDK
194*/
195#if defined(MAGICKCORE_JPEG_DELEGATE)
196#ifndef NOJPEGDIB
197
198/* New DIB Compression Defines */
199#define JPEG_DIB        mmioFOURCC('J','P','E','G')    /* Still image JPEG DIB biCompression */
200#define MJPG_DIB        mmioFOURCC('M','J','P','G')    /* Motion JPEG DIB biCompression     */
201
202/* JPEGColorSpaceID Definitions */
203#define JPEG_Y          1       /* Y only component of YCbCr */
204#define JPEG_YCbCr      2       /* YCbCr as define by CCIR 601 */
205#define JPEG_RGB        3       /* 3 component RGB */
206
207/* Structure definitions */
208
209#if defined(MAGICK_FUTURE)
210typedef struct tagJPEGINFOHEADER {
211    /* compression-specific fields */
212    /* these fields are defined for 'JPEG' and 'MJPG' */
213    DWORD       JPEGSize;
214    DWORD       JPEGProcess;
215
216    /* Process specific fields */
217    DWORD       JPEGColorSpaceID;
218    DWORD       JPEGBitsPerSample;
219    DWORD       JPEGHSubSampling;
220    DWORD       JPEGVSubSampling;
221} JPEGINFOHEADER;
222#endif
223
224/* Default DHT Segment */
225
226static const unsigned char MJPGDHTSeg[0x1A8] = {
227 /* JPEG DHT Segment for YCrCb omitted from MJPG data */
2280xFF,0xD8,0xFF,0xC4,0x01,0xA2,
2290x00,0x00,0x01,0x05,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
2300x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x01,0x00,0x03,0x01,0x01,0x01,0x01,
2310x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
2320x08,0x09,0x0A,0x0B,0x10,0x00,0x02,0x01,0x03,0x03,0x02,0x04,0x03,0x05,0x05,0x04,0x04,0x00,
2330x00,0x01,0x7D,0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,0x21,0x31,0x41,0x06,0x13,0x51,0x61,
2340x07,0x22,0x71,0x14,0x32,0x81,0x91,0xA1,0x08,0x23,0x42,0xB1,0xC1,0x15,0x52,0xD1,0xF0,0x24,
2350x33,0x62,0x72,0x82,0x09,0x0A,0x16,0x17,0x18,0x19,0x1A,0x25,0x26,0x27,0x28,0x29,0x2A,0x34,
2360x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x53,0x54,0x55,0x56,
2370x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x73,0x74,0x75,0x76,0x77,0x78,
2380x79,0x7A,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,
2390x9A,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,0xB9,
2400xBA,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,0xD9,
2410xDA,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,
2420xF8,0xF9,0xFA,0x11,0x00,0x02,0x01,0x02,0x04,0x04,0x03,0x04,0x07,0x05,0x04,0x04,0x00,0x01,
2430x02,0x77,0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71,
2440x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91,0xA1,0xB1,0xC1,0x09,0x23,0x33,0x52,0xF0,0x15,0x62,
2450x72,0xD1,0x0A,0x16,0x24,0x34,0xE1,0x25,0xF1,0x17,0x18,0x19,0x1A,0x26,0x27,0x28,0x29,0x2A,
2460x35,0x36,0x37,0x38,0x39,0x3A,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,0x53,0x54,0x55,0x56,
2470x57,0x58,0x59,0x5A,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6A,0x73,0x74,0x75,0x76,0x77,0x78,
2480x79,0x7A,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x92,0x93,0x94,0x95,0x96,0x97,0x98,
2490x99,0x9A,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,0xA8,0xA9,0xAA,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,0xB8,
2500xB9,0xBA,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,0xC8,0xC9,0xCA,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,0xD8,
2510xD9,0xDA,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,0xE8,0xE9,0xEA,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,0xF8,
2520xF9,0xFA,0xFF,0xD9
253};
254
255/* End DHT default */
256
257/* End JPEG */
258#endif
259#endif
260
261static inline size_t MagickMax(const size_t x,const size_t y)
262{
263  if (x > y)
264    return(x);
265  return(y);
266}
267
268static inline size_t MagickMin(const size_t x,const size_t y)
269{
270  if (x < y)
271    return(x);
272  return(y);
273}
274
275#if defined(MAGICKCORE_JPEG_DELEGATE)
276/*
277%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
278%                                                                             %
279%                                                                             %
280%                                                                             %
281%   R e a d J P E G I m a g e                                                 %
282%                                                                             %
283%                                                                             %
284%                                                                             %
285%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
286%
287%  ReadJPEGImage() reads a JPEG image file and returns it.  It allocates
288%  the memory necessary for the new Image structure and returns a pointer to
289%  the new image.
290%
291%  The format of the ReadJPEGImage method is:
292%
293%      Image *ReadJPEGImage(const ImageInfo *image_info,
294%        ExceptionInfo *exception)
295%
296%  A description of each parameter follows:
297%
298%    o image_info: the image info.
299%
300%    o exception: return any errors or warnings in this structure.
301%
302*/
303
304static MagickBooleanType EmitMessage(j_common_ptr jpeg_info,int level)
305{
306  char
307    message[JMSG_LENGTH_MAX];
308
309  ErrorManager
310    *error_manager;
311
312  Image
313    *image;
314
315  (jpeg_info->err->format_message)(jpeg_info,message);
316  error_manager=(ErrorManager *) jpeg_info->client_data;
317  image=error_manager->image;
318  if (error_manager->verbose != MagickFalse)
319    (void) fprintf(stdout,"%s\n",message);
320  if (level < 0)
321    {
322      if ((jpeg_info->err->num_warnings == 0) ||
323          (jpeg_info->err->trace_level >= 3))
324        ThrowBinaryException(CorruptImageError,(char *) message,
325          image->filename);
326      jpeg_info->err->num_warnings++;
327    }
328  else
329    if (jpeg_info->err->trace_level >= level)
330      ThrowBinaryException(CoderError,(char *) message,image->filename);
331  return(MagickTrue);
332}
333
334static boolean FillInputBuffer(j_decompress_ptr cinfo)
335{
336  SourceManager
337    *source;
338
339  source=(SourceManager *) cinfo->src;
340  if (source->image)
341    source->manager.bytes_in_buffer=(size_t) ReadBlob(source->image,
342      MagickMin(source->source_length,MaxBufferExtent),source->buffer);
343  else
344    {
345      source->manager.bytes_in_buffer=(size_t) MagickMin(source->source_length,
346        MaxBufferExtent);
347      (void) CopyMagickMemory(source->buffer,source->source_data,
348        source->manager.bytes_in_buffer);
349      source->source_data+=source->manager.bytes_in_buffer;
350    }
351  source->source_length-=source->manager.bytes_in_buffer;
352  if (source->manager.bytes_in_buffer == 0)
353    {
354      if (source->start_of_blob != 0)
355        ERREXIT(cinfo,JERR_INPUT_EMPTY);
356      WARNMS(cinfo,JWRN_JPEG_EOF);
357      source->buffer[0]=(JOCTET) 0xff;
358      source->buffer[1]=(JOCTET) JPEG_EOI;
359      source->manager.bytes_in_buffer=2;
360    }
361  source->manager.next_input_byte=source->buffer;
362  source->start_of_blob=FALSE;
363  return(TRUE);
364}
365
366static int GetCharacter(j_decompress_ptr jpeg_info)
367{
368  if (jpeg_info->src->bytes_in_buffer == 0)
369    (void) (*jpeg_info->src->fill_input_buffer)(jpeg_info);
370  jpeg_info->src->bytes_in_buffer--;
371  return((int) GETJOCTET(*jpeg_info->src->next_input_byte++));
372}
373
374static void InitializeSource(j_decompress_ptr cinfo)
375{
376  SourceManager
377    *source;
378
379  source=(SourceManager *) cinfo->src;
380  source->start_of_blob=TRUE;
381}
382
383static void JPEGErrorHandler(j_common_ptr jpeg_info)
384{
385  ErrorManager
386    *error_manager;
387
388  (void) EmitMessage(jpeg_info,0);
389  error_manager=(ErrorManager *) jpeg_info->client_data;
390  longjmp(error_manager->error_recovery,1);
391}
392
393static boolean ReadComment(j_decompress_ptr jpeg_info)
394{
395  char
396    *comment;
397
398  ErrorManager
399    *error_manager;
400
401  Image
402    *image;
403
404  register char
405    *p;
406
407  register long
408    i;
409
410  size_t
411    length;
412
413  /*
414    Determine length of comment.
415  */
416  error_manager=(ErrorManager *) jpeg_info->client_data;
417  image=error_manager->image;
418  length=(size_t) ((unsigned long) GetCharacter(jpeg_info) << 8);
419  length+=GetCharacter(jpeg_info);
420  length-=2;
421  if (length <= 0)
422    return(MagickTrue);
423  comment=(char *) NULL;
424  if (~length >= MaxTextExtent)
425    comment=(char *) AcquireQuantumMemory(length+MaxTextExtent,
426      sizeof(*comment));
427  if (comment == (char *) NULL)
428    ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
429      image->filename);
430  /*
431    Read comment.
432  */
433  i=(long) length-1;
434  for (p=comment; i-- >= 0; p++)
435    *p=(char) GetCharacter(jpeg_info);
436  *p='\0';
437  (void) SetImageProperty(image,"comment",comment);
438  comment=DestroyString(comment);
439  return(MagickTrue);
440}
441
442static boolean ReadICCProfile(j_decompress_ptr jpeg_info)
443{
444  char
445    magick[12];
446
447  ErrorManager
448    *error_manager;
449
450  Image
451    *image;
452
453  MagickBooleanType
454    status;
455
456  register long
457    i;
458
459  register unsigned char
460    *p;
461
462  size_t
463    length;
464
465  StringInfo
466    *icc_profile,
467    *profile;
468
469  /*
470    Read color profile.
471  */
472  length=(size_t) ((unsigned long) GetCharacter(jpeg_info) << 8);
473  length+=(size_t) GetCharacter(jpeg_info);
474  if (length < 2)
475    return(MagickFalse);
476  length-=2;
477  if (length <= 14)
478    {
479      while (length-- != 0)
480        (void) GetCharacter(jpeg_info);
481      return(MagickTrue);
482    }
483  for (i=0; i < 12; i++)
484    magick[i]=(char) GetCharacter(jpeg_info);
485  if (LocaleCompare(magick,ICC_PROFILE) != 0)
486    {
487      /*
488        Not a ICC profile, return.
489      */
490      for (i=0; i < (long) (length-12); i++)
491        (void) GetCharacter(jpeg_info);
492      return(MagickTrue);
493    }
494  (void) GetCharacter(jpeg_info);  /* id */
495  (void) GetCharacter(jpeg_info);  /* markers */
496  if (length < 14)
497    return(MagickFalse);
498  length-=14;
499  error_manager=(ErrorManager *) jpeg_info->client_data;
500  image=error_manager->image;
501  profile=AcquireStringInfo(length);
502  if (profile == (StringInfo *) NULL)
503    ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
504      image->filename);
505  p=GetStringInfoDatum(profile);
506  for (i=(long) GetStringInfoLength(profile)-1; i >= 0; i--)
507    *p++=(unsigned char) GetCharacter(jpeg_info);
508  icc_profile=(StringInfo *) GetImageProfile(image,"icc");
509  if (icc_profile != (StringInfo *) NULL)
510    ConcatenateStringInfo(icc_profile,profile);
511  else
512    {
513      status=SetImageProfile(image,"icc",profile);
514      if (status == MagickFalse)
515        ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
516          image->filename);
517    }
518  if (image->debug != MagickFalse)
519    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
520      "Profile: ICC, %lu bytes",(unsigned long) length);
521  return(MagickTrue);
522}
523
524static boolean ReadIPTCProfile(j_decompress_ptr jpeg_info)
525{
526  char
527    magick[MaxTextExtent];
528
529  ErrorManager
530    *error_manager;
531
532  Image
533    *image;
534
535  MagickBooleanType
536    status;
537
538  register long
539    i;
540
541  register unsigned char
542    *p;
543
544  size_t
545    length,
546    tag_length;
547
548  StringInfo
549    *iptc_profile,
550    *profile;
551
552#if defined(GET_ONLY_IPTC_DATA)
553  unsigned char
554    tag[MaxTextExtent];
555#endif
556
557  /*
558    Determine length of binary data stored here.
559  */
560  length=(size_t) ((unsigned long) GetCharacter(jpeg_info) << 8);
561  length+=(size_t) GetCharacter(jpeg_info);
562  if (length <= 2)
563    return(MagickTrue);
564  length-=2;
565  tag_length=0;
566#if defined(GET_ONLY_IPTC_DATA)
567  *tag='\0';
568#endif
569  error_manager=(ErrorManager *) jpeg_info->client_data;
570  image=error_manager->image;
571  iptc_profile=(StringInfo *) GetImageProfile(image,"iptc");
572  if (iptc_profile == (StringInfo *) NULL)
573    {
574#if defined(GET_ONLY_IPTC_DATA)
575      /*
576        Find the beginning of the iptc portion of the binary data.
577      */
578      for (*tag='\0'; length > 0; )
579      {
580        *tag=GetCharacter(jpeg_info);
581        *(tag+1)=GetCharacter(jpeg_info);
582        if (length < 2)
583          return(MagickFalse);
584        length-=2;
585        if ((*tag == 0x1c) && (*(tag+1) == 0x02))
586          break;
587      }
588      tag_length=2;
589#else
590      /*
591        Validate that this was written as a Photoshop resource format slug.
592      */
593      for (i=0; i < 10; i++)
594        magick[i]=(char) GetCharacter(jpeg_info);
595      magick[10]='\0';
596      if (length <= 10)
597        return(MagickTrue);
598      length-=10;
599      if (LocaleCompare(magick,"Photoshop ") != 0)
600        {
601          /*
602            Not a ICC profile, return.
603          */
604          for (i=0; i < (long) length; i++)
605            (void) GetCharacter(jpeg_info);
606          return(MagickTrue);
607        }
608      /*
609        Remove the version number.
610      */
611      for (i=0; i < 4; i++)
612        (void) GetCharacter(jpeg_info);
613      if (length <= 4)
614        return(MagickTrue);
615      length-=4;
616      tag_length=0;
617#endif
618    }
619  if (length == 0)
620    return(MagickTrue);
621  profile=AcquireStringInfo(length);
622  if (profile == (StringInfo *) NULL)
623    ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
624      image->filename);
625  p=GetStringInfoDatum(profile);
626  for (i=(long) GetStringInfoLength(profile)-1; i >= 0; i--)
627    *p++=(unsigned char) GetCharacter(jpeg_info);
628  iptc_profile=(StringInfo *) GetImageProfile(image,"iptc");
629  if (iptc_profile != (StringInfo *) NULL)
630    ConcatenateStringInfo(iptc_profile,profile);
631  else
632    {
633      status=SetImageProfile(image,"iptc",profile);
634      if (status == MagickFalse)
635        ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
636          image->filename);
637    }
638  if (image->debug != MagickFalse)
639    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
640      "Profile: iptc, %lu bytes",(unsigned long) length);
641  return(MagickTrue);
642}
643
644static boolean ReadProfile(j_decompress_ptr jpeg_info)
645{
646  char
647    name[MaxTextExtent];
648
649  ErrorManager
650    *error_manager;
651
652  Image
653    *image;
654
655  int
656    marker;
657
658  MagickBooleanType
659    status;
660
661  register long
662    i;
663
664  register unsigned char
665    *p;
666
667  size_t
668    length;
669
670  StringInfo
671    *profile;
672
673  /*
674    Read generic profile.
675  */
676  length=(size_t) ((unsigned long) GetCharacter(jpeg_info) << 8);
677  length+=(size_t) GetCharacter(jpeg_info);
678  if (length <= 2)
679    return(MagickTrue);
680  length-=2;
681  marker=jpeg_info->unread_marker-JPEG_APP0;
682  error_manager=(ErrorManager *) jpeg_info->client_data;
683  image=error_manager->image;
684  (void) FormatMagickString(name,MaxTextExtent,"APP%d",marker);
685  profile=AcquireStringInfo(length);
686  if (profile == (StringInfo *) NULL)
687    ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
688      image->filename);
689  p=GetStringInfoDatum(profile);
690  for (i=(long) GetStringInfoLength(profile)-1; i >= 0; i--)
691    *p++=(unsigned char) GetCharacter(jpeg_info);
692  if (marker == 1)
693    {
694      p=GetStringInfoDatum(profile);
695      if ((length > 4) && (LocaleNCompare((char *) p,"exif",4) == 0))
696        (void) CopyMagickString(name,"iptc",MaxTextExtent);
697      if ((length > 5) && (LocaleNCompare((char *) p,"http:",5) == 0))
698        (void) CopyMagickString(name,"xmp",MaxTextExtent);
699    }
700  status=SetImageProfile(image,name,profile);
701  if (status == MagickFalse)
702    ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
703      image->filename);
704  if (image->debug != MagickFalse)
705    (void) LogMagickEvent(CoderEvent,GetMagickModule(),
706      "Profile: %s, %lu bytes",name,(unsigned long) length);
707  return(MagickTrue);
708}
709
710static void SkipInputData(j_decompress_ptr cinfo,long number_bytes)
711{
712  SourceManager
713    *source;
714
715  if (number_bytes <= 0)
716    return;
717  source=(SourceManager *) cinfo->src;
718  while (number_bytes > (long) source->manager.bytes_in_buffer)
719  {
720    number_bytes-=(long) source->manager.bytes_in_buffer;
721    (void) FillInputBuffer(cinfo);
722  }
723  source->manager.next_input_byte+=(size_t) number_bytes;
724  source->manager.bytes_in_buffer-=(size_t) number_bytes;
725}
726
727static void TerminateSource(j_decompress_ptr cinfo)
728{
729  cinfo=cinfo;
730}
731
732static void JPEGSourceManagerMemory(j_decompress_ptr cinfo,unsigned char *source_data, unsigned long source_length)
733{
734  SourceManager
735    *source;
736
737  cinfo->src=(struct jpeg_source_mgr *) (*cinfo->mem->alloc_small)
738    ((j_common_ptr) cinfo,JPOOL_IMAGE,sizeof(SourceManager));
739  source=(SourceManager *) cinfo->src;
740  source->buffer=(JOCTET *) (*cinfo->mem->alloc_small)
741    ((j_common_ptr) cinfo,JPOOL_IMAGE,MaxBufferExtent*sizeof(JOCTET));
742  source=(SourceManager *) cinfo->src;
743  source->manager.init_source=InitializeSource;
744  source->manager.fill_input_buffer=FillInputBuffer;
745  source->manager.skip_input_data=SkipInputData;
746  source->manager.resync_to_restart=jpeg_resync_to_restart;
747  source->manager.term_source=TerminateSource;
748  source->manager.bytes_in_buffer=0;
749  source->manager.next_input_byte=NULL;
750  source->image=0;
751  source->source_data=source_data;
752  source->source_length=source_length;
753}
754
755static void JPEGSourceManagerBLOB(j_decompress_ptr cinfo,Image *image, unsigned long source_length)
756{
757  SourceManager
758    *source;
759
760  cinfo->src=(struct jpeg_source_mgr *) (*cinfo->mem->alloc_small)
761    ((j_common_ptr) cinfo,JPOOL_IMAGE,sizeof(SourceManager));
762  source=(SourceManager *) cinfo->src;
763  source->buffer=(JOCTET *) (*cinfo->mem->alloc_small)
764    ((j_common_ptr) cinfo,JPOOL_IMAGE,MaxBufferExtent*sizeof(JOCTET));
765  source=(SourceManager *) cinfo->src;
766  source->manager.init_source=InitializeSource;
767  source->manager.fill_input_buffer=FillInputBuffer;
768  source->manager.skip_input_data=SkipInputData;
769  source->manager.resync_to_restart=jpeg_resync_to_restart;
770  source->manager.term_source=TerminateSource;
771  source->manager.bytes_in_buffer=0;
772  source->manager.next_input_byte=NULL;
773  source->image=image;
774  source->source_data=0;
775  source->source_length=source_length;
776}
777#endif
778
779/*
780%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
781%                                                                             %
782%                                                                             %
783%                                                                             %
784%   D e c o d e I m a g e                                                     %
785%                                                                             %
786%                                                                             %
787%                                                                             %
788%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
789%
790%  DecodeImage unpacks the packed image pixels into runlength-encoded
791%  pixel packets.
792%
793%  The format of the DecodeImage method is:
794%
795%      MagickBooleanType DecodeImage(Image *image,
796%        const MagickBooleanType compression,unsigned char *pixels)
797%
798%  A description of each parameter follows:
799%
800%    o image: the address of a structure of type Image.
801%
802%    o compression:  A value of 1 means the compressed pixels are runlength
803%      encoded for a 256-color bitmap.  A value of 2 means a 16-color bitmap.
804%
805%    o pixels:  The address of a byte (8 bits) array of pixel data created by
806%      the decoding process.
807%
808*/
809static MagickBooleanType DecodeImage(Image *image,
810  const MagickBooleanType compression,unsigned char *pixels)
811{
812#if !defined(__WINDOWS__) || defined(__MINGW32__)
813#define BI_RLE8  1
814#endif
815
816  long
817    y;
818
819  register long
820    i,
821    x;
822
823  register unsigned char
824    *p,
825    *q;
826
827  ssize_t
828    count;
829
830  unsigned char
831    byte;
832
833  assert(image != (Image *) NULL);
834  assert(image->signature == MagickSignature);
835  if (image->debug != MagickFalse)
836    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
837  assert(pixels != (unsigned char *) NULL);
838  (void) ResetMagickMemory(pixels,0,(size_t) image->columns*image->rows*
839    sizeof(*pixels));
840  byte=0;
841  x=0;
842  p=pixels;
843  q=pixels+(size_t) image->columns*image->rows;
844  for (y=0; y < (long) image->rows; )
845  {
846    if ((p < pixels) || (p >= q))
847      break;
848    count=(ssize_t) ReadBlobByte(image);
849    if ((int) count == EOF)
850      break;
851    if (count != 0)
852      {
853        count=(ssize_t) MagickMin((size_t) count,(size_t) (q-p));
854        /*
855          Encoded mode.
856        */
857        byte=(unsigned char) ReadBlobByte(image);
858        if (compression == BI_RLE8)
859          {
860            for (i=0; i < (long) count; i++)
861              *p++=(unsigned char) byte;
862          }
863        else
864          {
865            for (i=0; i < (long) count; i++)
866              *p++=(unsigned char)
867                ((i & 0x01) != 0 ? (byte & 0x0f) : ((byte >> 4) & 0x0f));
868          }
869        x+=count;
870      }
871    else
872      {
873        /*
874          Escape mode.
875        */
876        count=(ssize_t) ReadBlobByte(image);
877        if (count == 0x01)
878          return(MagickTrue);
879        switch (count)
880        {
881          case 0x00:
882          {
883            /*
884              End of line.
885            */
886            x=0;
887            y++;
888            p=pixels+y*image->columns;
889            break;
890          }
891          case 0x02:
892          {
893            /*
894              Delta mode.
895            */
896            x+=ReadBlobByte(image);
897            y+=ReadBlobByte(image);
898            p=pixels+y*image->columns+x;
899            break;
900          }
901          default:
902          {
903            /*
904              Absolute mode.
905            */
906            count=(ssize_t) MagickMin((size_t) count,(size_t) (q-p));
907            if (compression == BI_RLE8)
908              for (i=0; i < (long) count; i++)
909                *p++=(unsigned char) ReadBlobByte(image);
910            else
911              for (i=0; i < (long) count; i++)
912              {
913                if ((i & 0x01) == 0)
914                  byte=(unsigned char) ReadBlobByte(image);
915                *p++=(unsigned char)
916                  ((i & 0x01) != 0 ? (byte & 0x0f) : ((byte >> 4) & 0x0f));
917              }
918            x+=count;
919            /*
920              Read pad byte.
921            */
922            if (compression == BI_RLE8)
923              {
924                if ((count & 0x01) != 0)
925                  if (ReadBlobByte(image) == EOF)
926                    ThrowBinaryException(CorruptImageError,
927                      "UnexpectedEndOfFile",image->filename);
928              }
929            else
930              if (((count & 0x03) == 1) || ((count & 0x03) == 2))
931                if (ReadBlobByte(image) == EOF)
932                  ThrowBinaryException(CorruptImageError,
933                    "UnexpectedEndOfFile",image->filename);
934            break;
935          }
936        }
937      }
938    if (SetImageProgress(image,LoadImageTag,y,image->rows) == MagickFalse)
939      break;
940  }
941  if (ReadBlobByte(image) == EOF)
942    ThrowBinaryException(CorruptImageError,"UnexpectedEndOfFile",
943      image->filename);
944  if (ReadBlobByte(image) == EOF)
945    ThrowBinaryException(CorruptImageError,"UnexpectedEndOfFile",
946      image->filename);
947  return(MagickTrue);
948}
949
950/*
951%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
952%                                                                             %
953%                                                                             %
954%                                                                             %
955%   I s A V I                                                                 %
956%                                                                             %
957%                                                                             %
958%                                                                             %
959%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
960%
961%  IsAVI() returns MagickTrue if the image format type, identified by the
962%  magick string, is Audio/Video Interleaved file format.
963%
964%  The format of the IsAVI method is:
965%
966%      unsigned long IsAVI(const unsigned char *magick,const size_t length)
967%
968%  A description of each parameter follows:
969%
970%    o magick: This string is generally the first few bytes of an image file
971%      or blob.
972%
973%    o length: Specifies the length of the magick string.
974%
975*/
976static MagickBooleanType IsAVI(const unsigned char *magick,const size_t length)
977{
978  if (length < 4)
979    return(MagickFalse);
980  if (memcmp(magick,"RIFF",4) == 0)
981    return(MagickTrue);
982  return(MagickFalse);
983}
984
985/*
986%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
987%                                                                             %
988%                                                                             %
989%                                                                             %
990%   R e a d A V I I m a g e                                                   %
991%                                                                             %
992%                                                                             %
993%                                                                             %
994%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
995%
996%  ReadAVIImage() reads an Audio Video Interleave image file and returns
997%  it.  It allocates the memory necessary for the new Image structure and
998%  returns a pointer to the new image.
999%
1000%  The format of the ReadAVIImage method is:
1001%
1002%      Image *ReadAVIImage(const ImageInfo *image_info,ExceptionInfo *exception)
1003%
1004%  A description of each parameter follows:
1005%
1006%    o image:  Method ReadAVIImage returns a pointer to the image after
1007%      reading. A null image is returned if there is a memory shortage or if
1008%      the image cannot be read.
1009%
1010%    o image_info: the image info.
1011%
1012%    o exception: return any errors or warnings in this structure.
1013%
1014*/
1015
1016static Image *DecodeAVIImage(const ImageInfo *image_info,
1017  ExceptionInfo *exception)
1018{
1019  Image
1020    *image,
1021    *images;
1022
1023  ImageInfo
1024    *read_info;
1025
1026  MagickBooleanType
1027    status;
1028
1029  register long
1030    i;
1031
1032  /*
1033    Open image file.
1034  */
1035  assert(image_info != (const ImageInfo *) NULL);
1036  assert(image_info->signature == MagickSignature);
1037