Home | History | Annotate | Download | only in coders
      1 /*
      2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
      3 %                                                                             %
      4 %                                                                             %
      5 %                                                                             %
      6 %                            DDDD   PPPP   X   X                              %
      7 %                            D   D  P   P   X X                               %
      8 %                            D   D  PPPP    XXX                               %
      9 %                            D   D  P       X X                               %
     10 %                            DDDD   P      X   X                              %
     11 %                                                                             %
     12 %                                                                             %
     13 %                     Read/Write SMTPE DPX Image Format                       %
     14 %                                                                             %
     15 %                              Software Design                                %
     16 %                                   Cristy                                    %
     17 %                                March 2001                                   %
     18 %                                                                             %
     19 %                                                                             %
     20 %  Copyright 1999-2019 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 %    https://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 /*
     41   Include declarations.
     42 */
     43 #include "MagickCore/studio.h"
     44 #include "MagickCore/attribute.h"
     45 #include "MagickCore/artifact.h"
     46 #include "MagickCore/blob.h"
     47 #include "MagickCore/blob-private.h"
     48 #include "MagickCore/cache.h"
     49 #include "MagickCore/colorspace.h"
     50 #include "MagickCore/exception.h"
     51 #include "MagickCore/exception-private.h"
     52 #include "MagickCore/geometry.h"
     53 #include "MagickCore/image.h"
     54 #include "MagickCore/image-private.h"
     55 #include "MagickCore/list.h"
     56 #include "MagickCore/magick.h"
     57 #include "MagickCore/memory_.h"
     58 #include "MagickCore/module.h"
     59 #include "MagickCore/monitor.h"
     60 #include "MagickCore/monitor-private.h"
     61 #include "MagickCore/option.h"
     62 #include "MagickCore/pixel-accessor.h"
     63 #include "MagickCore/profile.h"
     64 #include "MagickCore/property.h"
     65 #include "MagickCore/quantum-private.h"
     66 #include "MagickCore/static.h"
     67 #include "MagickCore/string_.h"
     68 #include "MagickCore/string-private.h"
     69 
     70 /*
     72   Define declaration.
     73 */
     74 #define MaxNumberImageElements  8
     75 
     76 /*
     78   Typedef declaration.
     79 */
     80 typedef enum
     81 {
     82   UserDefinedColorimetric = 0,
     83   PrintingDensityColorimetric = 1,
     84   LinearColorimetric = 2,
     85   LogarithmicColorimetric = 3,
     86   UnspecifiedVideoColorimetric = 4,
     87   SMTPE_274MColorimetric = 5,
     88   ITU_R709Colorimetric = 6,
     89   ITU_R601_625LColorimetric = 7,
     90   ITU_R601_525LColorimetric = 8,
     91   NTSCCompositeVideoColorimetric = 9,
     92   PALCompositeVideoColorimetric = 10,
     93   ZDepthLinearColorimetric = 11,
     94   DepthHomogeneousColorimetric = 12
     95 } DPXColorimetric;
     96 
     97 typedef enum
     98 {
     99   UndefinedComponentType = 0,
    100   RedComponentType = 1,
    101   GreenComponentType = 2,
    102   BlueComponentType = 3,
    103   AlphaComponentType = 4,
    104   LumaComponentType = 6,
    105   ColorDifferenceCbCrComponentType = 7,
    106   DepthComponentType = 8,
    107   CompositeVideoComponentType = 9,
    108   RGBComponentType = 50,
    109   RGBAComponentType = 51,
    110   ABGRComponentType = 52,
    111   CbYCrY422ComponentType = 100,
    112   CbYACrYA4224ComponentType = 101,
    113   CbYCr444ComponentType = 102,
    114   CbYCrA4444ComponentType = 103,
    115   UserDef2ElementComponentType = 150,
    116   UserDef3ElementComponentType = 151,
    117   UserDef4ElementComponentType = 152,
    118   UserDef5ElementComponentType = 153,
    119   UserDef6ElementComponentType = 154,
    120   UserDef7ElementComponentType = 155,
    121   UserDef8ElementComponentType = 156
    122 } DPXComponentType;
    123 
    124 typedef enum
    125 {
    126   TransferCharacteristicUserDefined = 0,
    127   TransferCharacteristicPrintingDensity = 1,
    128   TransferCharacteristicLinear = 2,
    129   TransferCharacteristicLogarithmic = 3,
    130   TransferCharacteristicUnspecifiedVideo = 4,
    131   TransferCharacteristicSMTPE274M = 5,     /* 1920x1080 TV */
    132   TransferCharacteristicITU_R709 = 6,      /* ITU R709 */
    133   TransferCharacteristicITU_R601_625L = 7, /* 625 Line */
    134   TransferCharacteristicITU_R601_525L = 8, /* 525 Line */
    135   TransferCharacteristicNTSCCompositeVideo = 9,
    136   TransferCharacteristicPALCompositeVideo = 10,
    137   TransferCharacteristicZDepthLinear = 11,
    138   TransferCharacteristicZDepthHomogeneous = 12
    139 } DPXTransferCharacteristic;
    140 
    141 typedef struct _DPXFileInfo
    142 {
    143   unsigned int
    144     magic,
    145     image_offset;
    146 
    147   char
    148     version[8];
    149 
    150   unsigned int
    151     file_size,
    152     ditto_key,
    153     generic_size,
    154     industry_size,
    155     user_size;
    156 
    157   char
    158     filename[100],
    159     timestamp[24],
    160     creator[100],
    161     project[200],
    162     copyright[200];
    163 
    164   unsigned int
    165     encrypt_key;
    166 
    167   char
    168     reserve[104];
    169 } DPXFileInfo;
    170 
    171 typedef struct _DPXFilmInfo
    172 {
    173   char
    174     id[2],
    175     type[2],
    176     offset[2],
    177     prefix[6],
    178     count[4],
    179     format[32];
    180 
    181   unsigned int
    182     frame_position,
    183     sequence_extent,
    184     held_count;
    185 
    186   float
    187     frame_rate,
    188     shutter_angle;
    189 
    190   char
    191     frame_id[32],
    192     slate[100],
    193     reserve[56];
    194 } DPXFilmInfo;
    195 
    196 typedef struct _DPXImageElement
    197 {
    198   unsigned int
    199     data_sign,
    200     low_data;
    201 
    202   float
    203     low_quantity;
    204 
    205   unsigned int
    206     high_data;
    207 
    208   float
    209     high_quantity;
    210 
    211   unsigned char
    212     descriptor,
    213     transfer_characteristic,
    214     colorimetric,
    215     bit_size;
    216 
    217   unsigned short
    218     packing,
    219     encoding;
    220 
    221   unsigned int
    222     data_offset,
    223     end_of_line_padding,
    224     end_of_image_padding;
    225 
    226   unsigned char
    227     description[32];
    228 } DPXImageElement;
    229 
    230 typedef struct _DPXImageInfo
    231 {
    232   unsigned short
    233     orientation,
    234     number_elements;
    235 
    236   unsigned int
    237     pixels_per_line,
    238     lines_per_element;
    239 
    240   DPXImageElement
    241     image_element[MaxNumberImageElements];
    242 
    243   unsigned char
    244     reserve[52];
    245 } DPXImageInfo;
    246 
    247 typedef struct _DPXOrientationInfo
    248 {
    249   unsigned int
    250     x_offset,
    251     y_offset;
    252 
    253   float
    254     x_center,
    255     y_center;
    256 
    257   unsigned int
    258     x_size,
    259     y_size;
    260 
    261   char
    262     filename[100],
    263     timestamp[24],
    264     device[32],
    265     serial[32];
    266 
    267   unsigned short
    268     border[4];
    269 
    270   unsigned int
    271     aspect_ratio[2];
    272 
    273   unsigned char
    274     reserve[28];
    275 } DPXOrientationInfo;
    276 
    277 typedef struct _DPXTelevisionInfo
    278 {
    279   unsigned int
    280     time_code,
    281     user_bits;
    282 
    283   unsigned char
    284     interlace,
    285     field_number,
    286     video_signal,
    287     padding;
    288 
    289   float
    290     horizontal_sample_rate,
    291     vertical_sample_rate,
    292     frame_rate,
    293     time_offset,
    294     gamma,
    295     black_level,
    296     black_gain,
    297     break_point,
    298     white_level,
    299     integration_times;
    300 
    301   char
    302     reserve[76];
    303 } DPXTelevisionInfo;
    304 
    305 typedef struct _DPXUserInfo
    306 {
    307   char
    308     id[32];
    309 } DPXUserInfo;
    310 
    311 typedef struct DPXInfo
    312 {
    313   DPXFileInfo
    314     file;
    315 
    316   DPXImageInfo
    317     image;
    318 
    319   DPXOrientationInfo
    320     orientation;
    321 
    322   DPXFilmInfo
    323     film;
    324 
    325   DPXTelevisionInfo
    326     television;
    327 
    328   DPXUserInfo
    329     user;
    330 } DPXInfo;
    331 
    332 /*
    334   Forward declaractions.
    335 */
    336 static MagickBooleanType
    337   WriteDPXImage(const ImageInfo *,Image *,ExceptionInfo *);
    338 
    339 /*
    341 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    342 %                                                                             %
    343 %                                                                             %
    344 %                                                                             %
    345 %   I s D P X                                                                 %
    346 %                                                                             %
    347 %                                                                             %
    348 %                                                                             %
    349 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    350 %
    351 %  IsDPX() returns MagickTrue if the image format type, identified by the
    352 %  magick string, is DPX.
    353 %
    354 %  The format of the IsDPX method is:
    355 %
    356 %      MagickBooleanType IsDPX(const unsigned char *magick,const size_t extent)
    357 %
    358 %  A description of each parameter follows:
    359 %
    360 %    o magick: compare image format pattern against these bytes.
    361 %
    362 %    o extent: Specifies the extent of the magick string.
    363 %
    364 */
    365 static MagickBooleanType IsDPX(const unsigned char *magick,const size_t extent)
    366 {
    367   if (extent < 4)
    368     return(MagickFalse);
    369   if (memcmp(magick,"SDPX",4) == 0)
    370     return(MagickTrue);
    371   if (memcmp(magick,"XPDS",4) == 0)
    372     return(MagickTrue);
    373   return(MagickFalse);
    374 }
    375 
    376 /*
    378 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    379 %                                                                             %
    380 %                                                                             %
    381 %                                                                             %
    382 %   R e a d D P X I m a g e                                                   %
    383 %                                                                             %
    384 %                                                                             %
    385 %                                                                             %
    386 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    387 %
    388 %  ReadDPXImage() reads an DPX X image file and returns it.  It
    389 %  allocates the memory necessary for the new Image structure and returns a
    390 %  pointer to the new image.
    391 %
    392 %  The format of the ReadDPXImage method is:
    393 %
    394 %      Image *ReadDPXImage(const ImageInfo *image_info,ExceptionInfo *exception)
    395 %
    396 %  A description of each parameter follows:
    397 %
    398 %    o image_info: the image info.
    399 %
    400 %    o exception: return any errors or warnings in this structure.
    401 %
    402 */
    403 
    404 static size_t GetBytesPerRow(const size_t columns,
    405   const size_t samples_per_pixel,const size_t bits_per_pixel,
    406   const MagickBooleanType pad)
    407 {
    408   size_t
    409     bytes_per_row;
    410 
    411   switch (bits_per_pixel)
    412   {
    413     case 1:
    414     {
    415       bytes_per_row=4*(((size_t) samples_per_pixel*columns*bits_per_pixel+31)/
    416         32);
    417       break;
    418     }
    419     case 8:
    420     default:
    421     {
    422       bytes_per_row=4*(((size_t) samples_per_pixel*columns*bits_per_pixel+31)/
    423         32);
    424       break;
    425     }
    426     case 10:
    427     {
    428       if (pad == MagickFalse)
    429         {
    430           bytes_per_row=4*(((size_t) samples_per_pixel*columns*bits_per_pixel+
    431             31)/32);
    432           break;
    433         }
    434       bytes_per_row=4*(((size_t) (32*((samples_per_pixel*columns+2)/3))+31)/32);
    435       break;
    436     }
    437     case 12:
    438     {
    439       if (pad == MagickFalse)
    440         {
    441           bytes_per_row=4*(((size_t) samples_per_pixel*columns*bits_per_pixel+
    442             31)/32);
    443           break;
    444         }
    445       bytes_per_row=2*(((size_t) (16*samples_per_pixel*columns)+15)/16);
    446       break;
    447     }
    448     case 16:
    449     {
    450       if (pad == MagickFalse)
    451         {
    452           bytes_per_row=2*(((size_t) samples_per_pixel*columns*bits_per_pixel+
    453             15)/16);
    454           break;
    455         }
    456       bytes_per_row=4*(((size_t) samples_per_pixel*columns*bits_per_pixel+31)/
    457         32);
    458       break;
    459     }
    460     case 32:
    461     {
    462       bytes_per_row=4*(((size_t) samples_per_pixel*columns*bits_per_pixel+31)/
    463         32);
    464       break;
    465     }
    466     case 64:
    467     {
    468       bytes_per_row=8*(((size_t) samples_per_pixel*columns*bits_per_pixel+63)/
    469         64);
    470       break;
    471     }
    472   }
    473   return(bytes_per_row);
    474 }
    475 
    476 static const char *GetImageTransferCharacteristic(
    477   const DPXTransferCharacteristic characteristic)
    478 {
    479   const char
    480     *transfer;
    481 
    482   /*
    483     Get the element transfer characteristic.
    484   */
    485   switch(characteristic)
    486   {
    487     case TransferCharacteristicUserDefined:
    488     {
    489       transfer="UserDefined";
    490       break;
    491     }
    492     case TransferCharacteristicPrintingDensity:
    493     {
    494       transfer="PrintingDensity";
    495       break;
    496     }
    497     case TransferCharacteristicLinear:
    498     {
    499       transfer="Linear";
    500       break;
    501     }
    502     case TransferCharacteristicLogarithmic:
    503     {
    504       transfer="Logarithmic";
    505       break;
    506     }
    507     case TransferCharacteristicUnspecifiedVideo:
    508     {
    509       transfer="UnspecifiedVideo";
    510       break;
    511     }
    512     case TransferCharacteristicSMTPE274M:
    513     {
    514       transfer="SMTPE274M";
    515       break;
    516     }
    517     case TransferCharacteristicITU_R709:
    518     {
    519       transfer="ITU-R709";
    520       break;
    521     }
    522     case TransferCharacteristicITU_R601_625L:
    523     {
    524       transfer="ITU-R601-625L";
    525       break;
    526     }
    527     case TransferCharacteristicITU_R601_525L:
    528     {
    529       transfer="ITU-R601-525L";
    530       break;
    531     }
    532     case TransferCharacteristicNTSCCompositeVideo:
    533     {
    534       transfer="NTSCCompositeVideo";
    535       break;
    536     }
    537     case TransferCharacteristicPALCompositeVideo:
    538     {
    539       transfer="PALCompositeVideo";
    540       break;
    541     }
    542     case TransferCharacteristicZDepthLinear:
    543     {
    544       transfer="ZDepthLinear";
    545       break;
    546     }
    547     case TransferCharacteristicZDepthHomogeneous:
    548     {
    549       transfer="ZDepthHomogeneous";
    550       break;
    551     }
    552     default:
    553       transfer="Reserved";
    554   }
    555   return(transfer);
    556 }
    557 
    558 static inline MagickBooleanType IsFloatDefined(const float value)
    559 {
    560   union
    561   {
    562     unsigned int
    563       unsigned_value;
    564 
    565     float
    566       float_value;
    567   } quantum;
    568 
    569   quantum.unsigned_value=0U;
    570   quantum.float_value=(float) value;
    571   if (quantum.unsigned_value == 0U)
    572     return(MagickFalse);
    573   return(MagickTrue);
    574 }
    575 
    576 static void SetPrimaryChromaticity(const DPXColorimetric colorimetric,
    577   ChromaticityInfo *chromaticity_info)
    578 {
    579   switch(colorimetric)
    580   {
    581     case SMTPE_274MColorimetric:
    582     case ITU_R709Colorimetric:
    583     {
    584       chromaticity_info->red_primary.x=0.640;
    585       chromaticity_info->red_primary.y=0.330;
    586       chromaticity_info->red_primary.z=0.030;
    587       chromaticity_info->green_primary.x=0.300;
    588       chromaticity_info->green_primary.y=0.600;
    589       chromaticity_info->green_primary.z=0.100;
    590       chromaticity_info->blue_primary.x=0.150;
    591       chromaticity_info->blue_primary.y=0.060;
    592       chromaticity_info->blue_primary.z=0.790;
    593       chromaticity_info->white_point.x=0.3127;
    594       chromaticity_info->white_point.y=0.3290;
    595       chromaticity_info->white_point.z=0.3582;
    596       break;
    597     }
    598     case NTSCCompositeVideoColorimetric:
    599     {
    600       chromaticity_info->red_primary.x=0.67;
    601       chromaticity_info->red_primary.y=0.33;
    602       chromaticity_info->red_primary.z=0.00;
    603       chromaticity_info->green_primary.x=0.21;
    604       chromaticity_info->green_primary.y=0.71;
    605       chromaticity_info->green_primary.z=0.08;
    606       chromaticity_info->blue_primary.x=0.14;
    607       chromaticity_info->blue_primary.y=0.08;
    608       chromaticity_info->blue_primary.z=0.78;
    609       chromaticity_info->white_point.x=0.310;
    610       chromaticity_info->white_point.y=0.316;
    611       chromaticity_info->white_point.z=0.374;
    612       break;
    613     }
    614     case PALCompositeVideoColorimetric:
    615     {
    616       chromaticity_info->red_primary.x=0.640;
    617       chromaticity_info->red_primary.y=0.330;
    618       chromaticity_info->red_primary.z=0.030;
    619       chromaticity_info->green_primary.x=0.290;
    620       chromaticity_info->green_primary.y=0.600;
    621       chromaticity_info->green_primary.z=0.110;
    622       chromaticity_info->blue_primary.x=0.150;
    623       chromaticity_info->blue_primary.y=0.060;
    624       chromaticity_info->blue_primary.z=0.790;
    625       chromaticity_info->white_point.x=0.3127;
    626       chromaticity_info->white_point.y=0.3290;
    627       chromaticity_info->white_point.z=0.3582;
    628       break;
    629     }
    630     default:
    631       break;
    632   }
    633 }
    634 
    635 static void TimeCodeToString(const size_t timestamp,char *code)
    636 {
    637 #define TimeFields  7
    638 
    639   unsigned int
    640     shift;
    641 
    642   register ssize_t
    643     i;
    644 
    645   *code='\0';
    646   shift=4*TimeFields;
    647   for (i=0; i <= TimeFields; i++)
    648   {
    649     (void) FormatLocaleString(code,MagickPathExtent-strlen(code),"%x",
    650       (unsigned int) ((timestamp >> shift) & 0x0fU));
    651     code++;
    652     if (((i % 2) != 0) && (i < TimeFields))
    653       *code++=':';
    654     shift-=4;
    655     *code='\0';
    656   }
    657 }
    658 
    659 static Image *ReadDPXImage(const ImageInfo *image_info,ExceptionInfo *exception)
    660 {
    661   char
    662     magick[4],
    663     value[MagickPathExtent];
    664 
    665   DPXInfo
    666     dpx;
    667 
    668   Image
    669     *image;
    670 
    671   MagickBooleanType
    672     status;
    673 
    674   MagickOffsetType
    675     offset;
    676 
    677   QuantumInfo
    678     *quantum_info;
    679 
    680   QuantumType
    681     quantum_type;
    682 
    683   register ssize_t
    684     i;
    685 
    686   size_t
    687     extent,
    688     samples_per_pixel;
    689 
    690   ssize_t
    691     count,
    692     n,
    693     row,
    694     y;
    695 
    696   unsigned char
    697     component_type;
    698 
    699   /*
    700     Open image file.
    701   */
    702   assert(image_info != (const ImageInfo *) NULL);
    703   assert(image_info->signature == MagickCoreSignature);
    704   if (image_info->debug != MagickFalse)
    705     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
    706       image_info->filename);
    707   assert(exception != (ExceptionInfo *) NULL);
    708   assert(exception->signature == MagickCoreSignature);
    709   image=AcquireImage(image_info,exception);
    710   status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
    711   if (status == MagickFalse)
    712     {
    713       image=DestroyImageList(image);
    714       return((Image *) NULL);
    715     }
    716   /*
    717     Read DPX file header.
    718   */
    719   offset=0;
    720   count=ReadBlob(image,4,(unsigned char *) magick);
    721   offset+=count;
    722   if ((count != 4) || ((LocaleNCompare(magick,"SDPX",4) != 0) &&
    723       (LocaleNCompare((char *) magick,"XPDS",4) != 0)))
    724     ThrowReaderException(CorruptImageError,"ImproperImageHeader");
    725   image->endian=LSBEndian;
    726   if (LocaleNCompare(magick,"SDPX",4) == 0)
    727     image->endian=MSBEndian;
    728   (void) memset(&dpx,0,sizeof(dpx));
    729   dpx.file.image_offset=ReadBlobLong(image);
    730   offset+=4;
    731   offset+=ReadBlob(image,sizeof(dpx.file.version),(unsigned char *)
    732     dpx.file.version);
    733   (void) FormatImageProperty(image,"dpx:file.version","%.8s",dpx.file.version);
    734   dpx.file.file_size=ReadBlobLong(image);
    735   if (0 && dpx.file.file_size > GetBlobSize(image))
    736     ThrowReaderException(CorruptImageError,"ImproperImageHeader");
    737   offset+=4;
    738   dpx.file.ditto_key=ReadBlobLong(image);
    739   offset+=4;
    740   if (dpx.file.ditto_key != ~0U)
    741     (void) FormatImageProperty(image,"dpx:file.ditto.key","%u",
    742       dpx.file.ditto_key);
    743   dpx.file.generic_size=ReadBlobLong(image);
    744   if (0 && dpx.file.generic_size > GetBlobSize(image))
    745     ThrowReaderException(CorruptImageError,"ImproperImageHeader");
    746   offset+=4;
    747   dpx.file.industry_size=ReadBlobLong(image);
    748   if (dpx.file.industry_size > GetBlobSize(image))
    749     ThrowReaderException(CorruptImageError,"ImproperImageHeader");
    750   offset+=4;
    751   dpx.file.user_size=ReadBlobLong(image);
    752   if (0 && dpx.file.user_size > GetBlobSize(image))
    753     ThrowReaderException(CorruptImageError,"ImproperImageHeader");
    754   offset+=4;
    755   offset+=ReadBlob(image,sizeof(dpx.file.filename),(unsigned char *)
    756     dpx.file.filename);
    757   (void) FormatImageProperty(image,"dpx:file.filename","%.100s",
    758     dpx.file.filename);
    759   (void) FormatImageProperty(image,"document","%.100s",dpx.file.filename);
    760   offset+=ReadBlob(image,sizeof(dpx.file.timestamp),(unsigned char *)
    761     dpx.file.timestamp);
    762   if (*dpx.file.timestamp != '\0')
    763     (void) FormatImageProperty(image,"dpx:file.timestamp","%.24s",
    764       dpx.file.timestamp);
    765   offset+=ReadBlob(image,sizeof(dpx.file.creator),(unsigned char *)
    766     dpx.file.creator);
    767   if (*dpx.file.creator != '\0')
    768     {
    769       (void) FormatImageProperty(image,"dpx:file.creator","%.100s",
    770         dpx.file.creator);
    771       (void) FormatImageProperty(image,"software","%.100s",dpx.file.creator);
    772     }
    773   offset+=ReadBlob(image,sizeof(dpx.file.project),(unsigned char *)
    774     dpx.file.project);
    775   if (*dpx.file.project != '\0')
    776     {
    777       (void) FormatImageProperty(image,"dpx:file.project","%.200s",
    778         dpx.file.project);
    779       (void) FormatImageProperty(image,"comment","%.100s",dpx.file.project);
    780     }
    781   offset+=ReadBlob(image,sizeof(dpx.file.copyright),(unsigned char *)
    782     dpx.file.copyright);
    783   if (*dpx.file.copyright != '\0')
    784     {
    785       (void) FormatImageProperty(image,"dpx:file.copyright","%.200s",
    786         dpx.file.copyright);
    787       (void) FormatImageProperty(image,"copyright","%.100s",
    788         dpx.file.copyright);
    789     }
    790   dpx.file.encrypt_key=ReadBlobLong(image);
    791   offset+=4;
    792   if (dpx.file.encrypt_key != ~0U)
    793     (void) FormatImageProperty(image,"dpx:file.encrypt_key","%u",
    794       dpx.file.encrypt_key);
    795   offset+=ReadBlob(image,sizeof(dpx.file.reserve),(unsigned char *)
    796     dpx.file.reserve);
    797   /*
    798     Read DPX image header.
    799   */
    800   dpx.image.orientation=ReadBlobShort(image);
    801   if (dpx.image.orientation > 7)
    802     ThrowReaderException(CorruptImageError,"ImproperImageHeader");
    803   offset+=2;
    804   if (dpx.image.orientation != (unsigned short) ~0)
    805     (void) FormatImageProperty(image,"dpx:image.orientation","%d",
    806       dpx.image.orientation);
    807   switch (dpx.image.orientation)
    808   {
    809     default:
    810     case 0: image->orientation=TopLeftOrientation; break;
    811     case 1: image->orientation=TopRightOrientation; break;
    812     case 2: image->orientation=BottomLeftOrientation; break;
    813     case 3: image->orientation=BottomRightOrientation; break;
    814     case 4: image->orientation=LeftTopOrientation; break;
    815     case 5: image->orientation=RightTopOrientation; break;
    816     case 6: image->orientation=LeftBottomOrientation; break;
    817     case 7: image->orientation=RightBottomOrientation; break;
    818   }
    819   dpx.image.number_elements=ReadBlobShort(image);
    820   if ((dpx.image.number_elements < 1) ||
    821       (dpx.image.number_elements > MaxNumberImageElements))
    822     ThrowReaderException(CorruptImageError,"ImproperImageHeader");
    823   offset+=2;
    824   dpx.image.pixels_per_line=ReadBlobLong(image);
    825   offset+=4;
    826   image->columns=dpx.image.pixels_per_line;
    827   dpx.image.lines_per_element=ReadBlobLong(image);
    828   offset+=4;
    829   image->rows=dpx.image.lines_per_element;
    830   for (i=0; i < 8; i++)
    831   {
    832     char
    833       property[MagickPathExtent];
    834 
    835     dpx.image.image_element[i].data_sign=ReadBlobLong(image);
    836     offset+=4;
    837     dpx.image.image_element[i].low_data=ReadBlobLong(image);
    838     offset+=4;
    839     dpx.image.image_element[i].low_quantity=ReadBlobFloat(image);
    840     offset+=4;
    841     dpx.image.image_element[i].high_data=ReadBlobLong(image);
    842     offset+=4;
    843     dpx.image.image_element[i].high_quantity=ReadBlobFloat(image);
    844     offset+=4;
    845     dpx.image.image_element[i].descriptor=(unsigned char) ReadBlobByte(image);
    846     offset++;
    847     dpx.image.image_element[i].transfer_characteristic=(unsigned char)
    848       ReadBlobByte(image);
    849     (void) FormatLocaleString(property,MagickPathExtent,
    850       "dpx:image.element[%lu].transfer-characteristic",(long) i);
    851     (void) FormatImageProperty(image,property,"%s",
    852       GetImageTransferCharacteristic((DPXTransferCharacteristic)
    853       dpx.image.image_element[i].transfer_characteristic));
    854     offset++;
    855     dpx.image.image_element[i].colorimetric=(unsigned char) ReadBlobByte(image);
    856     offset++;
    857     dpx.image.image_element[i].bit_size=(unsigned char) ReadBlobByte(image);
    858     offset++;
    859     dpx.image.image_element[i].packing=ReadBlobShort(image);
    860     if (dpx.image.image_element[i].packing > 2)
    861       ThrowReaderException(CorruptImageError,"ImproperImageHeader");
    862     offset+=2;
    863     dpx.image.image_element[i].encoding=ReadBlobShort(image);
    864     offset+=2;
    865     dpx.image.image_element[i].data_offset=ReadBlobLong(image);
    866     offset+=4;
    867     dpx.image.image_element[i].end_of_line_padding=ReadBlobLong(image);
    868     offset+=4;
    869     dpx.image.image_element[i].end_of_image_padding=ReadBlobLong(image);
    870     offset+=4;
    871     offset+=ReadBlob(image,sizeof(dpx.image.image_element[i].description),
    872       (unsigned char *) dpx.image.image_element[i].description);
    873   }
    874   SetImageColorspace(image,RGBColorspace,exception);
    875   offset+=ReadBlob(image,sizeof(dpx.image.reserve),(unsigned char *)
    876     dpx.image.reserve);
    877   if (dpx.file.image_offset >= 1664U)
    878     {
    879       /*
    880         Read DPX orientation header.
    881       */
    882       dpx.orientation.x_offset=ReadBlobLong(image);
    883       offset+=4;
    884       if (dpx.orientation.x_offset != ~0U)
    885         (void) FormatImageProperty(image,"dpx:orientation.x_offset","%u",
    886           dpx.orientation.x_offset);
    887       dpx.orientation.y_offset=ReadBlobLong(image);
    888       offset+=4;
    889       if (dpx.orientation.y_offset != ~0U)
    890         (void) FormatImageProperty(image,"dpx:orientation.y_offset","%u",
    891           dpx.orientation.y_offset);
    892       dpx.orientation.x_center=ReadBlobFloat(image);
    893       offset+=4;
    894       if (IsFloatDefined(dpx.orientation.x_center) != MagickFalse)
    895         (void) FormatImageProperty(image,"dpx:orientation.x_center","%g",
    896           dpx.orientation.x_center);
    897       dpx.orientation.y_center=ReadBlobFloat(image);
    898       offset+=4;
    899       if (IsFloatDefined(dpx.orientation.y_center) != MagickFalse)
    900         (void) FormatImageProperty(image,"dpx:orientation.y_center","%g",
    901           dpx.orientation.y_center);
    902       dpx.orientation.x_size=ReadBlobLong(image);
    903       offset+=4;
    904       if (dpx.orientation.x_size != ~0U)
    905         (void) FormatImageProperty(image,"dpx:orientation.x_size","%u",
    906           dpx.orientation.x_size);
    907       dpx.orientation.y_size=ReadBlobLong(image);
    908       offset+=4;
    909       if (dpx.orientation.y_size != ~0U)
    910         (void) FormatImageProperty(image,"dpx:orientation.y_size","%u",
    911           dpx.orientation.y_size);
    912       offset+=ReadBlob(image,sizeof(dpx.orientation.filename),(unsigned char *)
    913         dpx.orientation.filename);
    914       if (*dpx.orientation.filename != '\0')
    915         (void) FormatImageProperty(image,"dpx:orientation.filename","%.100s",
    916           dpx.orientation.filename);
    917       offset+=ReadBlob(image,sizeof(dpx.orientation.timestamp),(unsigned char *)
    918         dpx.orientation.timestamp);
    919       if (*dpx.orientation.timestamp != '\0')
    920         (void) FormatImageProperty(image,"dpx:orientation.timestamp","%.24s",
    921           dpx.orientation.timestamp);
    922       offset+=ReadBlob(image,sizeof(dpx.orientation.device),(unsigned char *)
    923         dpx.orientation.device);
    924       if (*dpx.orientation.device != '\0')
    925         (void) FormatImageProperty(image,"dpx:orientation.device","%.32s",
    926           dpx.orientation.device);
    927       offset+=ReadBlob(image,sizeof(dpx.orientation.serial),(unsigned char *)
    928         dpx.orientation.serial);
    929       if (*dpx.orientation.serial != '\0')
    930         (void) FormatImageProperty(image,"dpx:orientation.serial","%.32s",
    931           dpx.orientation.serial);
    932       for (i=0; i < 4; i++)
    933       {
    934         dpx.orientation.border[i]=ReadBlobShort(image);
    935         offset+=2;
    936       }
    937       if ((dpx.orientation.border[0] != (unsigned short) (~0)) &&
    938           (dpx.orientation.border[1] != (unsigned short) (~0)))
    939         (void) FormatImageProperty(image,"dpx:orientation.border","%dx%d%+d%+d",
    940           dpx.orientation.border[0],dpx.orientation.border[1],
    941           dpx.orientation.border[2],dpx.orientation.border[3]);
    942       for (i=0; i < 2; i++)
    943       {
    944         dpx.orientation.aspect_ratio[i]=ReadBlobLong(image);
    945         offset+=4;
    946       }
    947       if ((dpx.orientation.aspect_ratio[0] != ~0U) &&
    948           (dpx.orientation.aspect_ratio[1] != ~0U))
    949         (void) FormatImageProperty(image,"dpx:orientation.aspect_ratio",
    950           "%ux%u",dpx.orientation.aspect_ratio[0],
    951           dpx.orientation.aspect_ratio[1]);
    952       offset+=ReadBlob(image,sizeof(dpx.orientation.reserve),(unsigned char *)
    953         dpx.orientation.reserve);
    954     }
    955   if (dpx.file.image_offset >= 1920U)
    956     {
    957       /*
    958         Read DPX film header.
    959       */
    960       offset+=ReadBlob(image,sizeof(dpx.film.id),(unsigned char *) dpx.film.id);
    961       if (*dpx.film.id != '\0')
    962         (void) FormatImageProperty(image,"dpx:film.id","%.2s",dpx.film.id);
    963       offset+=ReadBlob(image,sizeof(dpx.film.type),(unsigned char *)
    964         dpx.film.type);
    965       if (*dpx.film.type != '\0')
    966         (void) FormatImageProperty(image,"dpx:film.type","%.2s",dpx.film.type);
    967       offset+=ReadBlob(image,sizeof(dpx.film.offset),(unsigned char *)
    968         dpx.film.offset);
    969       if (*dpx.film.offset != '\0')
    970         (void) FormatImageProperty(image,"dpx:film.offset","%.2s",
    971           dpx.film.offset);
    972       offset+=ReadBlob(image,sizeof(dpx.film.prefix),(unsigned char *)
    973         dpx.film.prefix);
    974       if (*dpx.film.prefix != '\0')
    975         (void) FormatImageProperty(image,"dpx:film.prefix","%.6s",
    976           dpx.film.prefix);
    977       offset+=ReadBlob(image,sizeof(dpx.film.count),(unsigned char *)
    978         dpx.film.count);
    979       if (*dpx.film.count != '\0')
    980         (void) FormatImageProperty(image,"dpx:film.count","%.4s",
    981           dpx.film.count);
    982       offset+=ReadBlob(image,sizeof(dpx.film.format),(unsigned char *)
    983         dpx.film.format);
    984       if (*dpx.film.format != '\0')
    985         (void) FormatImageProperty(image,"dpx:film.format","%.4s",
    986           dpx.film.format);
    987       dpx.film.frame_position=ReadBlobLong(image);
    988       offset+=4;
    989       if (dpx.film.frame_position != ~0U)
    990         (void) FormatImageProperty(image,"dpx:film.frame_position","%u",
    991           dpx.film.frame_position);
    992       dpx.film.sequence_extent=ReadBlobLong(image);
    993       offset+=4;
    994       if (dpx.film.sequence_extent != ~0U)
    995         (void) FormatImageProperty(image,"dpx:film.sequence_extent","%u",
    996           dpx.film.sequence_extent);
    997       dpx.film.held_count=ReadBlobLong(image);
    998       offset+=4;
    999       if (dpx.film.held_count != ~0U)
   1000         (void) FormatImageProperty(image,"dpx:film.held_count","%u",
   1001           dpx.film.held_count);
   1002       dpx.film.frame_rate=ReadBlobFloat(image);
   1003       offset+=4;
   1004       if (IsFloatDefined(dpx.film.frame_rate) != MagickFalse)
   1005         (void) FormatImageProperty(image,"dpx:film.frame_rate","%g",
   1006           dpx.film.frame_rate);
   1007       dpx.film.shutter_angle=ReadBlobFloat(image);
   1008       offset+=4;
   1009       if (IsFloatDefined(dpx.film.shutter_angle) != MagickFalse)
   1010         (void) FormatImageProperty(image,"dpx:film.shutter_angle","%g",
   1011           dpx.film.shutter_angle);
   1012       offset+=ReadBlob(image,sizeof(dpx.film.frame_id),(unsigned char *)
   1013         dpx.film.frame_id);
   1014       if (*dpx.film.frame_id != '\0')
   1015         (void) FormatImageProperty(image,"dpx:film.frame_id","%.32s",
   1016           dpx.film.frame_id);
   1017       offset+=ReadBlob(image,sizeof(dpx.film.slate),(unsigned char *)
   1018         dpx.film.slate);
   1019       if (*dpx.film.slate != '\0')
   1020         (void) FormatImageProperty(image,"dpx:film.slate","%.100s",
   1021           dpx.film.slate);
   1022       offset+=ReadBlob(image,sizeof(dpx.film.reserve),(unsigned char *)
   1023         dpx.film.reserve);
   1024     }
   1025   if (dpx.file.image_offset >= 2048U)
   1026     {
   1027       /*
   1028         Read DPX television header.
   1029       */
   1030       dpx.television.time_code=(unsigned int) ReadBlobLong(image);
   1031       offset+=4;
   1032       TimeCodeToString(dpx.television.time_code,value);
   1033       (void) SetImageProperty(image,"dpx:television.time.code",value,exception);
   1034       dpx.television.user_bits=(unsigned int) ReadBlobLong(image);
   1035       offset+=4;
   1036       TimeCodeToString(dpx.television.user_bits,value);
   1037       (void) SetImageProperty(image,"dpx:television.user.bits",value,exception);
   1038       dpx.television.interlace=(unsigned char) ReadBlobByte(image);
   1039       offset++;
   1040       if (dpx.television.interlace != 0)
   1041         (void) FormatImageProperty(image,"dpx:television.interlace","%.20g",
   1042           (double) dpx.television.interlace);
   1043       dpx.television.field_number=(unsigned char) ReadBlobByte(image);
   1044       offset++;
   1045       if (dpx.television.field_number != 0)
   1046         (void) FormatImageProperty(image,"dpx:television.field_number","%.20g",
   1047           (double) dpx.television.field_number);
   1048       dpx.television.video_signal=(unsigned char) ReadBlobByte(image);
   1049       offset++;
   1050       if (dpx.television.video_signal != 0)
   1051         (void) FormatImageProperty(image,"dpx:television.video_signal","%.20g",
   1052           (double) dpx.television.video_signal);
   1053       dpx.television.padding=(unsigned char) ReadBlobByte(image);
   1054       offset++;
   1055       if (dpx.television.padding != 0)
   1056         (void) FormatImageProperty(image,"dpx:television.padding","%d",
   1057           dpx.television.padding);
   1058       dpx.television.horizontal_sample_rate=ReadBlobFloat(image);
   1059       offset+=4;
   1060       if (IsFloatDefined(dpx.television.horizontal_sample_rate) != MagickFalse)
   1061         (void) FormatImageProperty(image,
   1062           "dpx:television.horizontal_sample_rate","%g",
   1063           dpx.television.horizontal_sample_rate);
   1064       dpx.television.vertical_sample_rate=ReadBlobFloat(image);
   1065       offset+=4;
   1066       if (IsFloatDefined(dpx.television.vertical_sample_rate) != MagickFalse)
   1067         (void) FormatImageProperty(image,"dpx:television.vertical_sample_rate",
   1068           "%g",dpx.television.vertical_sample_rate);
   1069       dpx.television.frame_rate=ReadBlobFloat(image);
   1070       offset+=4;
   1071       if (IsFloatDefined(dpx.television.frame_rate) != MagickFalse)
   1072         (void) FormatImageProperty(image,"dpx:television.frame_rate","%g",
   1073           dpx.television.frame_rate);
   1074       dpx.television.time_offset=ReadBlobFloat(image);
   1075       offset+=4;
   1076       if (IsFloatDefined(dpx.television.time_offset) != MagickFalse)
   1077         (void) FormatImageProperty(image,"dpx:television.time_offset","%g",
   1078           dpx.television.time_offset);
   1079       dpx.television.gamma=ReadBlobFloat(image);
   1080       offset+=4;
   1081       if (IsFloatDefined(dpx.television.gamma) != MagickFalse)
   1082         (void) FormatImageProperty(image,"dpx:television.gamma","%g",
   1083           dpx.television.gamma);
   1084       dpx.television.black_level=ReadBlobFloat(image);
   1085       offset+=4;
   1086       if (IsFloatDefined(dpx.television.black_level) != MagickFalse)
   1087         (void) FormatImageProperty(image,"dpx:television.black_level","%g",
   1088           dpx.television.black_level);
   1089       dpx.television.black_gain=ReadBlobFloat(image);
   1090       offset+=4;
   1091       if (IsFloatDefined(dpx.television.black_gain) != MagickFalse)
   1092         (void) FormatImageProperty(image,"dpx:television.black_gain","%g",
   1093           dpx.television.black_gain);
   1094       dpx.television.break_point=ReadBlobFloat(image);
   1095       offset+=4;
   1096       if (IsFloatDefined(dpx.television.break_point) != MagickFalse)
   1097         (void) FormatImageProperty(image,"dpx:television.break_point","%g",
   1098           dpx.television.break_point);
   1099       dpx.television.white_level=ReadBlobFloat(image);
   1100       offset+=4;
   1101       if (IsFloatDefined(dpx.television.white_level) != MagickFalse)
   1102         (void) FormatImageProperty(image,"dpx:television.white_level","%g",
   1103           dpx.television.white_level);
   1104       dpx.television.integration_times=ReadBlobFloat(image);
   1105       offset+=4;
   1106       if (IsFloatDefined(dpx.television.integration_times) != MagickFalse)
   1107         (void) FormatImageProperty(image,"dpx:television.integration_times",
   1108           "%g",dpx.television.integration_times);
   1109       offset+=ReadBlob(image,sizeof(dpx.television.reserve),(unsigned char *)
   1110         dpx.television.reserve);
   1111     }
   1112   if (dpx.file.image_offset > 2080U)
   1113     {
   1114       /*
   1115         Read DPX user header.
   1116       */
   1117       offset+=ReadBlob(image,sizeof(dpx.user.id),(unsigned char *) dpx.user.id);
   1118       if (*dpx.user.id != '\0')
   1119         (void) FormatImageProperty(image,"dpx:user.id","%.32s",dpx.user.id);
   1120       if ((dpx.file.user_size != ~0U) &&
   1121           ((size_t) dpx.file.user_size > sizeof(dpx.user.id)))
   1122         {
   1123           StringInfo
   1124             *profile;
   1125 
   1126            if (dpx.file.user_size > GetBlobSize(image))
   1127              ThrowReaderException(CorruptImageError,
   1128                "InsufficientImageDataInFile");
   1129            profile=BlobToStringInfo((const unsigned char *) NULL,
   1130              dpx.file.user_size-sizeof(dpx.user.id));
   1131            if (profile == (StringInfo *) NULL)
   1132              ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
   1133            offset+=ReadBlob(image,GetStringInfoLength(profile),
   1134              GetStringInfoDatum(profile));
   1135            if (EOFBlob(image) != MagickFalse)
   1136              (void) SetImageProfile(image,"dpx:user-data",profile,exception);
   1137            profile=DestroyStringInfo(profile);
   1138         }
   1139     }
   1140   for ( ; offset < (MagickOffsetType) dpx.file.image_offset; offset++)
   1141     if (ReadBlobByte(image) == EOF)
   1142       break;
   1143   if (EOFBlob(image) != MagickFalse)
   1144     ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
   1145       image->filename);
   1146   if (image_info->ping != MagickFalse)
   1147     {
   1148       (void) CloseBlob(image);
   1149       return(GetFirstImageInList(image));
   1150     }
   1151   status=SetImageExtent(image,image->columns,image->rows,exception);
   1152   if (status == MagickFalse)
   1153     return(DestroyImageList(image));
   1154   status=ResetImagePixels(image,exception);
   1155   if (status == MagickFalse)
   1156     return(DestroyImageList(image));
   1157   for (n=0; n < (ssize_t) dpx.image.number_elements; n++)
   1158   {
   1159     /*
   1160       Convert DPX raster image to pixel packets.
   1161     */
   1162     if ((dpx.image.image_element[n].data_offset != ~0U) &&
   1163         (dpx.image.image_element[n].data_offset != 0U))
   1164       {
   1165          MagickOffsetType
   1166            data_offset;
   1167 
   1168          data_offset=(MagickOffsetType) dpx.image.image_element[n].data_offset;
   1169          if (data_offset < offset)
   1170            offset=SeekBlob(image,data_offset,SEEK_SET);
   1171          else
   1172            for ( ; offset < data_offset; offset++)
   1173              if (ReadBlobByte(image) == EOF)
   1174                break;
   1175           if (offset != data_offset)
   1176             ThrowReaderException(CorruptImageError,"UnableToReadImageData");
   1177        }
   1178     SetPrimaryChromaticity((DPXColorimetric)
   1179       dpx.image.image_element[n].colorimetric,&image->chromaticity);
   1180     image->depth=dpx.image.image_element[n].bit_size;
   1181     if ((image->depth == 0) || (image->depth > 32))
   1182       ThrowReaderException(CorruptImageError,"ImproperImageHeader");
   1183     samples_per_pixel=1;
   1184     quantum_type=GrayQuantum;
   1185     component_type=dpx.image.image_element[n].descriptor;
   1186     switch (component_type)
   1187     {
   1188       case CbYCrY422ComponentType:
   1189       {
   1190         samples_per_pixel=2;
   1191         quantum_type=CbYCrYQuantum;
   1192         break;
   1193       }
   1194       case CbYACrYA4224ComponentType:
   1195       case CbYCr444ComponentType:
   1196       {
   1197         samples_per_pixel=3;
   1198         quantum_type=CbYCrQuantum;
   1199         break;
   1200       }
   1201       case RGBComponentType:
   1202       {
   1203         samples_per_pixel=3;
   1204         quantum_type=RGBQuantum;
   1205         break;
   1206       }
   1207       case ABGRComponentType:
   1208       case RGBAComponentType:
   1209       {
   1210         image->alpha_trait=BlendPixelTrait;
   1211         samples_per_pixel=4;
   1212         quantum_type=RGBAQuantum;
   1213         break;
   1214       }
   1215       default:
   1216         break;
   1217     }
   1218     switch (component_type)
   1219     {
   1220       case CbYCrY422ComponentType:
   1221       case CbYACrYA4224ComponentType:
   1222       case CbYCr444ComponentType:
   1223       {
   1224         SetImageColorspace(image,Rec709YCbCrColorspace,exception);
   1225         break;
   1226       }
   1227       case LumaComponentType:
   1228       {
   1229         SetImageColorspace(image,GRAYColorspace,exception);
   1230         break;
   1231       }
   1232       default:
   1233       {
   1234         SetImageColorspace(image,sRGBColorspace,exception);
   1235         if (dpx.image.image_element[n].transfer_characteristic == LogarithmicColorimetric)
   1236           SetImageColorspace(image,LogColorspace,exception);
   1237         if (dpx.image.image_element[n].transfer_characteristic == PrintingDensityColorimetric)
   1238           SetImageColorspace(image,LogColorspace,exception);
   1239         break;
   1240       }
   1241     }
   1242     extent=GetBytesPerRow(image->columns,samples_per_pixel,image->depth,
   1243       dpx.image.image_element[n].packing == 0 ? MagickFalse : MagickTrue);
   1244     /*
   1245       DPX any-bit pixel format.
   1246     */
   1247     row=0;
   1248     quantum_info=AcquireQuantumInfo(image_info,image);
   1249     if (quantum_info == (QuantumInfo *) NULL)
   1250       ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
   1251     SetQuantumQuantum(quantum_info,32);
   1252     SetQuantumPack(quantum_info,dpx.image.image_element[n].packing == 0 ?
   1253       MagickTrue : MagickFalse);
   1254     for (y=0; y < (ssize_t) image->rows; y++)
   1255     {
   1256       const unsigned char
   1257         *pixels;
   1258 
   1259       MagickBooleanType
   1260         sync;
   1261 
   1262       register Quantum
   1263         *q;
   1264 
   1265       size_t
   1266         length;
   1267 
   1268       ssize_t
   1269         offset;
   1270 
   1271       pixels=(const unsigned char *) ReadBlobStream(image,extent,
   1272         GetQuantumPixels(quantum_info),&count);
   1273       if (count != (ssize_t) extent)
   1274         break;
   1275       if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
   1276           (image->previous == (Image *) NULL))
   1277         {
   1278           MagickBooleanType
   1279             proceed;
   1280 
   1281           proceed=SetImageProgress(image,LoadImageTag,(MagickOffsetType) row,
   1282             image->rows);
   1283           if (proceed == MagickFalse)
   1284             break;
   1285         }
   1286       offset=row++;
   1287       q=QueueAuthenticPixels(image,0,offset,image->columns,1,exception);
   1288       if (q == (Quantum *) NULL)
   1289         break;
   1290       length=ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
   1291         quantum_type,pixels,exception);
   1292       (void) length;
   1293       sync=SyncAuthenticPixels(image,exception);
   1294       if (sync == MagickFalse)
   1295         break;
   1296     }
   1297     quantum_info=DestroyQuantumInfo(quantum_info);
   1298     if (y < (ssize_t) image->rows)
   1299       ThrowReaderException(CorruptImageError,"UnableToReadImageData");
   1300     SetQuantumImageType(image,quantum_type);
   1301     if (EOFBlob(image) != MagickFalse)
   1302       ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
   1303         image->filename);
   1304     if ((i+1) < (ssize_t) dpx.image.number_elements)
   1305       {
   1306         /*
   1307           Allocate next image structure.
   1308         */
   1309         AcquireNextImage(image_info,image,exception);
   1310         if (GetNextImageInList(image) == (Image *) NULL)
   1311           {
   1312             status=MagickFalse;
   1313             break;
   1314           }
   1315         image=SyncNextImageInList(image);
   1316         status=SetImageProgress(image,LoadImagesTag,TellBlob(image),
   1317           GetBlobSize(image));
   1318         if (status == MagickFalse)
   1319           break;
   1320       }
   1321   }
   1322   (void) CloseBlob(image);
   1323   if (status == MagickFalse)
   1324     return(DestroyImageList(image));
   1325   return(GetFirstImageInList(image));
   1326 }
   1327 
   1328 /*
   1330 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1331 %                                                                             %
   1332 %                                                                             %
   1333 %                                                                             %
   1334 %   R e g i s t e r D P X I m a g e                                           %
   1335 %                                                                             %
   1336 %                                                                             %
   1337 %                                                                             %
   1338 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1339 %
   1340 %  RegisterDPXImage() adds properties for the DPX image format to
   1341 %  the list of supported formats.  The properties include the image format
   1342 %  tag, a method to read and/or write the format, whether the format
   1343 %  supports the saving of more than one frame to the same file or blob,
   1344 %  whether the format supports native in-memory I/O, and a brief
   1345 %  description of the format.
   1346 %
   1347 %  The format of the RegisterDPXImage method is:
   1348 %
   1349 %      size_t RegisterDPXImage(void)
   1350 %
   1351 */
   1352 ModuleExport size_t RegisterDPXImage(void)
   1353 {
   1354   MagickInfo
   1355     *entry;
   1356 
   1357   static const char
   1358     *DPXNote =
   1359     {
   1360       "Digital Moving Picture Exchange Bitmap, Version 2.0.\n"
   1361       "See SMPTE 268M-2003 specification at http://www.smtpe.org\n"
   1362     };
   1363 
   1364   entry=AcquireMagickInfo("DPX","DPX","SMPTE 268M-2003 (DPX 2.0)");
   1365   entry->decoder=(DecodeImageHandler *) ReadDPXImage;
   1366   entry->encoder=(EncodeImageHandler *) WriteDPXImage;
   1367   entry->magick=(IsImageFormatHandler *) IsDPX;
   1368   entry->flags^=CoderAdjoinFlag;
   1369   entry->flags|=CoderDecoderSeekableStreamFlag;
   1370   entry->note=ConstantString(DPXNote);
   1371   (void) RegisterMagickInfo(entry);
   1372   return(MagickImageCoderSignature);
   1373 }
   1374 
   1375 /*
   1377 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1378 %                                                                             %
   1379 %                                                                             %
   1380 %                                                                             %
   1381 %   U n r e g i s t e r D P X I m a g e                                       %
   1382 %                                                                             %
   1383 %                                                                             %
   1384 %                                                                             %
   1385 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1386 %
   1387 %  UnregisterDPXImage() removes format registrations made by the
   1388 %  DPX module from the list of supported formats.
   1389 %
   1390 %  The format of the UnregisterDPXImage method is:
   1391 %
   1392 %      UnregisterDPXImage(void)
   1393 %
   1394 */
   1395 ModuleExport void UnregisterDPXImage(void)
   1396 {
   1397   (void) UnregisterMagickInfo("DPX");
   1398 }
   1399 
   1400 /*
   1402 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1403 %                                                                             %
   1404 %                                                                             %
   1405 %                                                                             %
   1406 %   W r i t e D P X I m a g e                                                 %
   1407 %                                                                             %
   1408 %                                                                             %
   1409 %                                                                             %
   1410 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
   1411 %
   1412 %  WriteDPXImage() writes an image in DPX encoded image format.
   1413 %
   1414 %  The format of the WriteDPXImage method is:
   1415 %
   1416 %      MagickBooleanType WriteDPXImage(const ImageInfo *image_info,
   1417 %        Image *image,ExceptionInfo *exception)
   1418 %
   1419 %  A description of each parameter follows.
   1420 %
   1421 %    o image_info: the image info.
   1422 %
   1423 %    o image:  The image.
   1424 %
   1425 %    o exception: return any errors or warnings in this structure.
   1426 %
   1427 */
   1428 
   1429 static unsigned int StringToTimeCode(const char *key)
   1430 {
   1431   char
   1432     buffer[2];
   1433 
   1434   register ssize_t
   1435     i;
   1436 
   1437   unsigned int
   1438     shift,
   1439     value;
   1440 
   1441   value=0;
   1442   shift=28;
   1443   buffer[1]='\0';
   1444   for (i=0; (*key != 0) && (i < 11); i++)
   1445   {
   1446     if (isxdigit((int) ((unsigned char) *key)) == 0)
   1447       {
   1448         key++;
   1449         continue;
   1450       }
   1451     buffer[0]=(*key++);
   1452     value|=(unsigned int) ((strtol(buffer,(char **) NULL,16)) << shift);
   1453     shift-=4;
   1454   }
   1455   return(value);
   1456 }
   1457 
   1458 static inline const char *GetDPXProperty(const Image *image,
   1459   const char *property,ExceptionInfo *exception)
   1460 {
   1461   const char
   1462     *value;
   1463 
   1464   value=GetImageArtifact(image,property);
   1465   if (value != (const char *) NULL)
   1466     return(value);
   1467   return(GetImageProperty(image,property,exception));
   1468 }
   1469 
   1470 static MagickBooleanType WriteDPXImage(const ImageInfo *image_info,Image *image,
   1471   ExceptionInfo *exception)
   1472 {
   1473   char
   1474     *url;
   1475 
   1476   const char
   1477     *value;
   1478 
   1479   const StringInfo
   1480     *profile;
   1481 
   1482   DPXInfo
   1483     dpx;
   1484 
   1485   GeometryInfo
   1486     geometry_info;
   1487 
   1488   MagickBooleanType
   1489     status;
   1490 
   1491   MagickOffsetType
   1492     offset;
   1493 
   1494   MagickStatusType
   1495     flags;
   1496 
   1497   QuantumInfo
   1498     *quantum_info;
   1499 
   1500   QuantumType
   1501     quantum_type;
   1502 
   1503   register const Quantum
   1504     *p;
   1505 
   1506   register ssize_t
   1507     i;
   1508 
   1509   size_t
   1510     channels,
   1511     extent;
   1512 
   1513   ssize_t
   1514     count,
   1515     horizontal_factor,
   1516     vertical_factor,
   1517     y;
   1518 
   1519   time_t
   1520     seconds;
   1521 
   1522   unsigned char
   1523     *pixels;
   1524 
   1525   /*
   1526     Open output image file.
   1527   */
   1528   assert(image_info != (const ImageInfo *) NULL);
   1529   assert(image_info->signature == MagickCoreSignature);
   1530   assert(image != (Image *) NULL);
   1531   assert(image->signature == MagickCoreSignature);
   1532   if (image->debug != MagickFalse)
   1533     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
   1534   horizontal_factor=4;
   1535   vertical_factor=4;
   1536   if (image_info->sampling_factor != (char *) NULL)
   1537     {
   1538       flags=ParseGeometry(image_info->sampling_factor,&geometry_info);
   1539       horizontal_factor=(ssize_t) geometry_info.rho;
   1540       vertical_factor=(ssize_t) geometry_info.sigma;
   1541       if ((flags & SigmaValue) == 0)
   1542         vertical_factor=horizontal_factor;
   1543       if ((horizontal_factor != 1) && (horizontal_factor != 2) &&
   1544           (horizontal_factor != 4) && (vertical_factor != 1) &&
   1545           (vertical_factor != 2) && (vertical_factor != 4))
   1546         ThrowWriterException(CorruptImageError,"UnexpectedSamplingFactor");
   1547     }
   1548   if ((image->colorspace == YCbCrColorspace) &&
   1549       ((horizontal_factor == 2) || (vertical_factor == 2)))
   1550     if ((image->columns % 2) != 0)
   1551       image->columns++;
   1552   assert(exception != (ExceptionInfo *) NULL);
   1553   assert(exception->signature == MagickCoreSignature);
   1554   status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
   1555   if (status == MagickFalse)
   1556     return(status);
   1557   /*
   1558     Write file header.
   1559   */
   1560   (void) memset(&dpx,0,sizeof(dpx));
   1561   offset=0;
   1562   dpx.file.magic=0x53445058U;
   1563   offset+=WriteBlobLong(image,dpx.file.magic);
   1564   dpx.file.image_offset=0x2000U;
   1565   profile=GetImageProfile(image,"dpx:user-data");
   1566   if (profile != (StringInfo *) NULL)
   1567     {
   1568       if (GetStringInfoLength(profile) > 1048576)
   1569         ThrowWriterException(ImageError,"WidthOrHeightExceedsLimit");
   1570       dpx.file.image_offset+=(unsigned int) GetStringInfoLength(profile);
   1571       dpx.file.image_offset=(((dpx.file.image_offset+0x2000-1)/0x2000)*0x2000);
   1572     }
   1573   offset+=WriteBlobLong(image,dpx.file.image_offset);
   1574   (void) strncpy(dpx.file.version,"V2.0",sizeof(dpx.file.version)-1);
   1575   offset+=WriteBlob(image,8,(unsigned char *) &dpx.file.version);
   1576   channels=1;
   1577   if (IsImageGray(image) == MagickFalse)
   1578     channels=3;
   1579   if (image->alpha_trait != UndefinedPixelTrait)
   1580     channels++;
   1581   dpx.file.file_size=(unsigned int) (channels*image->columns*image->rows+
   1582     dpx.file.image_offset);
   1583   offset+=WriteBlobLong(image,dpx.file.file_size);
   1584   dpx.file.ditto_key=1U;  /* new frame */
   1585   offset+=WriteBlobLong(image,dpx.file.ditto_key);
   1586   dpx.file.generic_size=0x00000680U;
   1587   offset+=WriteBlobLong(image,dpx.file.generic_size);
   1588   dpx.file.industry_size=0x00000180U;
   1589   offset+=WriteBlobLong(image,dpx.file.industry_size);
   1590   dpx.file.user_size=0;
   1591   if (profile != (StringInfo *) NULL)
   1592     {
   1593       dpx.file.user_size+=(unsigned int) GetStringInfoLength(profile);
   1594       dpx.file.user_size=(((dpx.file.user_size+0x2000-1)/0x2000)*0x2000);
   1595     }
   1596   offset+=WriteBlobLong(image,dpx.file.user_size);
   1597   value=GetDPXProperty(image,"dpx:file.filename",exception);
   1598   if (value != (const char *) NULL)
   1599     (void) strncpy(dpx.file.filename,value,sizeof(dpx.file.filename)-1);
   1600   offset+=WriteBlob(image,sizeof(dpx.file.filename),(unsigned char *)
   1601     dpx.file.filename);
   1602   seconds=time((time_t *) NULL);
   1603   (void) FormatMagickTime(seconds,sizeof(dpx.file.timestamp),
   1604     dpx.file.timestamp);
   1605   offset+=WriteBlob(image,sizeof(dpx.file.timestamp),(unsigned char *)
   1606     dpx.file.timestamp);
   1607   url=GetMagickHomeURL();
   1608   (void) strncpy(dpx.file.creator,url,sizeof(dpx.file.creator)-1);
   1609   url=DestroyString(url);
   1610   value=GetDPXProperty(image,"dpx:file.creator",exception);
   1611   if (value != (const char *) NULL)
   1612     (void) strncpy(dpx.file.creator,value,sizeof(dpx.file.creator)-1);
   1613   offset+=WriteBlob(image,sizeof(dpx.file.creator),(unsigned char *)
   1614     dpx.file.creator);
   1615   value=GetDPXProperty(image,"dpx:file.project",exception);
   1616   if (value != (const char *) NULL)
   1617     (void) strncpy(dpx.file.project,value,sizeof(dpx.file.project)-1);
   1618   offset+=WriteBlob(image,sizeof(dpx.file.project),(unsigned char *)
   1619     dpx.file.project);
   1620   value=GetDPXProperty(image,"dpx:file.copyright",exception);
   1621   if (value != (const char *) NULL)
   1622     (void) strncpy(dpx.file.copyright,value,sizeof(dpx.file.copyright)-1);
   1623   offset+=WriteBlob(image,sizeof(dpx.file.copyright),(unsigned char *)
   1624     dpx.file.copyright);
   1625   dpx.file.encrypt_key=(~0U);
   1626   offset+=WriteBlobLong(image,dpx.file.encrypt_key);
   1627   offset+=WriteBlob(image,sizeof(dpx.file.reserve),(unsigned char *)
   1628     dpx.file.reserve);
   1629   /*
   1630     Write image header.
   1631   */
   1632   switch (image->orientation)
   1633   {
   1634     default:
   1635     case TopLeftOrientation: dpx.image.orientation=0; break;
   1636     case TopRightOrientation: dpx.image.orientation=1; break;
   1637     case BottomLeftOrientation: dpx.image.orientation=2; break;
   1638     case BottomRightOrientation: dpx.image.orientation=3; break;
   1639     case LeftTopOrientation: dpx.image.orientation=4; break;
   1640     case RightTopOrientation: dpx.image.orientation=5; break;
   1641     case LeftBottomOrientation: dpx.image.orientation=6; break;
   1642     case RightBottomOrientation: dpx.image.orientation=7; break;
   1643   }
   1644   offset+=WriteBlobShort(image,dpx.image.orientation);
   1645   dpx.image.number_elements=1;
   1646   offset+=WriteBlobShort(image,dpx.image.number_elements);
   1647   if ((image->columns != (unsigned int) image->columns) ||
   1648       (image->rows != (unsigned int) image->rows))
   1649     ThrowWriterException(ImageError,"WidthOrHeightExceedsLimit");
   1650   offset+=WriteBlobLong(image,(unsigned int) image->columns);
   1651   offset+=WriteBlobLong(image,(unsigned int) image->rows);
   1652   for (i=0; i < 8; i++)
   1653   {
   1654     dpx.image.image_element[i].data_sign=0U;
   1655     offset+=WriteBlobLong(image,dpx.image.image_element[i].data_sign);
   1656     dpx.image.image_element[i].low_data=0U;
   1657     offset+=WriteBlobLong(image,dpx.image.image_element[i].low_data);
   1658     dpx.image.image_element[i].low_quantity=0.0f;
   1659     offset+=WriteBlobFloat(image,dpx.image.image_element[i].low_quantity);
   1660     dpx.image.image_element[i].high_data=0U;
   1661     offset+=WriteBlobLong(image,dpx.image.image_element[i].high_data);
   1662     dpx.image.image_element[i].high_quantity=0.0f;
   1663     offset+=WriteBlobFloat(image,dpx.image.image_element[i].high_quantity);
   1664     dpx.image.image_element[i].descriptor=0;
   1665     if (i == 0)
   1666       switch (image->colorspace)
   1667       {
   1668         case Rec601YCbCrColorspace:
   1669         case Rec709YCbCrColorspace:
   1670         case YCbCrColorspace:
   1671         {
   1672           dpx.image.image_element[i].descriptor=CbYCr444ComponentType;
   1673           if (image->alpha_trait != UndefinedPixelTrait)
   1674             dpx.image.image_element[i].descriptor=CbYCrA4444ComponentType;
   1675           break;
   1676         }
   1677         default:
   1678         {
   1679           dpx.image.image_element[i].descriptor=RGBComponentType;
   1680           if (image->alpha_trait != UndefinedPixelTrait)
   1681             dpx.image.image_element[i].descriptor=RGBAComponentType;
   1682           if ((image_info->type != TrueColorType) &&
   1683               (image->alpha_trait == UndefinedPixelTrait) &&
   1684               (SetImageGray(image,exception) != MagickFalse))
   1685             dpx.image.image_element[i].descriptor=LumaComponentType;
   1686           break;
   1687         }
   1688       }
   1689     offset+=WriteBlobByte(image,dpx.image.image_element[i].descriptor);
   1690     dpx.image.image_element[i].transfer_characteristic=0;
   1691     if (image->colorspace == LogColorspace)
   1692       dpx.image.image_element[0].transfer_characteristic=
   1693         PrintingDensityColorimetric;
   1694     offset+=WriteBlobByte(image,
   1695       dpx.image.image_element[i].transfer_characteristic);
   1696     dpx.image.image_element[i].colorimetric=0;
   1697     offset+=WriteBlobByte(image,dpx.image.image_element[i].colorimetric);
   1698     dpx.image.image_element[i].bit_size=0;
   1699     if (i == 0)
   1700       dpx.image.image_element[i].bit_size=(unsigned char) image->depth;
   1701     offset+=WriteBlobByte(image,dpx.image.image_element[i].bit_size);
   1702     dpx.image.image_element[i].packing=0;
   1703     if ((image->depth == 10) || (image->depth == 12))
   1704       dpx.image.image_element[i].packing=1;
   1705     offset+=WriteBlobShort(image,dpx.image.image_element[i].packing);
   1706     dpx.image.image_element[i].encoding=0;
   1707     offset+=WriteBlobShort(image,dpx.image.image_element[i].encoding);
   1708     dpx.image.image_element[i].data_offset=0U;
   1709     if (i == 0)
   1710       dpx.image.image_element[i].data_offset=dpx.file.image_offset;
   1711     offset+=WriteBlobLong(image,dpx.image.image_element[i].data_offset);
   1712     dpx.image.image_element[i].end_of_line_padding=0U;
   1713     offset+=WriteBlobLong(image,dpx.image.image_element[i].end_of_line_padding);
   1714     offset+=WriteBlobLong(image,
   1715       dpx.image.image_element[i].end_of_image_padding);
   1716     offset+=WriteBlob(image,sizeof(dpx.image.image_element[i].description),
   1717       (unsigned char *) dpx.image.image_element[i].description);
   1718   }
   1719   offset+=WriteBlob(image,sizeof(dpx.image.reserve),(unsigned char *)
   1720     dpx.image.reserve);
   1721   /*
   1722     Write orientation header.
   1723   */
   1724   if ((image->rows != image->magick_rows) ||
   1725       (image->columns != image->magick_columns))
   1726     {
   1727       /*
   1728         These properties are not valid if image size changed.
   1729       */
   1730       (void) DeleteImageProperty(image,"dpx:orientation.x_offset");
   1731       (void) DeleteImageProperty(image,"dpx:orientation.y_offset");
   1732       (void) DeleteImageProperty(image,"dpx:orientation.x_center");
   1733       (void) DeleteImageProperty(image,"dpx:orientation.y_center");
   1734       (void) DeleteImageProperty(image,"dpx:orientation.x_size");
   1735       (void) DeleteImageProperty(image,"dpx:orientation.y_size");
   1736     }
   1737   dpx.orientation.x_offset=0U;
   1738   value=GetDPXProperty(image,"dpx:orientation.x_offset",exception);
   1739   if (value != (const char *) NULL)
   1740     dpx.orientation.x_offset=(unsigned int) StringToUnsignedLong(value);
   1741   offset+=WriteBlobLong(image,dpx.orientation.x_offset);
   1742   dpx.orientation.y_offset=0U;
   1743   value=GetDPXProperty(image,"dpx:orientation.y_offset",exception);
   1744   if (value != (const char *) NULL)
   1745     dpx.orientation.y_offset=(unsigned int) StringToUnsignedLong(value);
   1746   offset+=WriteBlobLong(image,dpx.orientation.y_offset);
   1747   dpx.orientation.x_center=0.0f;
   1748   value=GetDPXProperty(image,"dpx:orientation.x_center",exception);
   1749   if (value != (const char *) NULL)
   1750     dpx.orientation.x_center=StringToDouble(value,(char **) NULL);
   1751   offset+=WriteBlobFloat(image,dpx.orientation.x_center);
   1752   dpx.orientation.y_center=0.0f;
   1753   value=GetDPXProperty(image,"dpx:orientation.y_center",exception);
   1754   if (value != (const char *) NULL)
   1755     dpx.orientation.y_center=StringToDouble(value,(char **) NULL);
   1756   offset+=WriteBlobFloat(image,dpx.orientation.y_center);
   1757   dpx.orientation.x_size=0U;
   1758   value=GetDPXProperty(image,"dpx:orientation.x_size",exception);
   1759   if (value != (const char *) NULL)
   1760     dpx.orientation.x_size=(unsigned int) StringToUnsignedLong(value);
   1761   offset+=WriteBlobLong(image,dpx.orientation.x_size);
   1762   dpx.orientation.y_size=0U;
   1763   value=GetDPXProperty(image,"dpx:orientation.y_size",exception);
   1764   if (value != (const char *) NULL)
   1765     dpx.orientation.y_size=(unsigned int) StringToUnsignedLong(value);
   1766   offset+=WriteBlobLong(image,dpx.orientation.y_size);
   1767   value=GetDPXProperty(image,"dpx:orientation.filename",exception);
   1768   if (value != (const char *) NULL)
   1769     (void) strncpy(dpx.orientation.filename,value,
   1770       sizeof(dpx.orientation.filename)-1);
   1771   offset+=WriteBlob(image,sizeof(dpx.orientation.filename),(unsigned char *)
   1772     dpx.orientation.filename);
   1773   offset+=WriteBlob(image,sizeof(dpx.orientation.timestamp),(unsigned char *)
   1774     dpx.orientation.timestamp);
   1775   value=GetDPXProperty(image,"dpx:orientation.device",exception);
   1776   if (value != (const char *) NULL)
   1777     (void) strncpy(dpx.orientation.device,value,
   1778       sizeof(dpx.orientation.device)-1);
   1779   offset+=WriteBlob(image,sizeof(dpx.orientation.device),(unsigned char *)
   1780     dpx.orientation.device);
   1781   value=GetDPXProperty(image,"dpx:orientation.serial",exception);
   1782   if (value != (const char *) NULL)
   1783     (void) strncpy(dpx.orientation.serial,value,
   1784       sizeof(dpx.orientation.serial)-1);
   1785   offset+=WriteBlob(image,sizeof(dpx.orientation.serial),(unsigned char *)
   1786     dpx.orientation.serial);
   1787   for (i=0; i < 4; i++)
   1788     dpx.orientation.border[i]=0;
   1789   value=GetDPXProperty(image,"dpx:orientation.border",exception);
   1790   if (value != (const char *) NULL)
   1791     {
   1792       flags=ParseGeometry(value,&geometry_info);
   1793       if ((flags & SigmaValue) == 0)
   1794         geometry_info.sigma=geometry_info.rho;
   1795       dpx.orientation.border[0]=(unsigned short) (geometry_info.rho+0.5);
   1796       dpx.orientation.border[1]=(unsigned short) (geometry_info.sigma+0.5);
   1797       dpx.orientation.border[2]=(unsigned short) (geometry_info.xi+0.5);
   1798       dpx.orientation.border[3]=(unsigned short) (geometry_info.psi+0.5);
   1799     }
   1800   for (i=0; i < 4; i++)
   1801     offset+=WriteBlobShort(image,dpx.orientation.border[i]);
   1802   for (i=0; i < 2; i++)
   1803     dpx.orientation.aspect_ratio[i]=0U;
   1804   value=GetDPXProperty(image,"dpx:orientation.aspect_ratio",exception);
   1805   if (value != (const char *) NULL)
   1806     {
   1807       flags=ParseGeometry(value,&geometry_info);
   1808       if ((flags & SigmaValue) == 0)
   1809         geometry_info.sigma=geometry_info.rho;
   1810       dpx.orientation.aspect_ratio[0]=(unsigned int) (geometry_info.rho+0.5);
   1811       dpx.orientation.aspect_ratio[1]=(unsigned int) (geometry_info.sigma+0.5);
   1812     }
   1813   for (i=0; i < 2; i++)
   1814     offset+=WriteBlobLong(image,dpx.orientation.aspect_ratio[i]);
   1815   offset+=WriteBlob(image,sizeof(dpx.orientation.reserve),(unsigned char *)
   1816     dpx.orientation.reserve);
   1817   /*
   1818     Write film header.
   1819   */
   1820   (void) memset(dpx.film.id,0,sizeof(dpx.film.id));
   1821   value=GetDPXProperty(image,"dpx:film.id",exception);
   1822   if (value != (const char *) NULL)
   1823     (void) strncpy(dpx.film.id,value,sizeof(dpx.film.id)-1);
   1824   offset+=WriteBlob(image,sizeof(dpx.film.id),(unsigned char *) dpx.film.id);
   1825   (void) memset(dpx.film.type,0,sizeof(dpx.film.type));
   1826   value=GetDPXProperty(image,"dpx:film.type",exception);
   1827   if (value != (const char *) NULL)
   1828     (void) strncpy(dpx.film.type,value,sizeof(dpx.film.type)-1);
   1829   offset+=WriteBlob(image,sizeof(dpx.film.type),(unsigned char *)
   1830     dpx.film.type);
   1831   (void) memset(dpx.film.offset,0,sizeof(dpx.film.offset));
   1832   value=GetDPXProperty(image,"dpx:film.offset",exception);
   1833   if (value != (const char *) NULL)
   1834     (void) strncpy(dpx.film.offset,value,sizeof(dpx.film.offset)-1);
   1835   offset+=WriteBlob(image,sizeof(dpx.film.offset),(unsigned char *)
   1836     dpx.film.offset);
   1837   (void) memset(dpx.film.prefix,0,sizeof(dpx.film.prefix));
   1838   value=GetDPXProperty(image,"dpx:film.prefix",exception);
   1839   if (value != (const char *) NULL)
   1840     (void) strncpy(dpx.film.prefix,value,sizeof(dpx.film.prefix)-1);
   1841   offset+=WriteBlob(image,sizeof(dpx.film.prefix),(unsigned char *)
   1842     dpx.film.prefix);
   1843   (void) memset(dpx.film.count,0,sizeof(dpx.film.count));
   1844   value=GetDPXProperty(image,"dpx:film.count",exception);
   1845   if (value != (const char *) NULL)
   1846     (void) strncpy(dpx.film.count,value,sizeof(dpx.film.count)-1);
   1847   offset+=WriteBlob(image,sizeof(dpx.film.count),(unsigned char *)
   1848     dpx.film.count);
   1849   (void) memset(dpx.film.format,0,sizeof(dpx.film.format));
   1850   value=GetDPXProperty(image,"dpx:film.format",exception);
   1851   if (value != (const char *) NULL)
   1852     (void) strncpy(dpx.film.format,value,sizeof(dpx.film.format)-1);
   1853   offset+=WriteBlob(image,sizeof(dpx.film.format),(unsigned char *)
   1854     dpx.film.format);
   1855   dpx.film.frame_position=0U;
   1856   value=GetDPXProperty(image,"dpx:film.frame_position",exception);
   1857   if (value != (const char *) NULL)
   1858     dpx.film.frame_position=(unsigned int) StringToUnsignedLong(value);
   1859   offset+=WriteBlobLong(image,dpx.film.frame_position);
   1860   dpx.film.sequence_extent=0U;
   1861   value=GetDPXProperty(image,"dpx:film.sequence_extent",exception);
   1862   if (value != (const char *) NULL)
   1863     dpx.film.sequence_extent=(unsigned int) StringToUnsignedLong(value);
   1864   offset+=WriteBlobLong(image,dpx.film.sequence_extent);
   1865   dpx.film.held_count=0U;
   1866   value=GetDPXProperty(image,"dpx:film.held_count",exception);
   1867   if (value != (const char *) NULL)
   1868     dpx.film.held_count=(unsigned int) StringToUnsignedLong(value);
   1869   offset+=WriteBlobLong(image,dpx.film.held_count);
   1870   dpx.film.frame_rate=0.0f;
   1871   value=GetDPXProperty(image,"dpx:film.frame_rate",exception);
   1872   if (value != (const char *) NULL)
   1873     dpx.film.frame_rate=StringToDouble(value,(char **) NULL);
   1874   offset+=WriteBlobFloat(image,dpx.film.frame_rate);
   1875   dpx.film.shutter_angle=0.0f;
   1876   value=GetDPXProperty(image,"dpx:film.shutter_angle",exception);
   1877   if (value != (const char *) NULL)
   1878     dpx.film.shutter_angle=StringToDouble(value,(char **) NULL);
   1879   offset+=WriteBlobFloat(image,dpx.film.shutter_angle);
   1880   (void) memset(dpx.film.frame_id,0,sizeof(dpx.film.frame_id));
   1881   value=GetDPXProperty(image,"dpx:film.frame_id",exception);
   1882   if (value != (const char *) NULL)
   1883     (void) strncpy(dpx.film.frame_id,value,sizeof(dpx.film.frame_id)-1);
   1884   offset+=WriteBlob(image,sizeof(dpx.film.frame_id),(unsigned char *)
   1885     dpx.film.frame_id);
   1886   value=GetDPXProperty(image,"dpx:film.slate",exception);
   1887   if (value != (const char *) NULL)
   1888     (void) strncpy(dpx.film.slate,value,sizeof(dpx.film.slate)-1);
   1889   offset+=WriteBlob(image,sizeof(dpx.film.slate),(unsigned char *)
   1890     dpx.film.slate);
   1891   offset+=WriteBlob(image,sizeof(dpx.film.reserve),(unsigned char *)
   1892     dpx.film.reserve);
   1893   /*
   1894     Write television header.
   1895   */
   1896   value=GetDPXProperty(image,"dpx:television.time.code",exception);
   1897   if (value != (const char *) NULL)
   1898     dpx.television.time_code=StringToTimeCode(value);
   1899   offset+=WriteBlobLong(image,dpx.television.time_code);
   1900   value=GetDPXProperty(image,"dpx:television.user.bits",exception);
   1901   if (value != (const char *) NULL)
   1902     dpx.television.user_bits=StringToTimeCode(value);
   1903   offset+=WriteBlobLong(image,dpx.television.user_bits);
   1904   value=GetDPXProperty(image,"dpx:television.interlace",exception);
   1905   if (value != (const char *) NULL)
   1906     dpx.television.interlace=(unsigned char) StringToLong(value);
   1907   offset+=WriteBlobByte(image,dpx.television.interlace);
   1908   value=GetDPXProperty(image,"dpx:television.field_number",exception);
   1909   if (value != (const char *) NULL)
   1910     dpx.television.field_number=(unsigned char) StringToLong(value);
   1911   offset+=WriteBlobByte(image,dpx.television.field_number);
   1912   dpx.television.video_signal=0;
   1913   value=GetDPXProperty(image,"dpx:television.video_signal",exception);
   1914   if (value != (const char *) NULL)
   1915     dpx.television.video_signal=(unsigned char) StringToLong(value);
   1916   offset+=WriteBlobByte(image,dpx.television.video_signal);
   1917   dpx.television.padding=0;
   1918   value=GetDPXProperty(image,"dpx:television.padding",exception);
   1919   if (value != (const char *) NULL)
   1920     dpx.television.padding=(unsigned char) StringToLong(value);
   1921   offset+=WriteBlobByte(image,dpx.television.padding);
   1922   dpx.television.horizontal_sample_rate=0.0f;
   1923   value=GetDPXProperty(image,"dpx:television.horizontal_sample_rate",
   1924     exception);
   1925   if (value != (const char *) NULL)
   1926     dpx.television.horizontal_sample_rate=StringToDouble(value,(char **) NULL);
   1927   offset+=WriteBlobFloat(image,dpx.television.horizontal_sample_rate);
   1928   dpx.television.vertical_sample_rate=0.0f;
   1929   value=GetDPXProperty(image,"dpx:television.vertical_sample_rate",exception);
   1930   if (value != (const char *) NULL)
   1931     dpx.television.vertical_sample_rate=StringToDouble(value,(char **) NULL);
   1932   offset+=WriteBlobFloat(image,dpx.television.vertical_sample_rate);
   1933   dpx.television.frame_rate=0.0f;
   1934   value=GetDPXProperty(image,"dpx:television.frame_rate",exception);
   1935   if (value != (const char *) NULL)
   1936     dpx.television.frame_rate=StringToDouble(value,(char **) NULL);
   1937   offset+=WriteBlobFloat(image,dpx.television.frame_rate);
   1938   dpx.television.time_offset=0.0f;
   1939   value=GetDPXProperty(image,"dpx:television.time_offset",exception);
   1940   if (value != (const char *) NULL)
   1941     dpx.television.time_offset=StringToDouble(value,(char **) NULL);
   1942   offset+=WriteBlobFloat(image,dpx.television.time_offset);
   1943   dpx.television.gamma=0.0f;
   1944   value=GetDPXProperty(image,"dpx:television.gamma",exception);
   1945   if (value != (const char *) NULL)
   1946     dpx.television.gamma=StringToDouble(value,(char **) NULL);
   1947   offset+=WriteBlobFloat(image,dpx.television.gamma);
   1948   dpx.television.black_level=0.0f;
   1949   value=GetDPXProperty(image,"dpx:television.black_level",exception);
   1950   if (value != (const char *) NULL)
   1951     dpx.television.black_level=StringToDouble(value,(char **) NULL);
   1952   offset+=WriteBlobFloat(image,dpx.television.black_level);
   1953   dpx.television.black_gain=0.0f;
   1954   value=GetDPXProperty(image,"dpx:television.black_gain",exception);
   1955   if (value != (const char *) NULL)
   1956     dpx.television.black_gain=StringToDouble(value,(char **) NULL);
   1957   offset+=WriteBlobFloat(image,dpx.television.black_gain);
   1958   dpx.television.break_point=0.0f;
   1959   value=GetDPXProperty(image,"dpx:television.break_point",exception);
   1960   if (value != (const char *) NULL)
   1961     dpx.television.break_point=StringToDouble(value,(char **) NULL);
   1962   offset+=WriteBlobFloat(image,dpx.television.break_point);
   1963   dpx.television.white_level=0.0f;
   1964   value=GetDPXProperty(image,"dpx:television.white_level",exception);
   1965   if (value != (const char *) NULL)
   1966     dpx.television.white_level=StringToDouble(value,(char **) NULL);
   1967   offset+=WriteBlobFloat(image,dpx.television.white_level);
   1968   dpx.television.integration_times=0.0f;
   1969   value=GetDPXProperty(image,"dpx:television.integration_times",exception);
   1970   if (value != (const char *) NULL)
   1971     dpx.television.integration_times=StringToDouble(value,(char **) NULL);
   1972   offset+=WriteBlobFloat(image,dpx.television.integration_times);
   1973   offset+=WriteBlob(image,sizeof(dpx.television.reserve),(unsigned char *)
   1974     dpx.television.reserve);
   1975   /*
   1976     Write user header.
   1977   */
   1978   value=GetDPXProperty(image,"dpx:user.id",exception);
   1979   if (value != (const char *) NULL)
   1980     (void) strncpy(dpx.user.id,value,sizeof(dpx.user.id)-1);
   1981   offset+=WriteBlob(image,sizeof(dpx.user.id),(unsigned char *) dpx.user.id);
   1982   if (profile != (StringInfo *) NULL)
   1983     offset+=WriteBlob(image,GetStringInfoLength(profile),
   1984       GetStringInfoDatum(profile));
   1985   while (offset < (MagickOffsetType) dpx.image.image_element[0].data_offset)
   1986   {
   1987     count=WriteBlobByte(image,0x00);
   1988     if (count != 1)
   1989       {
   1990         ThrowFileException(exception,FileOpenError,"UnableToWriteFile",
   1991           image->filename);
   1992         break;
   1993       }
   1994     offset+=count;
   1995   }
   1996   /*
   1997     Convert pixel packets to DPX raster image.
   1998   */
   1999   quantum_info=AcquireQuantumInfo(image_info,image);
   2000   if (quantum_info == (QuantumInfo *) NULL)
   2001     ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
   2002   SetQuantumQuantum(quantum_info,32);
   2003   SetQuantumPack(quantum_info,dpx.image.image_element[0].packing == 0 ?
   2004     MagickTrue : MagickFalse);
   2005   quantum_type=RGBQuantum;
   2006   if (image->alpha_trait != UndefinedPixelTrait)
   2007     quantum_type=RGBAQuantum;
   2008   if (image->colorspace == YCbCrColorspace)
   2009     {
   2010       quantum_type=CbYCrQuantum;
   2011       if (image->alpha_trait != UndefinedPixelTrait)
   2012         quantum_type=CbYCrAQuantum;
   2013       if ((horizontal_factor == 2) || (vertical_factor == 2))
   2014         quantum_type=CbYCrYQuantum;
   2015     }
   2016   extent=GetBytesPerRow(image->columns,
   2017     image->alpha_trait != UndefinedPixelTrait ? 4UL : 3UL,image->depth,
   2018     dpx.image.image_element[0].packing == 0 ? MagickFalse : MagickTrue);
   2019   if ((image_info->type != TrueColorType) &&
   2020       (image->alpha_trait == UndefinedPixelTrait) &&
   2021       (SetImageGray(image,exception) != MagickFalse))
   2022     {
   2023       quantum_type=GrayQuantum;
   2024       extent=GetBytesPerRow(image->columns,1UL,image->depth,
   2025         dpx.image.image_element[0].packing == 0 ? MagickFalse : MagickTrue);
   2026     }
   2027   pixels=(unsigned char *) GetQuantumPixels(quantum_info);
   2028   for (y=0; y < (ssize_t) image->rows; y++)
   2029   {
   2030     p=GetVirtualPixels(image,0,y,image->columns,1,exception);
   2031     if (p == (const Quantum *) NULL)
   2032       break;
   2033     (void) ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
   2034       quantum_type,pixels,exception);
   2035     count=WriteBlob(image,extent,pixels);
   2036     if (count != (ssize_t) extent)
   2037       break;
   2038     status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
   2039       image->rows);
   2040     if (status == MagickFalse)
   2041       break;
   2042   }
   2043   quantum_info=DestroyQuantumInfo(quantum_info);
   2044   (void) CloseBlob(image);
   2045   return(status);
   2046 }
   2047