root / ImageMagick / branches / ImageMagick-6.3.6 / coders / avi.c

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