]> granicus.if.org Git - imagemagick/blob - coders/psd.c
(no commit message)
[imagemagick] / coders / psd.c
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %                                                                             %
4 %                                                                             %
5 %                                                                             %
6 %                            PPPP   SSSSS  DDDD                               %
7 %                            P   P  SS     D   D                              %
8 %                            PPPP    SSS   D   D                              %
9 %                            P         SS  D   D                              %
10 %                            P      SSSSS  DDDD                               %
11 %                                                                             %
12 %                                                                             %
13 %                   Read/Write Adobe Photoshop Image Format                   %
14 %                                                                             %
15 %                              Software Design                                %
16 %                                John Cristy                                  %
17 %                              Leonard Rosenthol                              %
18 %                                 July 1992                                   %
19 %                                                                             %
20 %                                                                             %
21 %  Copyright 1999-2010 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 \f
40 /*
41   Include declarations.
42 */
43 #include "magick/studio.h"
44 #include "magick/artifact.h"
45 #include "magick/blob.h"
46 #include "magick/blob-private.h"
47 #include "magick/cache.h"
48 #include "magick/colorspace.h"
49 #include "magick/constitute.h"
50 #include "magick/enhance.h"
51 #include "magick/exception.h"
52 #include "magick/exception-private.h"
53 #include "magick/image.h"
54 #include "magick/image-private.h"
55 #include "magick/list.h"
56 #include "magick/log.h"
57 #include "magick/magick.h"
58 #include "magick/memory_.h"
59 #include "magick/module.h"
60 #include "magick/monitor-private.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 \f
67 /*
68   Define declaractions.
69 */
70 #define MaxPSDChannels  56
71 #define PSDQuantum(x) (((long) (x)+1) & -2)
72 \f
73 /*
74   Enumerated declaractions.
75 */
76 typedef enum
77 {
78   BitmapMode = 0,
79   GrayscaleMode = 1,
80   IndexedMode = 2,
81   RGBMode = 3,
82   CMYKMode = 4,
83   MultichannelMode = 7,
84   DuotoneMode = 8,
85   LabMode = 9
86 } PSDImageType;
87 \f
88 /*
89   Typedef declaractions.
90 */
91 typedef struct _ChannelInfo
92 {
93   short int
94     type;
95
96   unsigned long
97     size;
98 } ChannelInfo;
99
100 typedef struct _LayerInfo
101 {
102   RectangleInfo
103     page,
104     mask;
105
106   unsigned short
107     channels;
108
109   ChannelInfo
110     channel_info[MaxPSDChannels];
111
112   char
113     blendkey[4];
114
115   Quantum
116     opacity;
117
118   unsigned char
119     clipping,
120     visible,
121     flags;
122
123   unsigned long
124     offset_x,
125     offset_y;
126
127   unsigned char
128     name[256];
129
130   Image
131     *image;
132 } LayerInfo;
133
134 typedef struct _PSDInfo
135 {
136   char
137     signature[4];
138
139   unsigned short
140     channels,
141     version;
142
143   unsigned char
144     reserved[6];
145
146   unsigned long
147     rows,
148     columns;
149
150   unsigned short
151     depth,
152     mode;
153 } PSDInfo;
154 \f
155 /*
156   Forward declarations.
157 */
158 static MagickBooleanType
159   WritePSDImage(const ImageInfo *,Image *);
160 \f
161 /*
162 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
163 %                                                                             %
164 %                                                                             %
165 %                                                                             %
166 %   I s P S D                                                                 %
167 %                                                                             %
168 %                                                                             %
169 %                                                                             %
170 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
171 %
172 %  IsPSD()() returns MagickTrue if the image format type, identified by the
173 %  magick string, is PSD.
174 %
175 %  The format of the IsPSD method is:
176 %
177 %      MagickBooleanType IsPSD(const unsigned char *magick,const size_t length)
178 %
179 %  A description of each parameter follows:
180 %
181 %    o magick: compare image format pattern against these bytes.
182 %
183 %    o length: Specifies the length of the magick string.
184 %
185 */
186 static MagickBooleanType IsPSD(const unsigned char *magick,const size_t length)
187 {
188   if (length < 4)
189     return(MagickFalse);
190   if (LocaleNCompare((const char *) magick,"8BPS",4) == 0)
191     return(MagickTrue);
192   return(MagickFalse);
193 }
194 \f
195 /*
196 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
197 %                                                                             %
198 %                                                                             %
199 %                                                                             %
200 %   R e a d P S D I m a g e                                                   %
201 %                                                                             %
202 %                                                                             %
203 %                                                                             %
204 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
205 %
206 %  ReadPSDImage() reads an Adobe Photoshop image file and returns it.  It
207 %  allocates the memory necessary for the new Image structure and returns a
208 %  pointer to the new image.
209 %
210 %  The format of the ReadPSDImage method is:
211 %
212 %      Image *ReadPSDImage(image_info)
213 %
214 %  A description of each parameter follows:
215 %
216 %    o image_info: the image info.
217 %
218 %    o exception: return any errors or warnings in this structure.
219 %
220 */
221
222 static const char *CompositeOperatorToPSDBlendMode(CompositeOperator operator)
223 {
224   const char
225     *blend_mode;
226
227   switch (operator)
228   {
229     case OverCompositeOp:    blend_mode = "norm";  break;
230     case MultiplyCompositeOp:  blend_mode = "mul ";  break;
231     case DissolveCompositeOp:  blend_mode = "diss";  break;
232     case DifferenceCompositeOp:  blend_mode = "diff";  break;
233     case DarkenCompositeOp:    blend_mode = "dark";  break;
234     case LightenCompositeOp:  blend_mode = "lite";  break;
235     case HueCompositeOp:    blend_mode = "hue ";  break;
236     case SaturateCompositeOp:  blend_mode = "sat ";  break;
237     case ColorizeCompositeOp:  blend_mode = "colr";  break;
238     case LuminizeCompositeOp:  blend_mode = "lum ";  break;
239     case ScreenCompositeOp:    blend_mode = "scrn";  break;
240     case OverlayCompositeOp:  blend_mode = "over";  break;
241     default:
242       blend_mode = "norm";
243   }
244   return(blend_mode);
245 }
246
247 static ssize_t DecodePSDPixels(const size_t number_compact_pixels,
248   const unsigned char *compact_pixels,const long depth,
249   const size_t number_pixels,unsigned char *pixels)
250 {
251   int
252     pixel;
253
254   register ssize_t
255     i,
256     j;
257
258   ssize_t
259     packets;
260
261   size_t
262     length;
263
264   packets=(ssize_t) number_compact_pixels;
265   for (i=0; (packets > 1) && (i < (ssize_t) number_pixels); )
266   {
267     length=(*compact_pixels++);
268     packets--;
269     if (length == 128)
270       continue;
271     if (length > 128)
272       {
273         length=256-length+1;
274         pixel=(*compact_pixels++);
275         packets--;
276         for (j=0; j < (long) length; j++)
277         {
278           switch (depth)
279           {
280             case 1:
281             {
282               *pixels++=(pixel >> 7) & 0x01 ? 0 : 255;
283               *pixels++=(pixel >> 6) & 0x01 ? 0 : 255;
284               *pixels++=(pixel >> 5) & 0x01 ? 0 : 255;
285               *pixels++=(pixel >> 4) & 0x01 ? 0 : 255;
286               *pixels++=(pixel >> 3) & 0x01 ? 0 : 255;
287               *pixels++=(pixel >> 2) & 0x01 ? 0 : 255;
288               *pixels++=(pixel >> 1) & 0x01 ? 0 : 255;
289               *pixels++=(pixel >> 0) & 0x01 ? 0 : 255;
290               i+=8;
291               break;
292             }
293             case 4:
294             {
295               *pixels++=(pixel >> 4) & 0xff;
296               *pixels++=(pixel & 0x0f) & 0xff;
297               i+=2;
298               break;
299             }
300             case 2:
301             {
302               *pixels++=(pixel >> 6) & 0x03;
303               *pixels++=(pixel >> 4) & 0x03;
304               *pixels++=(pixel >> 2) & 0x03;
305               *pixels++=(pixel & 0x03) & 0x03;
306               i+=4;
307               break;
308             }
309             default:
310             {
311               *pixels++=pixel;
312               i++;
313               break;
314             }
315           }
316         }
317         continue;
318       }
319     length++;
320     for (j=0; j < (long) length; j++)
321     {
322       switch (depth)
323       {
324         case 1:
325         {
326           *pixels++=(*compact_pixels >> 7) & 0x01 ? 0 : 255;
327           *pixels++=(*compact_pixels >> 6) & 0x01 ? 0 : 255;
328           *pixels++=(*compact_pixels >> 5) & 0x01 ? 0 : 255;
329           *pixels++=(*compact_pixels >> 4) & 0x01 ? 0 : 255;
330           *pixels++=(*compact_pixels >> 3) & 0x01 ? 0 : 255;
331           *pixels++=(*compact_pixels >> 2) & 0x01 ? 0 : 255;
332           *pixels++=(*compact_pixels >> 1) & 0x01 ? 0 : 255;
333           *pixels++=(*compact_pixels >> 0) & 0x01 ? 0 : 255;
334           i+=8;
335           break;
336         }
337         case 4:
338         {
339           *pixels++=(*compact_pixels >> 4) & 0xff;
340           *pixels++=(*compact_pixels & 0x0f) & 0xff;
341           i+=2;
342           break;
343         }
344         case 2:
345         {
346           *pixels++=(*compact_pixels >> 6) & 0x03;
347           *pixels++=(*compact_pixels >> 4) & 0x03;
348           *pixels++=(*compact_pixels >> 2) & 0x03;
349           *pixels++=(*compact_pixels & 0x03) & 0x03;
350           i+=4;
351           break;
352         }
353         default:
354         {
355           *pixels++=(*compact_pixels);
356           i++;
357           break;
358         }
359       }
360       compact_pixels++;
361     }
362   }
363   return(i);
364 }
365
366 static inline MagickOffsetType GetPSDOffset(PSDInfo *psd_info,Image *image)
367 {
368   if (psd_info->version == 1)
369     return((MagickOffsetType) ReadBlobMSBShort(image));
370   return((MagickOffsetType) ReadBlobMSBLong(image));
371 }
372
373 static inline MagickSizeType GetPSDSize(PSDInfo *psd_info,Image *image)
374 {
375   if (psd_info->version == 1)
376     return((MagickSizeType) ReadBlobMSBLong(image));
377   return((MagickSizeType) ReadBlobMSBLongLong(image));
378 }
379
380 static inline long MagickAbsoluteValue(const long x)
381 {
382   if (x < 0)
383     return(-x);
384   return(x);
385 }
386
387 static const char *ModeToString(PSDImageType type)
388 {
389   switch (type)
390   {
391     case BitmapMode: return "Bitmap";
392     case GrayscaleMode: return "Grayscale";
393     case IndexedMode: return "Indexed";
394     case RGBMode: return "RGB";
395     case CMYKMode:  return "CMYK";
396     case MultichannelMode: return "Multichannel";
397     case DuotoneMode: return "Duotone";
398     case LabMode: return "L*A*B";
399     default: return "unknown";
400   }
401 }
402
403 static MagickBooleanType ParseImageResourceBlocks(Image *image,
404   const unsigned char *blocks,size_t length)
405 {
406   const unsigned char
407     *p;
408
409   StringInfo
410     *profile;
411
412   unsigned long
413     count,
414     long_sans;
415
416   unsigned short
417     id,
418     short_sans;
419
420   if (length < 16)
421     return(MagickFalse);
422   profile=AcquireStringInfo(length);
423   SetStringInfoDatum(profile,blocks);
424   (void) SetImageProfile(image,"8bim",profile);
425   profile=DestroyStringInfo(profile);
426   for (p=blocks; (p >= blocks) && (p < (blocks+length-16)); )
427   {
428     if (LocaleNCompare((const char *) p,"8BIM",4) != 0)
429       break;
430     p=PushLongPixel(LSBEndian,p,&long_sans);
431     p=PushShortPixel(LSBEndian,p,&id);
432     p=PushShortPixel(LSBEndian,p,&short_sans);
433     p=PushLongPixel(LSBEndian,p,&count);
434     switch (id)
435     {
436       case 0x03ed:
437       {
438         unsigned short
439           resolution;
440
441         /*
442           Resolution info.
443         */
444         p=PushShortPixel(LSBEndian,p,&resolution);
445         image->x_resolution=(double) resolution;
446         p=PushShortPixel(LSBEndian,p,&short_sans);
447         p=PushShortPixel(LSBEndian,p,&short_sans);
448         p=PushShortPixel(LSBEndian,p,&short_sans);
449         p=PushShortPixel(LSBEndian,p,&resolution);
450         image->y_resolution=(double) resolution;
451         p=PushShortPixel(LSBEndian,p,&short_sans);
452         p=PushShortPixel(LSBEndian,p,&short_sans);
453         p=PushShortPixel(LSBEndian,p,&short_sans);
454         break;
455       }
456       default:
457       {
458         p+=count;
459         break;
460       }
461     }
462     if ((count & 0x01) != 0)
463       p++;
464   }
465   return(MagickTrue);
466 }
467
468 static CompositeOperator PSDBlendModeToCompositeOperator(const char *mode)
469 {
470   if (mode == (const char *) NULL)
471     return(OverCompositeOp);
472   if (LocaleNCompare(mode,"norm",4) == 0)
473     return(OverCompositeOp);
474   if (LocaleNCompare(mode,"mul ",4) == 0)
475     return(MultiplyCompositeOp);
476   if (LocaleNCompare(mode,"diss",4) == 0)
477     return(DissolveCompositeOp);
478   if (LocaleNCompare(mode,"diff",4) == 0)
479     return(DifferenceCompositeOp);
480   if (LocaleNCompare(mode,"dark",4) == 0)
481     return(DarkenCompositeOp);
482   if (LocaleNCompare(mode,"lite",4) == 0)
483     return(LightenCompositeOp);
484   if (LocaleNCompare(mode,"hue ",4) == 0)
485     return(HueCompositeOp);
486   if (LocaleNCompare(mode,"sat ",4) == 0)
487     return(SaturateCompositeOp);
488   if (LocaleNCompare(mode,"colr",4) == 0)
489     return(ColorizeCompositeOp);
490   if (LocaleNCompare(mode,"lum ",4) == 0)
491     return(LuminizeCompositeOp);
492   if (LocaleNCompare(mode,"scrn",4) == 0)
493     return(ScreenCompositeOp);
494   if (LocaleNCompare(mode,"over",4) == 0)
495     return(OverlayCompositeOp);
496   if (LocaleNCompare(mode,"hLit",4) == 0)
497     return(OverCompositeOp);
498   if (LocaleNCompare(mode,"sLit",4) == 0)
499     return(OverCompositeOp);
500   if (LocaleNCompare(mode,"smud",4) == 0)
501     return(OverCompositeOp);
502   if (LocaleNCompare(mode,"div ",4) == 0)
503     return(OverCompositeOp);
504   if (LocaleNCompare(mode,"idiv",4) == 0)
505     return(OverCompositeOp);
506   return(OverCompositeOp);
507 }
508
509 static MagickBooleanType ReadPSDLayer(Image *image,
510   const unsigned long channels,const unsigned long type,
511   const MagickOffsetType *offsets,ExceptionInfo *exception)
512 {
513   long
514     y;
515
516   Quantum
517     pixel;
518
519   register IndexPacket
520     *indexes;
521
522   register long
523     x;
524
525   register PixelPacket
526     *q;
527
528   register const unsigned char
529     *p;
530
531   size_t
532     packet_size;
533
534   ssize_t
535     count;
536
537   unsigned char
538     *compact_pixels,
539     *pixels;
540
541   unsigned short
542     nibble;
543
544   packet_size=1;
545   if (image->storage_class == PseudoClass)
546     {
547       if (image->colors > 256)
548         packet_size++;
549       else
550         if (image->depth > 8)
551           packet_size++;
552     }
553   else
554     if (image->depth > 8)
555       packet_size++;
556   pixels=(unsigned char *) AcquireQuantumMemory(image->columns+256,packet_size*
557     sizeof(*pixels));
558   if (pixels == (unsigned char *) NULL)
559     ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
560       image->filename);
561   (void) ResetMagickMemory(pixels,0,image->columns*packet_size*sizeof(*pixels));
562   compact_pixels=(unsigned char *) NULL;
563   if (image->compression == RLECompression)
564     {
565       size_t
566         length;
567
568       length=0;
569       for (y=0; y < (long) image->rows; y++)
570         if ((MagickOffsetType) length < offsets[y])
571           length=offsets[y];
572       compact_pixels=(unsigned char *) AcquireQuantumMemory(length,
573         sizeof(*pixels));
574       if (compact_pixels == (unsigned char *) NULL)
575         ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
576           image->filename);
577       (void) ResetMagickMemory(compact_pixels,0,length*sizeof(*compact_pixels));
578     }
579   for (y=0; y < (long) image->rows; y++)
580   {
581     if (image->compression != RLECompression)
582       count=ReadBlob(image,packet_size*image->columns,pixels);
583     else
584       {
585         count=ReadBlob(image,(size_t) offsets[y],compact_pixels);
586         if (count != (ssize_t) offsets[y])
587           break;
588         count=DecodePSDPixels((size_t) offsets[y],compact_pixels,
589           image->depth,packet_size*image->columns,pixels);
590       }
591     if (count < (ssize_t) (packet_size*image->columns))
592       break;
593     q=GetAuthenticPixels(image,0,y,image->columns,1,exception);
594     if (q == (PixelPacket *) NULL)
595       break;
596     indexes=GetAuthenticIndexQueue(image);
597     p=pixels;
598     for (x=0; x < (long) image->columns; x++)
599     {
600       if (packet_size == 1)
601         pixel=ScaleCharToQuantum(*p++);
602       else
603         {
604           p=PushShortPixel(MSBEndian,p,&nibble);
605           pixel=ScaleShortToQuantum(nibble);
606         }
607       switch (type)
608       {
609         case -1:
610         {
611           q->opacity=(Quantum) (QuantumRange-pixel);
612           break;
613         }
614         case 0:
615         {
616           q->red=pixel;
617           if (channels == 1)
618             {
619               q->green=q->red;
620               q->blue=q->red;
621             }
622           if (image->storage_class == PseudoClass)
623             {
624               if (packet_size == 1)
625                 indexes[x]=(IndexPacket) ScaleQuantumToChar(pixel);
626               else
627                 indexes[x]=(IndexPacket) ScaleQuantumToShort(pixel);
628               *q=image->colormap[(long) indexes[x]];
629               q->red=image->colormap[(long) indexes[x]].red;
630               q->green=image->colormap[(long) indexes[x]].green;
631               q->blue=image->colormap[(long) indexes[x]].blue;
632             }
633           break;
634         }
635         case 1:
636         {
637           if (image->storage_class == PseudoClass)
638             q->opacity=(Quantum) (QuantumRange-pixel);
639           else
640             q->green=pixel;
641           break;
642         }
643         case 2:
644         {
645           q->blue=pixel;
646           break;
647         }
648         case 3:
649         {
650           if (image->colorspace == CMYKColorspace)
651             indexes[x]=(IndexPacket) pixel;
652           else
653             q->opacity=(Quantum) (QuantumRange-pixel);
654           break;
655         }
656         case 4:
657         {
658           q->opacity=(Quantum) (QuantumRange-pixel);
659           break;
660         }
661         default:
662           break;
663       }
664       q++;
665     }
666     if (SyncAuthenticPixels(image,exception) == MagickFalse)
667       break;
668   }
669   if (image->compression == RLECompression)
670     compact_pixels=(unsigned char *) RelinquishMagickMemory(compact_pixels);
671   pixels=(unsigned char *) RelinquishMagickMemory(pixels);
672   return(MagickTrue);
673 }
674
675 static Image *ReadPSDImage(const ImageInfo *image_info,ExceptionInfo *exception)
676 {
677   char
678     message[MaxTextExtent],
679     type[4];
680
681   Image
682     *image;
683
684   IndexPacket
685     *indexes;
686
687   LayerInfo
688     *layer_info;
689
690   long
691     j,
692     number_layers,
693     y;
694
695   MagickBooleanType
696     status;
697
698   MagickOffsetType
699     offset,
700     *offsets;
701
702   MagickSizeType
703     combinedlength,
704     length,
705     size;
706
707   PSDInfo
708     psd_info;
709
710   register long
711     i,
712     x;
713
714   register PixelPacket
715     *q;
716
717   ssize_t
718     count;
719
720   unsigned char
721     *data;
722
723   unsigned short
724     compression;
725
726   unsigned long
727     mask_size,
728     skip_first_alpha = 0;
729
730   /*
731     Open image file.
732   */
733   assert(image_info != (const ImageInfo *) NULL);
734   assert(image_info->signature == MagickSignature);
735   if (image_info->debug != MagickFalse)
736     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
737       image_info->filename);
738   assert(exception != (ExceptionInfo *) NULL);
739   assert(exception->signature == MagickSignature);
740   image=AcquireImage(image_info);
741   status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
742   if (status == MagickFalse)
743     {
744       image=DestroyImageList(image);
745       return((Image *) NULL);
746     }
747   /*
748     Read image header.
749   */
750   count=ReadBlob(image,4,(unsigned char *) psd_info.signature);
751   psd_info.version=ReadBlobMSBShort(image);
752   if ((count == 0) || (LocaleNCompare(psd_info.signature,"8BPS",4) != 0) ||
753       ((psd_info.version != 1) && (psd_info.version != 2)))
754     ThrowReaderException(CorruptImageError,"ImproperImageHeader");
755   count=ReadBlob(image,6,psd_info.reserved);
756   psd_info.channels=ReadBlobMSBShort(image);
757   if (psd_info.channels > MaxPSDChannels)
758     ThrowReaderException(CorruptImageError,"MaximumChannelsExceeded");
759   psd_info.rows=ReadBlobMSBLong(image);
760   psd_info.columns=ReadBlobMSBLong(image);
761   if ((psd_info.version == 1) && ((psd_info.rows > 30000) ||
762       (psd_info.columns > 30000)))
763     ThrowReaderException(CorruptImageError,"ImproperImageHeader");
764   psd_info.depth=ReadBlobMSBShort(image);
765   if ((psd_info.depth != 1) && (psd_info.depth != 8) && (psd_info.depth != 16))
766     ThrowReaderException(CorruptImageError,"ImproperImageHeader");
767   psd_info.mode=ReadBlobMSBShort(image);
768   if (image->debug != MagickFalse)
769     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
770       "  Image is %ld x %ld with channels=%d, depth=%d, mode=%s",
771       psd_info.columns,psd_info.rows,psd_info.channels,psd_info.depth,
772       ModeToString((PSDImageType) psd_info.mode));
773   /*
774     Initialize image.
775   */
776   image->depth=psd_info.depth;
777   image->columns=psd_info.columns;
778   image->rows=psd_info.rows;
779   if (SetImageBackgroundColor(image) == MagickFalse)
780     {
781       InheritException(exception,&image->exception);
782       image=DestroyImageList(image);
783       return((Image *) NULL);
784     }
785   image->matte=psd_info.channels >= 4 ? MagickTrue : MagickFalse;
786   if (psd_info.mode == LabMode)
787     image->colorspace=LabColorspace;
788   if (psd_info.mode == CMYKMode)
789     {
790       image->colorspace=CMYKColorspace;
791       image->matte=psd_info.channels >= 5 ? MagickTrue : MagickFalse;
792     }
793   if ((psd_info.mode == BitmapMode) || (psd_info.mode == GrayscaleMode) ||
794       (psd_info.mode == DuotoneMode))
795     {
796       if (AcquireImageColormap(image,256) == MagickFalse)
797         ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
798       image->matte=psd_info.channels >= 2 ? MagickTrue : MagickFalse;
799       if (image->debug != MagickFalse)
800         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
801           "  ImageColorMap allocated");
802       image->colorspace=GRAYColorspace;
803     }
804   if (image->debug != MagickFalse)
805     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
806       image->matte ? "  image has matte" : "  image has no matte");
807   /*
808     Read PSD raster colormap only present for indexed and duotone images.
809   */
810   length=ReadBlobMSBLong(image);
811   if (length != 0)
812     {
813       if (image->debug != MagickFalse)
814         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
815           "  reading colormap");
816       if (psd_info.mode == DuotoneMode)
817         {
818           /*
819             Duotone image data;  the format of this data is undocumented.
820           */
821           data=(unsigned char *) AcquireQuantumMemory((size_t) length,
822             sizeof(*data));
823           if (data == (unsigned char *) NULL)
824             ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
825           count=ReadBlob(image,(size_t) length,data);
826           data=(unsigned char *) RelinquishMagickMemory(data);
827         }
828       else
829         {
830           /*
831             Read PSD raster colormap.
832           */
833           if (AcquireImageColormap(image,(unsigned long) (length/3)) == MagickFalse)
834             ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
835           for (i=0; i < (long) image->colors; i++)
836             image->colormap[i].red=ScaleCharToQuantum((unsigned char)
837               ReadBlobByte(image));
838           for (i=0; i < (long) image->colors; i++)
839             image->colormap[i].green=ScaleCharToQuantum((unsigned char)
840               ReadBlobByte(image));
841           for (i=0; i < (long) image->colors; i++)
842             image->colormap[i].blue=ScaleCharToQuantum((unsigned char)
843               ReadBlobByte(image));
844           image->matte=psd_info.channels >= 2 ? MagickTrue : MagickFalse;
845         }
846     }
847   length=ReadBlobMSBLong(image);
848   if (length != 0)
849     {
850       unsigned char
851         *blocks;
852
853       /*
854         Image resources block.
855       */
856       if (image->debug != MagickFalse)
857         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
858           "  reading image resource blocks - %ld bytes",(long) length);
859       blocks=(unsigned char *) AcquireQuantumMemory((size_t) length,
860         sizeof(*blocks));
861       if (blocks == (unsigned char *) NULL)
862         ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
863       count=ReadBlob(image,(size_t) length,blocks);
864       if ((count != (ssize_t) length) ||
865           (LocaleNCompare((char *) blocks,"8BIM",4) != 0))
866         {
867           blocks=(unsigned char *) RelinquishMagickMemory(blocks);
868           ThrowReaderException(CorruptImageError,"ImproperImageHeader");
869         }
870       (void) ParseImageResourceBlocks(image,blocks,(size_t) length);
871       blocks=(unsigned char *) RelinquishMagickMemory(blocks);
872     }
873   /*
874     If we are only "pinging" the image, then we're done - so return.
875   */
876   if (image_info->ping != MagickFalse)
877     {
878       (void) CloseBlob(image);
879       return(GetFirstImageInList(image));
880     }
881   /*
882     Layer and mask block.
883   */
884   layer_info=(LayerInfo *) NULL;
885   number_layers=1;
886   length=GetPSDSize(&psd_info,image);
887   if (length == 8)
888     {
889       length=ReadBlobMSBLong(image);
890       length=ReadBlobMSBLong(image);
891     }
892   if ((image_info->number_scenes == 1) && (image_info->scene == 0))
893     for ( ; length != 0; length--)
894       if (ReadBlobByte(image) == EOF)
895         {
896           ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
897             image->filename);
898           break;
899         }
900   if (length == 0)
901     {
902       if (image->debug != MagickFalse)
903         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
904           "  image has no layers");
905     }
906   else
907     {
908       offset=TellBlob(image);
909       size=GetPSDSize(&psd_info,image);
910       if (size == 0)
911         {
912           unsigned long
913             quantum;
914
915           /*
916             Skip layers & masks.
917           */
918           quantum=psd_info.version == 1 ? 4UL : 8UL;
919           for (j=0; j < (long) (length-quantum); j++)
920             (void) ReadBlobByte(image);
921         }
922       else
923         {
924           MagickOffsetType
925             layer_offset;
926
927           layer_offset=offset+length;
928           number_layers=(short) ReadBlobMSBShort(image);
929           if (image->debug != MagickFalse)
930             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
931               "  image contains %ld layers", number_layers);
932           if (number_layers < 0)
933             {
934               /*
935                 Weird hack in PSD format to ignore first alpha channel.
936               */
937               skip_first_alpha=1;
938               number_layers=MagickAbsoluteValue(number_layers);
939               if (image->debug != MagickFalse)
940                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
941                   "  negative layer count corrected for");
942             }
943           layer_info=(LayerInfo *) AcquireQuantumMemory((size_t) number_layers,
944             sizeof(*layer_info));
945           if (layer_info == (LayerInfo *) NULL)
946             {
947               if (image->debug != MagickFalse)
948                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
949                   "  allocation of LayerInfo failed");
950               ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
951             }
952           (void) ResetMagickMemory(layer_info,0,(size_t) number_layers*
953             sizeof(*layer_info));
954           for (i=0; i < number_layers; i++)
955           {
956             if (image->debug != MagickFalse)
957               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
958                 "  reading layer #%ld",i+1);
959             layer_info[i].page.y=(long) ReadBlobMSBLong(image);
960             layer_info[i].page.x=(long) ReadBlobMSBLong(image);
961             layer_info[i].page.height=(unsigned long)
962               ReadBlobMSBLong(image)-layer_info[i].page.y;
963             layer_info[i].page.width=(unsigned long)
964               ReadBlobMSBLong(image)-layer_info[i].page.x;
965             layer_info[i].channels=ReadBlobMSBShort(image);
966             if (layer_info[i].channels > MaxPSDChannels)
967               ThrowReaderException(CorruptImageError,"MaximumChannelsExceeded");
968             if (image->debug != MagickFalse)
969               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
970                 "    offset(%ld,%ld), size(%ld,%ld), channels=%d",
971                 layer_info[i].page.x, layer_info[i].page.y,
972                 layer_info[i].page.height,layer_info[i].page.width,
973                 layer_info[i].channels);
974             for (j=0; j < (long) layer_info[i].channels; j++)
975             {
976               layer_info[i].channel_info[j].type=(short)
977                 ReadBlobMSBShort(image);
978               layer_info[i].channel_info[j].size=(unsigned long)
979                 GetPSDSize(&psd_info,image);
980               if (image->debug != MagickFalse)
981                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
982                   "    channel[%ld]: type=%d, size=%ld",j,
983                   layer_info[i].channel_info[j].type,
984               (long) layer_info[i].channel_info[j].size);
985             }
986             count=ReadBlob(image,4,(unsigned char *) type);
987             if ((count == 0) || (LocaleNCompare(type,"8BIM",4) != 0))
988               {
989                 if (image->debug != MagickFalse)
990                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
991                     "  layer type was %.4s instead of 8BIM", type);
992                  ThrowReaderException(CorruptImageError,"ImproperImageHeader");
993               }
994             count=ReadBlob(image,4,(unsigned char *) layer_info[i].blendkey);
995             layer_info[i].opacity=(Quantum) (QuantumRange-ScaleCharToQuantum(
996               (unsigned char) ReadBlobByte(image)));
997             layer_info[i].clipping=(unsigned char) ReadBlobByte(image);
998             layer_info[i].flags=(unsigned char) ReadBlobByte(image);
999             layer_info[i].visible=!(layer_info[i].flags & 0x02);
1000             if (image->debug != MagickFalse)
1001               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1002                 "   blend=%.4s, opacity=%lu, clipping=%s, flags=%d, visible=%s",
1003                 layer_info[i].blendkey,(unsigned long) layer_info[i].opacity,
1004                 layer_info[i].clipping ? "true" : "false",layer_info[i].flags,
1005                 layer_info[i].visible ? "true" : "false");
1006             (void) ReadBlobByte(image);  /* filler */
1007             combinedlength=0;
1008             size=ReadBlobMSBLong(image);
1009             if (size != 0)
1010               {
1011                 if (image->debug != MagickFalse)
1012                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1013                     "    layer contains additional info");
1014                 length=ReadBlobMSBLong(image);
1015                 if (length != 0)
1016                   {
1017                     /*
1018                       Layer mask info.
1019                     */
1020                     layer_info[i].mask.y=(long) ReadBlobMSBLong(image);
1021                     layer_info[i].mask.x=(long) ReadBlobMSBLong(image);
1022                     layer_info[i].mask.height=(unsigned long)
1023                       (ReadBlobMSBLong(image)-layer_info[i].mask.y);
1024                     layer_info[i].mask.width=(unsigned long)
1025                       (ReadBlobMSBLong(image)-layer_info[i].mask.x);
1026                     if (image->debug != MagickFalse)
1027                       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1028                         "      layer mask: offset(%ld,%ld), size(%ld,%ld), length=%ld",
1029                         layer_info[i].mask.x,layer_info[i].mask.y,
1030                         layer_info[i].mask.width, layer_info[i].mask.height,
1031                         (long) length-16);
1032                     /*
1033                       Skip over the rest of the layer mask information.
1034                     */
1035                     for (j=0; j < (long) (length-16); j++)
1036                       (void) ReadBlobByte(image);
1037                   }
1038                 combinedlength+=length+4;  /* +4 for length */
1039                 length=ReadBlobMSBLong(image);
1040                 if (length != 0)
1041                   {
1042                     /*
1043                       Layer blending ranges info.
1044                     */
1045                     if (image->debug != MagickFalse)
1046                       (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1047                         "      layer blending ranges: length=%ld",(long) length);
1048                     /*
1049                       We read it, but don't use it...
1050                     */
1051                     for (j=0; j < (long) (length); j+=8)
1052                     {
1053                       size_t blend_source=ReadBlobMSBLong(image);
1054                       size_t blend_dest=ReadBlobMSBLong(image);
1055                       if (image->debug != MagickFalse)
1056                         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1057                           "        source(%x), dest(%x)",(unsigned int)
1058                           blend_source,(unsigned int) blend_dest);
1059                     }
1060                   }
1061                 combinedlength+=length+4;
1062                 /*
1063                   Layer name.
1064                 */
1065                 length=(size_t) ReadBlobByte(image);
1066                 for (j=0; j < (long) length; j++)
1067                   layer_info[i].name[j]=(unsigned char) ReadBlobByte(image);
1068                 layer_info[i].name[j]='\0';
1069                 if (image->debug != MagickFalse)
1070                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1071                     "      layer name: %s",layer_info[i].name);
1072                 combinedlength+=length+1;
1073
1074 #if     0  /* still in development */
1075           /*
1076             Adjustment layers and other stuff...
1077           */
1078           {
1079             char  alsig[4],
1080                 alkey[4];
1081
1082             count=ReadBlob(image,4,alsig);
1083             if ((count == 0) || (LocaleNCompare(alsig,"8BIM",4) != 0)) {
1084               if (debug != MagickFalse)
1085               {
1086       if (image->debug != MagickFalse)
1087                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),"  adjustment layer type was %.4s instead of 8BIM", alsig);
1088               }
1089               ThrowReaderException(CorruptImageError,"ImproperImageHeader");
1090             }
1091             count=ReadBlob(image,4,alkey);
1092             length=ReadBlobMSBLong(image);
1093               if (debug != MagickFalse)
1094               {
1095       if (image->debug != MagickFalse)
1096                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1097                             "      adjustment layer key: %.4s, data length=%ld",
1098                             alkey, length);
1099               }
1100
1101               if ( length ) {
1102               for (j=0; j < (long) (length); j++)
1103                 (void) ReadBlobByte(image);
1104               }
1105
1106           }
1107           combinedlength += 12 + length;  /* sig, key, length + the actual length*/
1108 #endif
1109
1110                /*
1111                   Skip the rest of the variable data until we support it.
1112                 */
1113                 if (image->debug != MagickFalse)
1114                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1115                     "      unsupported data: length=%ld",(long)
1116                     (size-combinedlength));
1117                 for (j=0; j < (long) (size-combinedlength); j++)
1118                   (void) ReadBlobByte(image);
1119               }
1120             /*
1121               Allocate layered image.
1122             */
1123             layer_info[i].image=CloneImage(image,layer_info[i].page.width,
1124               layer_info[i].page.height,MagickFalse,&image->exception);
1125             if (layer_info[i].image == (Image *) NULL)
1126               {
1127                 for (j=0; j < i; j++)
1128                   layer_info[j].image=DestroyImage(layer_info[j].image);
1129                 if (image->debug != MagickFalse)
1130                   (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1131                     "  allocation of image for layer %ld failed", i);
1132                 ThrowReaderException(ResourceLimitError,
1133                   "MemoryAllocationFailed");
1134               }
1135             if (image->debug != MagickFalse)
1136               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1137                 "    setting up new layer image");
1138             (void) SetImageBackgroundColor(layer_info[i].image);
1139             layer_info[i].image->compose=
1140               PSDBlendModeToCompositeOperator(layer_info[i].blendkey);
1141             if (layer_info[i].visible == MagickFalse)
1142               layer_info[i].image->compose=NoCompositeOp;
1143             if (psd_info.mode == CMYKMode)
1144               layer_info[i].image->colorspace=CMYKColorspace;
1145             if ((psd_info.mode == BitmapMode) ||
1146                 (psd_info.mode == GrayscaleMode) ||
1147                 (psd_info.mode == DuotoneMode))
1148               layer_info[i].image->colorspace=GRAYColorspace;
1149             for (j=0; j < (long) layer_info[i].channels; j++)
1150               if (layer_info[i].channel_info[j].type == -1)
1151                 layer_info[i].image->matte=MagickTrue;
1152             /*
1153               Set up some hidden attributes for folks that need them.
1154             */
1155             (void) FormatMagickString(message,MaxTextExtent,"%ld",
1156               layer_info[i].page.x);
1157             (void) SetImageArtifact(layer_info[i].image,"psd:layer.x",message);
1158             (void) FormatMagickString(message,MaxTextExtent,"%ld",
1159               layer_info[i].page.y);
1160             (void) SetImageArtifact(layer_info[i].image,"psd:layer.y",message);
1161             (void) FormatMagickString(message,MaxTextExtent,"%lu",
1162               (unsigned long) layer_info[i].opacity);
1163             (void) SetImageArtifact(layer_info[i].image,"psd:layer.opacity",
1164               message);
1165             (void) SetImageProperty(layer_info[i].image,"label",(char *)
1166               layer_info[i].name);
1167           }
1168         if (image->debug != MagickFalse)
1169           (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1170             "  reading image data for layers");
1171         /*
1172           Read pixel data for each layer.
1173         */
1174         for (i=0; i < number_layers; i++)
1175         {
1176           if (image->debug != MagickFalse)
1177             (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1178               "  reading data for layer %ld",i);
1179             for (j=0; j < (long) layer_info[i].channels; j++)
1180             {
1181               if (image->debug != MagickFalse)
1182                 (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1183                   "    reading data for channel %ld", j);
1184 #if     1
1185               if (layer_info[i].channel_info[j].size <= (2*layer_info[i].image->rows))
1186                 {
1187                   long
1188                     k;
1189
1190                   if (image->debug != MagickFalse)
1191                     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1192                       "      layer data is empty");
1193                   /*
1194                     A layer without data.
1195                   */
1196                   for (k=0; k < (long) layer_info[i].channel_info[j].size; k++)
1197                     (void) ReadBlobByte(layer_info[i].image);
1198                   continue;
1199                 }
1200 #endif
1201               offsets=(MagickOffsetType *) NULL;
1202               layer_info[i].image->compression=NoCompression;
1203               compression=ReadBlobMSBShort(layer_info[i].image);
1204               if ((layer_info[i].page.height != 0) &&
1205                   (layer_info[i].page.width != 0))
1206                 {
1207                   if (compression == 1)
1208                     {
1209                       /*
1210                         Read RLE compressed data.
1211                       */
1212                       layer_info[i].image->compression=RLECompression;
1213                       if (image->debug != MagickFalse)
1214                         (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1215                           "      layer data is RLE compressed");
1216                       offsets=(MagickOffsetType *) AcquireQuantumMemory(
1217                         layer_info[i].image->rows,sizeof(*offsets));
1218                       if (offsets == (MagickOffsetType *) NULL)
1219                         ThrowReaderException(ResourceLimitError,
1220                           "MemoryAllocationFailed");
1221                       for (y=0; y < (long) layer_info[i].image->rows; y++)
1222                         offsets[y]=GetPSDOffset(&psd_info,layer_info[i].image);
1223                     }
1224                   status=ReadPSDLayer(layer_info[i].image,
1225                     layer_info[i].channels,(unsigned long)
1226                     layer_info[i].channel_info[j].type,offsets,exception);
1227                   if (compression == 1)
1228                     offsets=(MagickOffsetType *) RelinquishMagickMemory(
1229                       offsets);
1230                   if (status == MagickFalse)
1231                     break;
1232                 }
1233               }
1234             if (layer_info[i].opacity != OpaqueOpacity)
1235               {
1236                 /*
1237                   Correct for opacity level.
1238                 */
1239                 for (y=0; y < (long) layer_info[i].image->rows; y++)
1240                 {
1241                   q=GetAuthenticPixels(layer_info[i].image,0,y,
1242                     layer_info[i].image->columns,1,exception);
1243                   if (q == (PixelPacket *) NULL)
1244                     break;
1245                   indexes=GetAuthenticIndexQueue(layer_info[i].image);
1246                   for (x=0; x < (long) layer_info[i].image->columns; x++)
1247                   {
1248                     q->opacity=(Quantum) (QuantumRange-(Quantum) (QuantumScale*
1249                       ((QuantumRange-q->opacity)*(QuantumRange-
1250                       layer_info[i].opacity))));
1251                     q++;
1252                   }
1253                   if (SyncAuthenticPixels(layer_info[i].image,exception) == MagickFalse)
1254                     break;
1255                 }
1256               }
1257             if (layer_info[i].image->colorspace == CMYKColorspace)
1258               (void) NegateImage(layer_info[i].image,MagickFalse);
1259             status=SetImageProgress(image,LoadImagesTag,i,(MagickSizeType)
1260               number_layers);
1261             if (status == MagickFalse)
1262               break;
1263           }
1264         /* added by palf -> invisible group layer make layer of this group
1265            invisible I consider that all layer with width and height null are
1266            layer for group layer */
1267        {
1268          short inside_layer = 0;
1269          short layer_visible = 0;
1270          for (i=number_layers-1; i >=0; i--)
1271          {
1272            if ((layer_info[i].page.width == 0) ||
1273                (layer_info[i].page.height == 0))
1274              {
1275                if (inside_layer == 0)
1276                  {
1277                    inside_layer=1;
1278                    layer_visible=(short int) layer_info[i].visible;
1279                  }
1280                else
1281                  {
1282                    inside_layer = 0;
1283                  }
1284              }
1285            else
1286              if ((inside_layer == 1) && (layer_visible == 0))
1287                {
1288                  layer_info[i].visible=(unsigned char) layer_visible;
1289                  layer_info[i].image->compose=NoCompositeOp;
1290                }
1291          }
1292        }
1293        /* added by palf -> suppression of empty layer */
1294        /* I consider that all layer with width and height null are layer for group layer */
1295        for (i=0; i < number_layers; i++)
1296        {
1297          if ((layer_info[i].page.width == 0) ||
1298              (layer_info[i].page.height == 0))
1299            {
1300              if (layer_info[i].image != (Image *) NULL)
1301                layer_info[i].image=DestroyImage(layer_info[i].image);
1302              for (j=i; j < number_layers - 1; j++)
1303                layer_info[j] = layer_info[j+1];
1304              number_layers--;
1305              i--;
1306            }
1307         }
1308         mask_size = ReadBlobMSBLong(image);  /* global mask size: currently ignored */
1309         if (number_layers > 0)
1310           {
1311             if (image->debug != MagickFalse)
1312               (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1313                 "  putting layers into image list");
1314             for (i=0; i < number_layers; i++)
1315             {
1316               if (i > 0)
1317                 layer_info[i].image->previous=layer_info[i-1].image;
1318               if (i < (number_layers-1))
1319                 layer_info[i].image->next=layer_info[i+1].image;
1320               layer_info[i].image->page=layer_info[i].page;
1321             }
1322             image->next=layer_info[0].image;
1323             layer_info[0].image->previous=image;
1324             layer_info=(LayerInfo *) RelinquishMagickMemory(layer_info);
1325           }
1326         layer_offset-=TellBlob(image);
1327         offset=SeekBlob(image,layer_offset,SEEK_CUR);
1328       }
1329     }
1330   /*
1331     Read the precombined layer, present for PSD < 4 compatibility
1332   */
1333   if (image->debug != MagickFalse)
1334     (void) LogMagickEvent(CoderEvent,GetMagickModule(),
1335       "  reading the precombined layer");
1336   offsets=(MagickOffsetType *) NULL;
1337   image->compression=NoCompression;
1338   compression=ReadBlobMSBShort(image);
1339   if (compression == 1)
1340     {
1341       /*
1342         Read Packbit encoded pixel data as separate planes.
1343       */
1344       image->compression=RLECompression;
1345       offsets=(MagickOffsetType *) AcquireQuantumMemory(image->rows,
1346         psd_info.channels*sizeof(*offsets));
1347       if (offsets == (MagickOffsetType *) NULL)
1348         ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
1349       for (i=0; i < (long) (image->rows*psd_info.channels); i++)
1350         offsets[i]=GetPSDOffset(&psd_info,image);
1351     }
1352   for (i=0; i < (long) psd_info.channels; i++)
1353   {
1354     status=ReadPSDLayer(image,psd_info.channels,(unsigned long) i,offsets+i*
1355       image->rows,exception);
1356     if (status == MagickFalse)
1357       break;
1358     status=SetImageProgress(image,LoadImagesTag,i,psd_info.channels);
1359     if (status == MagickFalse)
1360       break;
1361   }
1362   if (compression == 1)
1363     offsets=(MagickOffsetType *) RelinquishMagickMemory(offsets);
1364   if (image->colorspace == CMYKColorspace)
1365     (void) NegateImage(image,MagickFalse);
1366   (void) CloseBlob(image);
1367   return(GetFirstImageInList(image));
1368 }
1369 \f
1370 /*
1371 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1372 %                                                                             %
1373 %                                                                             %
1374 %                                                                             %
1375 %   R e g i s t e r P S D I m a g e                                           %
1376 %                                                                             %
1377 %                                                                             %
1378 %                                                                             %
1379 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1380 %
1381 %  RegisterPSDImage() adds properties for the PSD image format to
1382 %  the list of supported formats.  The properties include the image format
1383 %  tag, a method to read and/or write the format, whether the format
1384 %  supports the saving of more than one frame to the same file or blob,
1385 %  whether the format supports native in-memory I/O, and a brief
1386 %  description of the format.
1387 %
1388 %  The format of the RegisterPSDImage method is:
1389 %
1390 %      unsigned long RegisterPSDImage(void)
1391 %
1392 */
1393 ModuleExport unsigned long RegisterPSDImage(void)
1394 {
1395   MagickInfo
1396     *entry;
1397
1398   entry=SetMagickInfo("PSB");
1399   entry->decoder=(DecodeImageHandler *) ReadPSDImage;
1400   entry->encoder=(EncodeImageHandler *) WritePSDImage;
1401   entry->magick=(IsImageFormatHandler *) IsPSD;
1402   entry->description=ConstantString("Adobe Large Document Format");
1403   entry->module=ConstantString("PSD");
1404   (void) RegisterMagickInfo(entry);
1405   entry=SetMagickInfo("PSD");
1406   entry->decoder=(DecodeImageHandler *) ReadPSDImage;
1407   entry->encoder=(EncodeImageHandler *) WritePSDImage;
1408   entry->magick=(IsImageFormatHandler *) IsPSD;
1409   entry->description=ConstantString("Adobe Photoshop bitmap");
1410   entry->module=ConstantString("PSD");
1411   (void) RegisterMagickInfo(entry);
1412   return(MagickImageCoderSignature);
1413 }
1414 \f
1415 /*
1416 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1417 %                                                                             %
1418 %                                                                             %
1419 %                                                                             %
1420 %   U n r e g i s t e r P S D I m a g e                                       %
1421 %                                                                             %
1422 %                                                                             %
1423 %                                                                             %
1424 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1425 %
1426 %  UnregisterPSDImage() removes format registrations made by the
1427 %  PSD module from the list of supported formats.
1428 %
1429 %  The format of the UnregisterPSDImage method is:
1430 %
1431 %      UnregisterPSDImage(void)
1432 %
1433 */
1434 ModuleExport void UnregisterPSDImage(void)
1435 {
1436   (void) UnregisterMagickInfo("PSB");
1437   (void) UnregisterMagickInfo("PSD");
1438 }
1439 \f
1440 /*
1441 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1442 %                                                                             %
1443 %                                                                             %
1444 %                                                                             %
1445 %   W r i t e P S D I m a g e                                                 %
1446 %                                                                             %
1447 %                                                                             %
1448 %                                                                             %
1449 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1450 %
1451 %  WritePSDImage() writes an image in the Adobe Photoshop encoded image format.
1452 %
1453 %  The format of the WritePSDImage method is:
1454 %
1455 %      MagickBooleanType WritePSDImage(const ImageInfo *image_info,Image *image)
1456 %
1457 %  A description of each parameter follows.
1458 %
1459 %    o image_info: the image info.
1460 %
1461 %    o image:  The image.
1462 %
1463 %
1464 */
1465
1466 static inline ssize_t SetPSDOffset(const PSDInfo *psd_info,Image *image,
1467   const size_t offset)
1468 {
1469   if (psd_info->version == 1)
1470     return(WriteBlobMSBShort(image,(unsigned short) offset));
1471   return(WriteBlobMSBLong(image,(unsigned short) offset));
1472 }
1473
1474 static inline ssize_t SetPSDSize(const PSDInfo *psd_info,Image *image,
1475   const MagickSizeType size)
1476 {
1477   if (psd_info->version == 1)
1478     return(WriteBlobMSBLong(image,(unsigned int) size));
1479   return(WriteBlobMSBLongLong(image,size));
1480 }
1481
1482 static size_t PSDPackbitsEncodeImage(Image *image,const size_t length,
1483   const unsigned char *pixels,unsigned char *compact_pixels)
1484 {
1485   int
1486     count;
1487
1488   register long
1489     i,
1490     j;
1491
1492   register unsigned char
1493     *q;
1494
1495   unsigned char
1496     *packbits;
1497
1498   /*
1499     Compress pixels with Packbits encoding.
1500   */
1501   assert(image != (Image *) NULL);
1502   assert(image->signature == MagickSignature);
1503   if (image->debug != MagickFalse)
1504     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1505   assert(pixels != (unsigned char *) NULL);
1506   packbits=(unsigned char *) AcquireQuantumMemory(128UL,sizeof(*packbits));
1507   if (packbits == (unsigned char *) NULL)
1508     ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
1509       image->filename);
1510   q=compact_pixels;
1511   for (i=(long) length; i != 0; )
1512   {
1513     switch (i)
1514     {
1515       case 1:
1516       {
1517         i--;
1518         *q++=(unsigned char) 0;
1519         *q++=(*pixels);
1520         break;
1521       }
1522       case 2:
1523       {
1524         i-=2;
1525         *q++=(unsigned char) 1;
1526         *q++=(*pixels);
1527         *q++=pixels[1];
1528         break;
1529       }
1530       case 3:
1531       {
1532         i-=3;
1533         if ((*pixels == *(pixels+1)) && (*(pixels+1) == *(pixels+2)))
1534           {
1535             *q++=(unsigned char) ((256-3)+1);
1536             *q++=(*pixels);
1537             break;
1538           }
1539         *q++=(unsigned char) 2;
1540         *q++=(*pixels);
1541         *q++=pixels[1];
1542         *q++=pixels[2];
1543         break;
1544       }
1545       default:
1546       {
1547         if ((*pixels == *(pixels+1)) && (*(pixels+1) == *(pixels+2)))
1548           {
1549             /*
1550               Packed run.
1551             */
1552             count=3;
1553             while (((long) count < i) && (*pixels == *(pixels+count)))
1554             {
1555               count++;
1556               if (count >= 127)
1557                 break;
1558             }
1559             i-=count;
1560             *q++=(unsigned char) ((256-count)+1);
1561             *q++=(*pixels);
1562             pixels+=count;
1563             break;
1564           }
1565         /*
1566           Literal run.
1567         */
1568         count=0;
1569         while ((*(pixels+count) != *(pixels+count+1)) ||
1570                (*(pixels+count+1) != *(pixels+count+2)))
1571         {
1572           packbits[count+1]=pixels[count];
1573           count++;
1574           if (((long) count >= (i-3)) || (count >= 127))
1575             break;
1576         }
1577         i-=count;
1578         *packbits=(unsigned char) (count-1);
1579         for (j=0; j <= (long) count; j++)
1580           *q++=packbits[j];
1581         pixels+=count;
1582         break;
1583       }
1584     }
1585   }
1586   *q++=(unsigned char) 128;  /* EOD marker */
1587   packbits=(unsigned char *) RelinquishMagickMemory(packbits);
1588   return((size_t) (q-compact_pixels));
1589 }
1590
1591 static void WritePackbitsLength(const PSDInfo *psd_info,
1592   const ImageInfo *image_info,Image *image,Image *tmp_image,
1593   unsigned char *pixels,unsigned char *compact_pixels,
1594   const QuantumType quantum_type)
1595 {
1596   int
1597     y;
1598
1599   QuantumInfo
1600     *quantum_info;
1601
1602   register const PixelPacket
1603     *p;
1604
1605   size_t
1606     length,
1607     packet_size;
1608
1609   if (tmp_image->depth > 8)
1610     tmp_image->depth=16;
1611   packet_size=tmp_image->depth > 8UL ? 2UL : 1UL;
1612   quantum_info=AcquireQuantumInfo(image_info,image);
1613   for (y=0; y < (long) tmp_image->rows; y++)
1614   {
1615     p=GetVirtualPixels(tmp_image,0,y,tmp_image->columns,1,&image->exception);
1616     if (p == (const PixelPacket *) NULL)
1617       break;
1618     length=ExportQuantumPixels(tmp_image,(CacheView *) NULL,quantum_info,
1619       quantum_type,pixels,&image->exception);
1620     length=PSDPackbitsEncodeImage(image,length,pixels,compact_pixels);
1621     (void) SetPSDOffset(psd_info,image,length);
1622   }
1623   quantum_info=DestroyQuantumInfo(quantum_info);
1624 }
1625
1626 static void WriteOneChannel(const PSDInfo *psd_info,const ImageInfo *image_info,
1627   Image *image,Image *tmp_image,unsigned char *pixels,
1628   unsigned char *compact_pixels,const QuantumType quantum_type,
1629   const MagickBooleanType compression_flag)
1630 {
1631   int
1632     y;
1633
1634   MagickBooleanType
1635     monochrome;
1636
1637   QuantumInfo
1638     *quantum_info;
1639
1640   register const PixelPacket
1641     *p;
1642
1643   register long
1644     i;
1645
1646   size_t
1647     length,
1648     packet_size;
1649
1650   (void) psd_info;
1651   if ((compression_flag != MagickFalse) &&
1652       (tmp_image->compression != RLECompression))
1653     (void) WriteBlobMSBShort(image,0);
1654   if (tmp_image->depth > 8)
1655     tmp_image->depth=16;
1656   monochrome=IsMonochromeImage(image,&image->exception);
1657   packet_size=tmp_image->depth > 8UL ? 2UL : 1UL;
1658   quantum_info=AcquireQuantumInfo(image_info,image);
1659   for (y=0; y < (long) tmp_image->rows; y++)
1660   {
1661     p=GetVirtualPixels(tmp_image,0,y,tmp_image->columns,1,&image->exception);
1662     if (p == (const PixelPacket *) NULL)
1663       break;
1664     length=ExportQuantumPixels(tmp_image,(CacheView *) NULL,quantum_info,
1665       quantum_type,pixels,&image->exception);
1666     if (monochrome != MagickFalse)
1667       for (i=0; i < (long) length; i++)
1668         pixels[i]=(~pixels[i]);
1669     if (tmp_image->compression != RLECompression)
1670       (void) WriteBlob(image,length,pixels);
1671     else
1672       {
1673         length=PSDPackbitsEncodeImage(image,length,pixels,compact_pixels);
1674         (void) WriteBlob(image,length,compact_pixels);
1675       }
1676   }
1677   quantum_info=DestroyQuantumInfo(quantum_info);
1678 }
1679
1680 static MagickBooleanType WriteImageChannels(const PSDInfo *psd_info,
1681   const ImageInfo *image_info,Image *image,Image *tmp_image,
1682   const MagickBooleanType separate)
1683 {
1684   int
1685     i;
1686
1687   size_t
1688     channels,
1689     packet_size;
1690
1691   unsigned char
1692     *compact_pixels,
1693     *pixels;
1694
1695   /*
1696     Write uncompressed pixels as separate planes.
1697   */
1698   channels=1;
1699   if ((tmp_image->storage_class == PseudoClass) &&
1700       (tmp_image->matte == MagickFalse))
1701     channels++;
1702   packet_size=tmp_image->depth > 8UL ? 2UL : 1UL;
1703   pixels=(unsigned char *) AcquireQuantumMemory(channels*tmp_image->columns,
1704     packet_size*sizeof(*pixels));
1705   compact_pixels=(unsigned char *) AcquireQuantumMemory(2*channels*
1706     tmp_image->columns,packet_size*sizeof(*pixels));
1707   if ((pixels == (unsigned char *) NULL) ||
1708       (compact_pixels == (unsigned char *) NULL))
1709     {
1710       if (pixels != (unsigned char *) NULL)
1711         pixels=(unsigned char *) RelinquishMagickMemory(pixels);
1712       if (compact_pixels != (unsigned char *) NULL)
1713         compact_pixels=(unsigned char *)
1714           RelinquishMagickMemory(compact_pixels);
1715       ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
1716     }
1717   i=0;
1718   if (IsGrayImage(tmp_image,&tmp_image->exception) != MagickFalse)
1719     {
1720       if (tmp_image->compression == RLECompression)
1721         {
1722           /*
1723             Packbits compression.
1724           */
1725           (void) WriteBlobMSBShort(image,1);
1726           if (tmp_image->matte != MagickFalse)
1727             WritePackbitsLength(psd_info,image_info,image,tmp_image,pixels,
1728               compact_pixels,AlphaQuantum);
1729           WritePackbitsLength(psd_info,image_info,image,tmp_image,pixels,
1730            compact_pixels,GrayQuantum);
1731         }
1732       WriteOneChannel(psd_info,image_info,image,tmp_image,pixels,
1733         compact_pixels,GrayQuantum,(i++ == 0) || (separate != MagickFalse) ?
1734         MagickTrue : MagickFalse);
1735     }
1736   else
1737     if (tmp_image->storage_class == PseudoClass)
1738       {
1739         if (tmp_image->compression == RLECompression)
1740           {
1741             /*
1742               Packbits compression.
1743             */
1744             (void) WriteBlobMSBShort(image,1);
1745             if (tmp_image->matte == MagickFalse)
1746               WritePackbitsLength(psd_info,image_info,image,tmp_image,pixels,
1747                 compact_pixels,IndexQuantum);
1748             else
1749               WritePackbitsLength(psd_info,image_info,image,tmp_image,pixels,
1750                 compact_pixels,IndexAlphaQuantum);
1751           }
1752         if (tmp_image->matte == MagickFalse)
1753           WriteOneChannel(psd_info,image_info,image,tmp_image,pixels,
1754             compact_pixels,IndexQuantum,(i++ == 0) ||
1755             (separate != MagickFalse) ? MagickTrue : MagickFalse);
1756         else
1757           WriteOneChannel(psd_info,image_info,image,tmp_image,pixels,
1758             compact_pixels,IndexAlphaQuantum,(i++ == 0) ||
1759             (separate != MagickFalse) ?  MagickTrue : MagickFalse);
1760         (void) SetImageProgress(image,SaveImagesTag,0,1);
1761       }
1762     else
1763       {
1764         if (tmp_image->colorspace == CMYKColorspace)
1765           {
1766             tmp_image->compression=NoCompression;
1767             (void) NegateImage(tmp_image,MagickFalse);
1768           }
1769         if (tmp_image->compression == RLECompression)
1770           {
1771             /*
1772               Packbits compression.
1773             */
1774             (void) WriteBlobMSBShort(image,1);
1775             if (tmp_image->matte != MagickFalse)
1776               WritePackbitsLength(psd_info,image_info,image,tmp_image,pixels,
1777                 compact_pixels,AlphaQuantum);
1778             WritePackbitsLength(psd_info,image_info,image,tmp_image,pixels,
1779               compact_pixels,RedQuantum);
1780             WritePackbitsLength(psd_info,image_info,image,tmp_image,pixels,
1781               compact_pixels,GreenQuantum);
1782             WritePackbitsLength(psd_info,image_info,image,tmp_image,pixels,
1783               compact_pixels,BlueQuantum);
1784             if (tmp_image->colorspace == CMYKColorspace)
1785               WritePackbitsLength(psd_info,image_info,image,tmp_image,pixels,
1786                 compact_pixels,BlackQuantum);
1787           }
1788         (void) SetImageProgress(image,SaveImagesTag,0,6);
1789         if (tmp_image->matte != MagickFalse)
1790           WriteOneChannel(psd_info,image_info,image,tmp_image,pixels,
1791             compact_pixels,AlphaQuantum,(i++ == 0) ||
1792             (separate != MagickFalse) ? MagickTrue : MagickFalse);
1793         (void) SetImageProgress(image,SaveImagesTag,1,6);
1794         WriteOneChannel(psd_info,image_info,image,tmp_image,pixels,
1795           compact_pixels,RedQuantum,(i++ == 0) || (separate != MagickFalse) ?
1796           MagickTrue : MagickFalse);
1797         (void) SetImageProgress(image,SaveImagesTag,2,6);
1798         WriteOneChannel(psd_info,image_info,image,tmp_image,pixels,
1799           compact_pixels,GreenQuantum,(i++ == 0) || (separate != MagickFalse) ?
1800           MagickTrue : MagickFalse);
1801         (void) SetImageProgress(image,SaveImagesTag,3,6);
1802         WriteOneChannel(psd_info,image_info,image,tmp_image,pixels,
1803           compact_pixels,BlueQuantum,(i++ == 0) || (separate != MagickFalse) ?
1804           MagickTrue : MagickFalse);
1805         (void) SetImageProgress(image,SaveImagesTag,4,6);
1806         if (tmp_image->colorspace == CMYKColorspace)
1807           {
1808             WriteOneChannel(psd_info,image_info,image,tmp_image,pixels,
1809               compact_pixels,BlackQuantum,(i++ == 0) ||
1810               (separate != MagickFalse) ? MagickTrue : MagickFalse);
1811             (void) NegateImage(tmp_image,MagickFalse);
1812           }
1813         (void) SetImageProgress(image,SaveImagesTag,5,6);
1814       }
1815   pixels=(unsigned char *) RelinquishMagickMemory(pixels);
1816   return(MagickTrue);
1817 }
1818
1819 static void WritePascalString(Image* inImage,const char *inString,int inPad)
1820 {
1821   size_t
1822     strLength;
1823   int i;
1824
1825   /* max length is 255 */
1826
1827   strLength = (strlen(inString) > 255UL ) ? 255UL : strlen(inString);
1828
1829   if ( strLength !=  0 )
1830   {
1831   (void) WriteBlobByte(inImage,(unsigned char) strLength);
1832   (void) WriteBlob(inImage, strLength, (const unsigned char *) inString);
1833   }
1834   else
1835   (void) WriteBlobByte(inImage, 0);
1836
1837   strLength ++;
1838
1839   if ( (strLength % inPad) == 0 )
1840     return;
1841   for (i=0; i < (long) (inPad-(strLength % inPad)); i++)
1842     (void) WriteBlobByte(inImage,0);
1843 }
1844
1845 static void WriteResolutionResourceBlock(Image *image)
1846 {
1847   double
1848     x_resolution,
1849     y_resolution;
1850
1851   unsigned short
1852     units;
1853
1854   x_resolution=65536.0*image->x_resolution+0.5;
1855   y_resolution=65536.0*image->y_resolution+0.5;
1856   units=1;
1857   if (image->units == PixelsPerCentimeterResolution)
1858     {
1859       x_resolution=2.54*65536.0*image->x_resolution*0.5;
1860       y_resolution=2.54*65536.0*image->y_resolution+0.5;
1861       units=2;
1862     }
1863   (void) WriteBlob(image,4,(const unsigned char *) "8BIM");
1864   (void) WriteBlobMSBShort(image,0x03ED);
1865   (void) WriteBlobMSBShort(image,0);
1866   (void) WriteBlobMSBLong(image,16); /* resource size */
1867   (void) WriteBlobMSBLong(image,(unsigned int) (x_resolution+0.5));
1868   (void) WriteBlobMSBShort(image,units); /* horizontal resolution unit */
1869   (void) WriteBlobMSBShort(image,units); /* width unit */
1870   (void) WriteBlobMSBLong(image,(unsigned int) (y_resolution+0.5));
1871   (void) WriteBlobMSBShort(image,units); /* vertical resolution unit */
1872   (void) WriteBlobMSBShort(image,units); /* height unit */
1873 }
1874
1875 static MagickBooleanType WritePSDImage(const ImageInfo *image_info,Image *image)
1876 {
1877   const char
1878     *theAttr;
1879
1880   const StringInfo
1881     *bim_profile,
1882     *icc_profile;
1883
1884   MagickBooleanType
1885     invert_layer_count = MagickFalse,
1886     status;
1887
1888   PSDInfo
1889     psd_info;
1890
1891   register long
1892     i;
1893
1894   size_t
1895     length,
1896     num_channels,
1897     packet_size;
1898
1899   unsigned char
1900     layer_name[4];
1901
1902   unsigned long
1903     channel_size,
1904     channelLength,
1905     layer_count,
1906     layer_info_size,
1907     rounded_layer_info_size;
1908
1909   Image
1910     * tmp_image = (Image *) NULL,
1911     * base_image = GetNextImageInList(image);
1912
1913   /*
1914     Open image file.
1915   */
1916   assert(image_info != (const ImageInfo *) NULL);
1917   assert(image_info->signature == MagickSignature);
1918   assert(image != (Image *) NULL);
1919   assert(image->signature == MagickSignature);
1920   if (image->debug != MagickFalse)
1921     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
1922   status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
1923   if (status == MagickFalse)
1924     return(status);
1925   packet_size=(size_t) (image->depth > 8 ? 6 : 3);
1926   if (image->matte != MagickFalse)
1927     packet_size+=image->depth > 8 ? 2 : 1;
1928   psd_info.version=1;
1929   if ((LocaleCompare(image_info->magick,"PSB") == 0) ||
1930       (image->columns > 30000) || (image->rows > 30000))
1931     psd_info.version=2;
1932   (void) WriteBlob(image,4,(const unsigned char *) "8BPS");
1933   (void) WriteBlobMSBShort(image,psd_info.version);  /* version */
1934   for (i=1; i <= 6; i++)
1935     (void) WriteBlobByte(image, 0);  /* 6 bytes of reserved */
1936   if (IsGrayImage(image,&image->exception) != MagickFalse)
1937     num_channels=1;
1938   else
1939     if (image->storage_class == PseudoClass)
1940       num_channels=(image->matte ? 2UL : 1UL);
1941     else
1942       {
1943         if (image->colorspace != CMYKColorspace)
1944           num_channels=(image->matte ? 4UL : 3UL);
1945         else
1946           num_channels=(image->matte ? 5UL : 4UL);
1947       }
1948   (void) WriteBlobMSBShort(image,(unsigned short) num_channels);
1949   (void) WriteBlobMSBLong(image,(unsigned int) image->rows);
1950   (void) WriteBlobMSBLong(image,(unsigned int) image->columns);
1951   if (IsGrayImage(image,&image->exception) != MagickFalse)
1952     {
1953       MagickBooleanType
1954         monochrome;
1955
1956       /*
1957         Write depth & mode.
1958       */
1959       monochrome=IsMonochromeImage(image,&image->exception);
1960       (void) WriteBlobMSBShort(image,monochrome != MagickFalse ? 1 :
1961         image->depth > 8 ? 16 : 8);
1962       (void) WriteBlobMSBShort(image,monochrome != MagickFalse ?
1963         BitmapMode : GrayscaleMode);
1964     }
1965   else
1966     {
1967       (void) WriteBlobMSBShort(image,(unsigned short)
1968         (image->storage_class == PseudoClass ? 8 : image->depth > 8 ? 16 : 8));
1969       if (((image->colorspace != UndefinedColorspace) ||
1970            (image->colorspace != CMYKColorspace)) &&
1971            (image->colorspace != CMYKColorspace))
1972         {
1973           if (image->colorspace != RGBColorspace)
1974             (void) TransformImageColorspace(image,RGBColorspace);
1975           (void) WriteBlobMSBShort(image,(unsigned short)
1976             (image->storage_class == PseudoClass ? IndexedMode : RGBMode));
1977         }
1978       else
1979         {
1980           if (image->colorspace != RGBColorspace)
1981             (void) TransformImageColorspace(image,CMYKColorspace);
1982           (void) WriteBlobMSBShort(image,CMYKMode);
1983         }
1984     }
1985   if ((IsGrayImage(image,&image->exception) != MagickFalse) ||
1986       (image->storage_class == DirectClass) || (image->colors > 256))
1987     (void) WriteBlobMSBLong(image,0);
1988   else
1989     {
1990       /*
1991         Write PSD raster colormap.
1992       */
1993       (void) WriteBlobMSBLong(image,768);
1994       for (i=0; i < (long) image->colors; i++)
1995         (void) WriteBlobByte(image,ScaleQuantumToChar(image->colormap[i].red));
1996       for ( ; i < 256; i++)
1997         (void) WriteBlobByte(image,0);
1998       for (i=0; i < (long) image->colors; i++)
1999         (void) WriteBlobByte(image,ScaleQuantumToChar(image->colormap[i].green));
2000       for ( ; i < 256; i++)
2001         (void) WriteBlobByte(image,0);
2002       for (i=0; i < (long) image->colors; i++)
2003         (void) WriteBlobByte(image,ScaleQuantumToChar(image->colormap[i].blue));
2004       for ( ; i < 256; i++)
2005         (void) WriteBlobByte(image,0);
2006     }
2007   /*
2008     Image resource block.
2009   */
2010   length=28; /* 0x03EB */
2011   bim_profile=(StringInfo *) NULL;
2012   icc_profile=GetImageProfile(image,"icc");
2013   if (icc_profile != (StringInfo *) NULL)
2014     length+=PSDQuantum(GetStringInfoLength(icc_profile))+12;
2015   else
2016     {
2017       bim_profile=GetImageProfile(image,"8bim");
2018       if (bim_profile != (StringInfo *) NULL)
2019         length+=GetStringInfoLength(bim_profile);
2020     }
2021   (void) WriteBlobMSBLong(image,length);
2022   WriteResolutionResourceBlock(image);
2023   if (bim_profile != (StringInfo *) NULL)
2024     (void) WriteBlob(image,GetStringInfoLength(bim_profile),GetStringInfoDatum(
2025       bim_profile));
2026   if (icc_profile != (StringInfo *) NULL)
2027     {
2028       (void) WriteBlob(image,4,(const unsigned char *) "8BIM");
2029       (void) WriteBlobMSBShort(image,0x040F);
2030       (void) WriteBlobMSBShort(image,0);
2031       (void) WriteBlobMSBLong(image,GetStringInfoLength(icc_profile));
2032       (void) WriteBlob(image,GetStringInfoLength(icc_profile),
2033         GetStringInfoDatum(icc_profile));
2034       if ((MagickOffsetType) GetStringInfoLength(icc_profile) !=
2035           PSDQuantum(GetStringInfoLength(icc_profile)))
2036         (void) WriteBlobByte(image,0);
2037     }
2038
2039 compute_layer_info:
2040   layer_count = 0;
2041   layer_info_size = 2;
2042   tmp_image = base_image;
2043   while ( tmp_image != NULL ) {
2044     packet_size=tmp_image->depth > 8 ? 2UL : 1UL;
2045
2046     if (IsGrayImage(image,&image->exception) != MagickFalse)
2047       num_channels=1;
2048     else
2049       if (tmp_image->storage_class == PseudoClass)
2050        num_channels = (tmp_image->matte != MagickFalse ? 2UL : 1UL);
2051       else
2052         if (tmp_image->colorspace != CMYKColorspace)
2053           num_channels = (tmp_image->matte != MagickFalse ? 4UL : 3UL);
2054         else
2055         num_channels = (tmp_image->matte != MagickFalse ? 5UL : 4UL);
2056
2057     channelLength=(unsigned long) (tmp_image->columns * tmp_image->rows *
2058       packet_size + 2);
2059     layer_info_size += (unsigned long) (4*4 + 2 + num_channels * 6 +
2060       (psd_info.version == 1 ? 8 : 16) + 4 * 1 + 4 + num_channels *
2061       channelLength);
2062     theAttr=(const char *) GetImageProperty(tmp_image,"label");
2063     if (!theAttr)
2064       layer_info_size += 16;
2065     else
2066       {
2067         size_t length=strlen(theAttr);
2068         layer_info_size += 8+length+(4-(length % 4))+1;
2069       }
2070     layer_count++;
2071     tmp_image = GetNextImageInList(tmp_image);
2072   }
2073
2074   /* if the image has a matte, then we need to use layers */
2075   if ( layer_count == 0 && image->matte == MagickTrue )
2076   {
2077   invert_layer_count = MagickTrue;
2078   base_image = image;
2079   goto compute_layer_info;  /* yes, goto's suck, but it keeps the code cleaner! */
2080   }
2081
2082   if ( layer_count == 0 )
2083     (void) SetPSDSize(&psd_info,image,0);
2084   else
2085   {
2086     (void) SetPSDSize(&psd_info,image,layer_info_size+
2087       (psd_info.version == 1 ? 8 : 16));
2088     if ( layer_info_size/2 != (layer_info_size+1)/2 ) /* odd */
2089       rounded_layer_info_size = layer_info_size + 1;
2090     else
2091       rounded_layer_info_size = layer_info_size;
2092     (void) SetPSDSize(&psd_info,image,rounded_layer_info_size);
2093
2094     if ( invert_layer_count )
2095       layer_count *= -1;  /* if we have a matte, then use negative count! */
2096     (void) WriteBlobMSBShort(image,(unsigned short) layer_count);
2097
2098     layer_count = 1;
2099     tmp_image = base_image;
2100     tmp_image->compression=NoCompression;
2101     while ( tmp_image != NULL ) {
2102       (void) WriteBlobMSBLong(image,0);
2103       (void) WriteBlobMSBLong(image,0);
2104       (void) WriteBlobMSBLong(image,(unsigned int) tmp_image->rows);
2105       (void) WriteBlobMSBLong(image,(unsigned int) tmp_image->columns);
2106
2107       packet_size=tmp_image->depth > 8 ? 2UL : 1UL;
2108       channel_size=(unsigned int) ((packet_size*tmp_image->rows*
2109         tmp_image->columns)+2);
2110       if (tmp_image->storage_class == PseudoClass) {
2111        (void) WriteBlobMSBShort(image,(unsigned short)
2112          (tmp_image->matte ? 2 : 1));
2113        if (tmp_image->matte) {
2114          (void) WriteBlobMSBShort(image,(unsigned short) -1);
2115          (void) SetPSDSize(&psd_info,image,channel_size);
2116        }
2117        (void) WriteBlobMSBShort(image, 0);
2118        (void) SetPSDSize(&psd_info,image,channel_size);
2119       } else
2120       if (tmp_image->colorspace != CMYKColorspace)
2121       {
2122         (void) WriteBlobMSBShort(image,(unsigned short)
2123           (tmp_image->matte ? 4 : 3));
2124        if (tmp_image->matte) {
2125          (void) WriteBlobMSBShort(image,(unsigned short) -1);
2126          (void) SetPSDSize(&psd_info,image,channel_size);
2127        }
2128        (void) WriteBlobMSBShort(image, 0);
2129        (void) SetPSDSize(&psd_info,image,channel_size);
2130        (void) WriteBlobMSBShort(image, 1);
2131        (void) SetPSDSize(&psd_info,image,channel_size);
2132        (void) WriteBlobMSBShort(image, 2);
2133        (void) SetPSDSize(&psd_info,image,channel_size);
2134       }
2135       else
2136       {
2137         (void) WriteBlobMSBShort(image,(unsigned short)
2138           (tmp_image->matte ? 5 : 4));
2139        if (tmp_image->matte) {
2140          (void) WriteBlobMSBShort(image,(unsigned short) -1);
2141          (void) SetPSDSize(&psd_info,image,channel_size);
2142        }
2143        (void) WriteBlobMSBShort(image, 0);
2144        (void) SetPSDSize(&psd_info,image,channel_size);
2145        (void) WriteBlobMSBShort(image, 1);
2146        (void) SetPSDSize(&psd_info,image,channel_size);
2147        (void) WriteBlobMSBShort(image, 2);
2148        (void) SetPSDSize(&psd_info,image,channel_size);
2149        (void) WriteBlobMSBShort(image, 3);
2150        (void) SetPSDSize(&psd_info,image,channel_size);
2151       }
2152
2153       (void) WriteBlob(image,4,(const unsigned char *) "8BIM");
2154       (void) WriteBlob(image,4,(const unsigned char *)
2155         CompositeOperatorToPSDBlendMode(tmp_image->compose));
2156       (void) WriteBlobByte(image, 255); /* BOGUS: layer opacity */
2157       (void) WriteBlobByte(image, 0);
2158       (void) WriteBlobByte(image, 1); /* BOGUS: layer attributes - visible, etc. */
2159       (void) WriteBlobByte(image, 0);
2160
2161
2162       theAttr=(const char *) GetImageProperty(tmp_image,"label");
2163       if (!theAttr) {
2164         (void) WriteBlobMSBLong(image, 16);
2165         (void) WriteBlobMSBLong(image, 0);
2166         (void) WriteBlobMSBLong(image, 0);
2167         (void) FormatMagickString((char *) layer_name,MaxTextExtent,"L%06ld",
2168           layer_count++ );
2169         WritePascalString( image, (char*)layer_name, 4 );
2170       } else {
2171         size_t length=strlen(theAttr);
2172         (void) WriteBlobMSBLong(image,(unsigned int) (length+(4-(length % 4))+
2173           1+8));
2174         (void) WriteBlobMSBLong(image,0);
2175         (void) WriteBlobMSBLong(image,0);
2176         WritePascalString( image, theAttr, 4 );
2177       }
2178       tmp_image = GetNextImageInList(tmp_image);
2179     };
2180
2181      /* now the image data! */
2182     tmp_image = base_image;
2183     while ( tmp_image != NULL ) {
2184       status=WriteImageChannels(&psd_info,image_info,image,tmp_image,MagickTrue);
2185
2186       /* add in the pad! */
2187        if ( rounded_layer_info_size != layer_info_size )
2188          (void) WriteBlobByte(image,'\0');
2189
2190       tmp_image = GetNextImageInList(tmp_image);
2191     };
2192
2193     /* user mask data */
2194      (void) WriteBlobMSBLong(image, 0);
2195
2196   }
2197
2198   /* now the background image data! */
2199   status=WriteImageChannels(&psd_info,image_info,image,image,MagickFalse);
2200
2201   (void) CloseBlob(image);
2202   return(status);
2203 }