13ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 23ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 33ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 43ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 53ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 63ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% PPPP SSSSS DDDD % 73ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% P P SS D D % 83ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% PPPP SSS D D % 93ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% P SS D D % 103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% P SSSSS DDDD % 113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% Read/Write Adobe Photoshop Image Format % 143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% Software Design % 16de984cdc3631106b1cbbb8d3972b76a0fc27e8e8cristy% Cristy % 173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% Leonard Rosenthol % 183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% July 1992 % 19b41f080d52a5ff2d9c235cffac1419b84028bd31dirk% Dirk Lemstra % 20b41f080d52a5ff2d9c235cffac1419b84028bd31dirk% December 2013 % 213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 237ce65e7125a4e1df1a274ce373c537a9df9c16cdCristy% Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization % 243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% dedicated to making software imaging solutions freely available. % 253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% You may not use this file except in compliance with the License. You may % 273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% obtain a copy of the License at % 283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% http://www.imagemagick.org/script/license.php % 303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% Unless required by applicable law or agreed to in writing, software % 323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% distributed under the License is distributed on an "AS IS" BASIS, % 333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % 343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% See the License for the specific language governing permissions and % 353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% limitations under the License. % 363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Include declarations. 443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 454c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/studio.h" 464c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/artifact.h" 474c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/attribute.h" 484c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/blob.h" 494c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/blob-private.h" 504c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/cache.h" 5118c0e4dff391a0a98e7f478d0d86bbd08f7708d0dirk#include "MagickCore/channel.h" 524c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/colormap.h" 53f432c635c526259b858c9aad3d409c5c44545686cristy#include "MagickCore/colormap-private.h" 544c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/colorspace.h" 55510d06a3f7063e91993e13d546d5685048248074cristy#include "MagickCore/colorspace-private.h" 564c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/constitute.h" 574c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/enhance.h" 584c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/exception.h" 594c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/exception-private.h" 604c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/image.h" 614c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/image-private.h" 624c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/list.h" 634c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/log.h" 644c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/magick.h" 654c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/memory_.h" 664c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/module.h" 674c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/monitor-private.h" 68b20a1794de28edf28c46f2268914c15781482530dirk#include "MagickCore/option.h" 694c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/pixel.h" 704c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/pixel-accessor.h" 714c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/profile.h" 724c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/property.h" 734c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/quantum-private.h" 744c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/static.h" 754c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/string_.h" 76b20a1794de28edf28c46f2268914c15781482530dirk#include "MagickCore/thread-private.h" 77b41f080d52a5ff2d9c235cffac1419b84028bd31dirk#ifdef MAGICKCORE_ZLIB_DELEGATE 78b41f080d52a5ff2d9c235cffac1419b84028bd31dirk#include <zlib.h> 79b41f080d52a5ff2d9c235cffac1419b84028bd31dirk#endif 8014c08dcd1910ecd8360f51d13885b2c9c39b655ddirk#include "psd-private.h" 8114c08dcd1910ecd8360f51d13885b2c9c39b655ddirk 823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 832d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy Define declaractions. 842d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy*/ 85aca3ec5b866931810b1d66b13099129a6fbe1b39cristy#define MaxPSDChannels 56 86bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy#define PSDQuantum(x) (((ssize_t) (x)+1) & -2) 872d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy 882d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy/* 892d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy Enumerated declaractions. 902d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy*/ 912d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristytypedef enum 922d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy{ 93b41f080d52a5ff2d9c235cffac1419b84028bd31dirk Raw = 0, 94b41f080d52a5ff2d9c235cffac1419b84028bd31dirk RLE = 1, 95b41f080d52a5ff2d9c235cffac1419b84028bd31dirk ZipWithoutPrediction = 2, 96b41f080d52a5ff2d9c235cffac1419b84028bd31dirk ZipWithPrediction = 3 97b41f080d52a5ff2d9c235cffac1419b84028bd31dirk} PSDCompressionType; 98b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 99b41f080d52a5ff2d9c235cffac1419b84028bd31dirktypedef enum 100b41f080d52a5ff2d9c235cffac1419b84028bd31dirk{ 1012d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy BitmapMode = 0, 1022d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy GrayscaleMode = 1, 1032d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy IndexedMode = 2, 1042d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy RGBMode = 3, 1052d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy CMYKMode = 4, 1062d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy MultichannelMode = 7, 1072d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy DuotoneMode = 8, 1082d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy LabMode = 9 1092d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy} PSDImageType; 1102d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy 1112d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy/* 1122d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy Typedef declaractions. 1132d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy*/ 1142d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristytypedef struct _ChannelInfo 1152d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy{ 1162d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy short int 1172d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy type; 1182d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy 119bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy size_t 1202d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy size; 1212d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy} ChannelInfo; 1222d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy 123a41d97fa7de942f144af6cfcceba24c523775c54dirktypedef struct _MaskInfo 1242d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy{ 125a41d97fa7de942f144af6cfcceba24c523775c54dirk Image 126a41d97fa7de942f144af6cfcceba24c523775c54dirk *image; 127a41d97fa7de942f144af6cfcceba24c523775c54dirk 1282d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy RectangleInfo 129a41d97fa7de942f144af6cfcceba24c523775c54dirk page; 1302d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy 131a41d97fa7de942f144af6cfcceba24c523775c54dirk unsigned char 132a41d97fa7de942f144af6cfcceba24c523775c54dirk background, 133a41d97fa7de942f144af6cfcceba24c523775c54dirk flags; 134a41d97fa7de942f144af6cfcceba24c523775c54dirk} MaskInfo; 1352d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy 136a41d97fa7de942f144af6cfcceba24c523775c54dirktypedef struct _LayerInfo 137a41d97fa7de942f144af6cfcceba24c523775c54dirk{ 1382d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy ChannelInfo 1392d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy channel_info[MaxPSDChannels]; 1402d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy 1412d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy char 1422d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy blendkey[4]; 1432d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy 144a41d97fa7de942f144af6cfcceba24c523775c54dirk Image 145a41d97fa7de942f144af6cfcceba24c523775c54dirk *image; 146a41d97fa7de942f144af6cfcceba24c523775c54dirk 147a41d97fa7de942f144af6cfcceba24c523775c54dirk MaskInfo 148a41d97fa7de942f144af6cfcceba24c523775c54dirk mask; 149a41d97fa7de942f144af6cfcceba24c523775c54dirk 1502d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy Quantum 1512d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy opacity; 1522d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy 153a41d97fa7de942f144af6cfcceba24c523775c54dirk RectangleInfo 154a41d97fa7de942f144af6cfcceba24c523775c54dirk page; 1552d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy 156bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy size_t 1572d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy offset_x, 1582d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy offset_y; 1592d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy 1602d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy unsigned char 161a41d97fa7de942f144af6cfcceba24c523775c54dirk clipping, 162a41d97fa7de942f144af6cfcceba24c523775c54dirk flags, 163a41d97fa7de942f144af6cfcceba24c523775c54dirk name[256], 164a41d97fa7de942f144af6cfcceba24c523775c54dirk visible; 1652d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy 166a41d97fa7de942f144af6cfcceba24c523775c54dirk unsigned short 167a41d97fa7de942f144af6cfcceba24c523775c54dirk channels; 1682d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy} LayerInfo; 169a41d97fa7de942f144af6cfcceba24c523775c54dirk 1702d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy/* 1713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Forward declarations. 1723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 1733ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType 1743a37efd7ece979e9c63dc8f2f2d3816bab8b1156cristy WritePSDImage(const ImageInfo *,Image *,ExceptionInfo *); 1753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 1773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 1793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 1803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 1813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% I s P S D % 1823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 1833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 1843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 1853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 1873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% IsPSD()() returns MagickTrue if the image format type, identified by the 1883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% magick string, is PSD. 1893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 1903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% The format of the IsPSD method is: 1913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 1923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% MagickBooleanType IsPSD(const unsigned char *magick,const size_t length) 1933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 1943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows: 1953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 1963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o magick: compare image format pattern against these bytes. 1973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 1983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o length: Specifies the length of the magick string. 1993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 2003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 2013ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsPSD(const unsigned char *magick,const size_t length) 2023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 2033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (length < 4) 2043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickFalse); 2053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleNCompare((const char *) magick,"8BPS",4) == 0) 2063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickTrue); 2073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickFalse); 2083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 2093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 2113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 2133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 2143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 2153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% R e a d P S D I m a g e % 2163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 2173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 2183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 2193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 2213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% ReadPSDImage() reads an Adobe Photoshop image file and returns it. It 2223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% allocates the memory necessary for the new Image structure and returns a 2233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% pointer to the new image. 2243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 2253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% The format of the ReadPSDImage method is: 2263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 22790de83d3fe5221a8896ab53556c2e7992078a96ccristy% Image *ReadPSDImage(image_info,ExceptionInfo *exception) 2283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 2293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows: 2303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 2313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o image_info: the image info. 2323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 2333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o exception: return any errors or warnings in this structure. 2343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 2353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 2363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 23719eb64195ef744f61293025952df1e5e6de66524cristystatic const char *CompositeOperatorToPSDBlendMode(CompositeOperator op) 238cd0817764b65f779425ef95dfd90abbcf76d0a46cristy{ 239cd0817764b65f779425ef95dfd90abbcf76d0a46cristy const char 240cd0817764b65f779425ef95dfd90abbcf76d0a46cristy *blend_mode; 241cd0817764b65f779425ef95dfd90abbcf76d0a46cristy 24219eb64195ef744f61293025952df1e5e6de66524cristy switch (op) 243cd0817764b65f779425ef95dfd90abbcf76d0a46cristy { 244fdc035a228cf5dbcefcb3e86f57dfbfbfd77ee13cristy case ColorBurnCompositeOp: blend_mode = "idiv"; break; 245fdc035a228cf5dbcefcb3e86f57dfbfbfd77ee13cristy case ColorDodgeCompositeOp: blend_mode = "div "; break; 246216b90f9cd72e8dbcc34653fe1e040ab4f876a5ecristy case ColorizeCompositeOp: blend_mode = "colr"; break; 247216b90f9cd72e8dbcc34653fe1e040ab4f876a5ecristy case DarkenCompositeOp: blend_mode = "dark"; break; 248216b90f9cd72e8dbcc34653fe1e040ab4f876a5ecristy case DifferenceCompositeOp: blend_mode = "diff"; break; 249216b90f9cd72e8dbcc34653fe1e040ab4f876a5ecristy case DissolveCompositeOp: blend_mode = "diss"; break; 250fdc035a228cf5dbcefcb3e86f57dfbfbfd77ee13cristy case ExclusionCompositeOp: blend_mode = "smud"; break; 251216b90f9cd72e8dbcc34653fe1e040ab4f876a5ecristy case HardLightCompositeOp: blend_mode = "hLit"; break; 252fdc035a228cf5dbcefcb3e86f57dfbfbfd77ee13cristy case HardMixCompositeOp: blend_mode = "hMix"; break; 253216b90f9cd72e8dbcc34653fe1e040ab4f876a5ecristy case HueCompositeOp: blend_mode = "hue "; break; 254216b90f9cd72e8dbcc34653fe1e040ab4f876a5ecristy case LightenCompositeOp: blend_mode = "lite"; break; 255fdc035a228cf5dbcefcb3e86f57dfbfbfd77ee13cristy case LinearBurnCompositeOp: blend_mode = "lbrn"; break; 256fdc035a228cf5dbcefcb3e86f57dfbfbfd77ee13cristy case LinearDodgeCompositeOp:blend_mode = "lddg"; break; 257fdc035a228cf5dbcefcb3e86f57dfbfbfd77ee13cristy case LinearLightCompositeOp:blend_mode = "lLit"; break; 258216b90f9cd72e8dbcc34653fe1e040ab4f876a5ecristy case LuminizeCompositeOp: blend_mode = "lum "; break; 259216b90f9cd72e8dbcc34653fe1e040ab4f876a5ecristy case MultiplyCompositeOp: blend_mode = "mul "; break; 260216b90f9cd72e8dbcc34653fe1e040ab4f876a5ecristy case OverCompositeOp: blend_mode = "norm"; break; 261216b90f9cd72e8dbcc34653fe1e040ab4f876a5ecristy case OverlayCompositeOp: blend_mode = "over"; break; 262fdc035a228cf5dbcefcb3e86f57dfbfbfd77ee13cristy case PinLightCompositeOp: blend_mode = "pLit"; break; 263216b90f9cd72e8dbcc34653fe1e040ab4f876a5ecristy case SaturateCompositeOp: blend_mode = "sat "; break; 264216b90f9cd72e8dbcc34653fe1e040ab4f876a5ecristy case ScreenCompositeOp: blend_mode = "scrn"; break; 265216b90f9cd72e8dbcc34653fe1e040ab4f876a5ecristy case SoftLightCompositeOp: blend_mode = "sLit"; break; 266fdc035a228cf5dbcefcb3e86f57dfbfbfd77ee13cristy case VividLightCompositeOp: blend_mode = "vLit"; break; 267216b90f9cd72e8dbcc34653fe1e040ab4f876a5ecristy default: blend_mode = "norm"; 268cd0817764b65f779425ef95dfd90abbcf76d0a46cristy } 269cd0817764b65f779425ef95dfd90abbcf76d0a46cristy return(blend_mode); 270cd0817764b65f779425ef95dfd90abbcf76d0a46cristy} 271cd0817764b65f779425ef95dfd90abbcf76d0a46cristy 272b20a1794de28edf28c46f2268914c15781482530dirk/* 273b20a1794de28edf28c46f2268914c15781482530dirk For some reason Photoshop seems to blend semi-transparent pixels with white. 274b20a1794de28edf28c46f2268914c15781482530dirk This method reverts the blending. This can be disabled by setting the 275b20a1794de28edf28c46f2268914c15781482530dirk option 'psd:alpha-unblend' to off. 276b20a1794de28edf28c46f2268914c15781482530dirk*/ 277b20a1794de28edf28c46f2268914c15781482530dirkstatic MagickBooleanType CorrectPSDAlphaBlend(const ImageInfo *image_info, 278b20a1794de28edf28c46f2268914c15781482530dirk Image *image,ExceptionInfo* exception) 279b20a1794de28edf28c46f2268914c15781482530dirk{ 280b20a1794de28edf28c46f2268914c15781482530dirk const char 281b20a1794de28edf28c46f2268914c15781482530dirk *option; 282b20a1794de28edf28c46f2268914c15781482530dirk 283b20a1794de28edf28c46f2268914c15781482530dirk MagickBooleanType 284b20a1794de28edf28c46f2268914c15781482530dirk status; 285b20a1794de28edf28c46f2268914c15781482530dirk 286b20a1794de28edf28c46f2268914c15781482530dirk ssize_t 287b20a1794de28edf28c46f2268914c15781482530dirk y; 288b20a1794de28edf28c46f2268914c15781482530dirk 289b20a1794de28edf28c46f2268914c15781482530dirk if (image->alpha_trait != BlendPixelTrait || image->colorspace != sRGBColorspace) 290b20a1794de28edf28c46f2268914c15781482530dirk return(MagickTrue); 291b20a1794de28edf28c46f2268914c15781482530dirk option=GetImageOption(image_info,"psd:alpha-unblend"); 292b20a1794de28edf28c46f2268914c15781482530dirk if (IsStringFalse(option) != MagickFalse) 293b20a1794de28edf28c46f2268914c15781482530dirk return(MagickTrue); 294b20a1794de28edf28c46f2268914c15781482530dirk status=MagickTrue; 295b20a1794de28edf28c46f2268914c15781482530dirk#if defined(MAGICKCORE_OPENMP_SUPPORT) 296b20a1794de28edf28c46f2268914c15781482530dirk#pragma omp parallel for schedule(static,4) shared(status) \ 297b20a1794de28edf28c46f2268914c15781482530dirk magick_threads(image,image,image->rows,1) 298b20a1794de28edf28c46f2268914c15781482530dirk#endif 299b20a1794de28edf28c46f2268914c15781482530dirk for (y=0; y < (ssize_t) image->rows; y++) 300b20a1794de28edf28c46f2268914c15781482530dirk { 301b20a1794de28edf28c46f2268914c15781482530dirk register Quantum 30205d2ff7ebf21f659f5b11e45afb294e152f4330cdirk *magick_restrict q; 303b20a1794de28edf28c46f2268914c15781482530dirk 304b20a1794de28edf28c46f2268914c15781482530dirk register ssize_t 305b20a1794de28edf28c46f2268914c15781482530dirk x; 306b20a1794de28edf28c46f2268914c15781482530dirk 307b20a1794de28edf28c46f2268914c15781482530dirk if (status == MagickFalse) 308b20a1794de28edf28c46f2268914c15781482530dirk continue; 309b20a1794de28edf28c46f2268914c15781482530dirk q=GetAuthenticPixels(image,0,y,image->columns,1,exception); 310b20a1794de28edf28c46f2268914c15781482530dirk if (q == (Quantum *) NULL) 311b20a1794de28edf28c46f2268914c15781482530dirk { 312b20a1794de28edf28c46f2268914c15781482530dirk status=MagickFalse; 313b20a1794de28edf28c46f2268914c15781482530dirk continue; 314b20a1794de28edf28c46f2268914c15781482530dirk } 315b20a1794de28edf28c46f2268914c15781482530dirk for (x=0; x < (ssize_t) image->columns; x++) 316b20a1794de28edf28c46f2268914c15781482530dirk { 317b20a1794de28edf28c46f2268914c15781482530dirk double 318b20a1794de28edf28c46f2268914c15781482530dirk gamma; 319b20a1794de28edf28c46f2268914c15781482530dirk 320b20a1794de28edf28c46f2268914c15781482530dirk register ssize_t 321b20a1794de28edf28c46f2268914c15781482530dirk i; 322b20a1794de28edf28c46f2268914c15781482530dirk 323b20a1794de28edf28c46f2268914c15781482530dirk gamma=QuantumScale*GetPixelAlpha(image, q); 324b20a1794de28edf28c46f2268914c15781482530dirk if (gamma != 0.0 && gamma != 1.0) 325b20a1794de28edf28c46f2268914c15781482530dirk { 326b20a1794de28edf28c46f2268914c15781482530dirk for (i=0; i < (ssize_t) GetPixelChannels(image); i++) 327b20a1794de28edf28c46f2268914c15781482530dirk { 328b20a1794de28edf28c46f2268914c15781482530dirk PixelChannel channel=GetPixelChannelChannel(image,i); 329b20a1794de28edf28c46f2268914c15781482530dirk if (channel != AlphaPixelChannel) 330b20a1794de28edf28c46f2268914c15781482530dirk q[i]=ClampToQuantum((q[i]-((1.0-gamma)*QuantumRange))/gamma); 331b20a1794de28edf28c46f2268914c15781482530dirk } 332b20a1794de28edf28c46f2268914c15781482530dirk } 333b20a1794de28edf28c46f2268914c15781482530dirk q+=GetPixelChannels(image); 334b20a1794de28edf28c46f2268914c15781482530dirk } 335b20a1794de28edf28c46f2268914c15781482530dirk if (SyncAuthenticPixels(image,exception) == MagickFalse) 336b20a1794de28edf28c46f2268914c15781482530dirk status=MagickFalse; 337b20a1794de28edf28c46f2268914c15781482530dirk } 338b20a1794de28edf28c46f2268914c15781482530dirk 339b20a1794de28edf28c46f2268914c15781482530dirk return(status); 340b20a1794de28edf28c46f2268914c15781482530dirk} 341b20a1794de28edf28c46f2268914c15781482530dirk 342b41f080d52a5ff2d9c235cffac1419b84028bd31dirkstatic inline CompressionType ConvertPSDCompression( 343b41f080d52a5ff2d9c235cffac1419b84028bd31dirk PSDCompressionType compression) 344b41f080d52a5ff2d9c235cffac1419b84028bd31dirk{ 345b41f080d52a5ff2d9c235cffac1419b84028bd31dirk switch (compression) 346b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 347b41f080d52a5ff2d9c235cffac1419b84028bd31dirk case RLE: 348b41f080d52a5ff2d9c235cffac1419b84028bd31dirk return RLECompression; 349b41f080d52a5ff2d9c235cffac1419b84028bd31dirk case ZipWithPrediction: 350b41f080d52a5ff2d9c235cffac1419b84028bd31dirk case ZipWithoutPrediction: 351b41f080d52a5ff2d9c235cffac1419b84028bd31dirk return ZipCompression; 352b41f080d52a5ff2d9c235cffac1419b84028bd31dirk default: 353b41f080d52a5ff2d9c235cffac1419b84028bd31dirk return NoCompression; 354b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 355b41f080d52a5ff2d9c235cffac1419b84028bd31dirk} 356b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 357b20a1794de28edf28c46f2268914c15781482530dirkstatic MagickBooleanType CorrectPSDOpacity(LayerInfo *layer_info, 358b41f080d52a5ff2d9c235cffac1419b84028bd31dirk ExceptionInfo *exception) 359b41f080d52a5ff2d9c235cffac1419b84028bd31dirk{ 360b20a1794de28edf28c46f2268914c15781482530dirk MagickBooleanType 361b20a1794de28edf28c46f2268914c15781482530dirk status; 362b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 363b41f080d52a5ff2d9c235cffac1419b84028bd31dirk ssize_t 364b41f080d52a5ff2d9c235cffac1419b84028bd31dirk y; 365b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 366b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (layer_info->opacity == OpaqueAlpha) 367b41f080d52a5ff2d9c235cffac1419b84028bd31dirk return(MagickTrue); 368b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 369b41f080d52a5ff2d9c235cffac1419b84028bd31dirk layer_info->image->alpha_trait=BlendPixelTrait; 370b20a1794de28edf28c46f2268914c15781482530dirk status=MagickTrue; 371b20a1794de28edf28c46f2268914c15781482530dirk#if defined(MAGICKCORE_OPENMP_SUPPORT) 372b20a1794de28edf28c46f2268914c15781482530dirk#pragma omp parallel for schedule(static,4) shared(status) \ 373b20a1794de28edf28c46f2268914c15781482530dirk magick_threads(layer_info->image,layer_info->image,layer_info->image->rows,1) 374b20a1794de28edf28c46f2268914c15781482530dirk#endif 375b41f080d52a5ff2d9c235cffac1419b84028bd31dirk for (y=0; y < (ssize_t) layer_info->image->rows; y++) 376b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 377b20a1794de28edf28c46f2268914c15781482530dirk register Quantum 37805d2ff7ebf21f659f5b11e45afb294e152f4330cdirk *magick_restrict q; 379b20a1794de28edf28c46f2268914c15781482530dirk 380b20a1794de28edf28c46f2268914c15781482530dirk register ssize_t 381b20a1794de28edf28c46f2268914c15781482530dirk x; 382b20a1794de28edf28c46f2268914c15781482530dirk 383b20a1794de28edf28c46f2268914c15781482530dirk if (status == MagickFalse) 384b20a1794de28edf28c46f2268914c15781482530dirk continue; 385d8083a693bea157df66921cb7570880bb081dcd1cristy q=GetAuthenticPixels(layer_info->image,0,y,layer_info->image->columns,1, 386d8083a693bea157df66921cb7570880bb081dcd1cristy exception); 387b20a1794de28edf28c46f2268914c15781482530dirk if (q == (Quantum *)NULL) 388b20a1794de28edf28c46f2268914c15781482530dirk { 389b20a1794de28edf28c46f2268914c15781482530dirk status=MagickFalse; 390b20a1794de28edf28c46f2268914c15781482530dirk continue; 391b20a1794de28edf28c46f2268914c15781482530dirk } 392b41f080d52a5ff2d9c235cffac1419b84028bd31dirk for (x=0; x < (ssize_t) layer_info->image->columns; x++) 393b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 394b41f080d52a5ff2d9c235cffac1419b84028bd31dirk SetPixelAlpha(layer_info->image,(Quantum) (QuantumScale*(GetPixelAlpha( 395b41f080d52a5ff2d9c235cffac1419b84028bd31dirk layer_info->image,q))*layer_info->opacity),q); 396b41f080d52a5ff2d9c235cffac1419b84028bd31dirk q+=GetPixelChannels(layer_info->image); 397b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 398b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (SyncAuthenticPixels(layer_info->image,exception) == MagickFalse) 399b20a1794de28edf28c46f2268914c15781482530dirk status=MagickFalse; 400b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 401b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 402b20a1794de28edf28c46f2268914c15781482530dirk return(status); 403b41f080d52a5ff2d9c235cffac1419b84028bd31dirk} 404b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 405cd0817764b65f779425ef95dfd90abbcf76d0a46cristystatic ssize_t DecodePSDPixels(const size_t number_compact_pixels, 406bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy const unsigned char *compact_pixels,const ssize_t depth, 407cd0817764b65f779425ef95dfd90abbcf76d0a46cristy const size_t number_pixels,unsigned char *pixels) 408cd0817764b65f779425ef95dfd90abbcf76d0a46cristy{ 409891df41d828a641db63d8bae45ca027d0e28341ddirk#define CheckNumberCompactPixels \ 410891df41d828a641db63d8bae45ca027d0e28341ddirk if (packets == 0) \ 411891df41d828a641db63d8bae45ca027d0e28341ddirk return(i); \ 412891df41d828a641db63d8bae45ca027d0e28341ddirk packets-- 413891df41d828a641db63d8bae45ca027d0e28341ddirk 414891df41d828a641db63d8bae45ca027d0e28341ddirk#define CheckNumberPixels(count) \ 415891df41d828a641db63d8bae45ca027d0e28341ddirk if (((ssize_t) i + count) > (ssize_t) number_pixels) \ 416891df41d828a641db63d8bae45ca027d0e28341ddirk return(i); \ 417891df41d828a641db63d8bae45ca027d0e28341ddirk i+=count 418891df41d828a641db63d8bae45ca027d0e28341ddirk 419cd0817764b65f779425ef95dfd90abbcf76d0a46cristy int 420cd0817764b65f779425ef95dfd90abbcf76d0a46cristy pixel; 421cd0817764b65f779425ef95dfd90abbcf76d0a46cristy 422cd0817764b65f779425ef95dfd90abbcf76d0a46cristy register ssize_t 423cd0817764b65f779425ef95dfd90abbcf76d0a46cristy i, 424cd0817764b65f779425ef95dfd90abbcf76d0a46cristy j; 425cd0817764b65f779425ef95dfd90abbcf76d0a46cristy 426cd0817764b65f779425ef95dfd90abbcf76d0a46cristy size_t 427cd0817764b65f779425ef95dfd90abbcf76d0a46cristy length; 428cd0817764b65f779425ef95dfd90abbcf76d0a46cristy 429802d364f093d693396e7052869766dd9fbe4d94bcristy ssize_t 430802d364f093d693396e7052869766dd9fbe4d94bcristy packets; 431802d364f093d693396e7052869766dd9fbe4d94bcristy 432cd0817764b65f779425ef95dfd90abbcf76d0a46cristy packets=(ssize_t) number_compact_pixels; 433cd0817764b65f779425ef95dfd90abbcf76d0a46cristy for (i=0; (packets > 1) && (i < (ssize_t) number_pixels); ) 434cd0817764b65f779425ef95dfd90abbcf76d0a46cristy { 435db435e2035e894ad4e7bda613cc95bb02ca4dac3dirk packets--; 43640084fae9e39c89210ccb4a80dcdd32fc16e640edirk length=(size_t) (*compact_pixels++); 437cd0817764b65f779425ef95dfd90abbcf76d0a46cristy if (length == 128) 438cd0817764b65f779425ef95dfd90abbcf76d0a46cristy continue; 439cd0817764b65f779425ef95dfd90abbcf76d0a46cristy if (length > 128) 440cd0817764b65f779425ef95dfd90abbcf76d0a46cristy { 441cd0817764b65f779425ef95dfd90abbcf76d0a46cristy length=256-length+1; 442891df41d828a641db63d8bae45ca027d0e28341ddirk CheckNumberCompactPixels; 443cd0817764b65f779425ef95dfd90abbcf76d0a46cristy pixel=(*compact_pixels++); 444284c7d8f94022fc8106d28e9659bd4e4ff2154ffcristy for (j=0; j < (ssize_t) length; j++) 445cd0817764b65f779425ef95dfd90abbcf76d0a46cristy { 446cd0817764b65f779425ef95dfd90abbcf76d0a46cristy switch (depth) 447cd0817764b65f779425ef95dfd90abbcf76d0a46cristy { 448cd0817764b65f779425ef95dfd90abbcf76d0a46cristy case 1: 449cd0817764b65f779425ef95dfd90abbcf76d0a46cristy { 450891df41d828a641db63d8bae45ca027d0e28341ddirk CheckNumberPixels(8); 451284c7d8f94022fc8106d28e9659bd4e4ff2154ffcristy *pixels++=(pixel >> 7) & 0x01 ? 0U : 255U; 452284c7d8f94022fc8106d28e9659bd4e4ff2154ffcristy *pixels++=(pixel >> 6) & 0x01 ? 0U : 255U; 453284c7d8f94022fc8106d28e9659bd4e4ff2154ffcristy *pixels++=(pixel >> 5) & 0x01 ? 0U : 255U; 454284c7d8f94022fc8106d28e9659bd4e4ff2154ffcristy *pixels++=(pixel >> 4) & 0x01 ? 0U : 255U; 455284c7d8f94022fc8106d28e9659bd4e4ff2154ffcristy *pixels++=(pixel >> 3) & 0x01 ? 0U : 255U; 456284c7d8f94022fc8106d28e9659bd4e4ff2154ffcristy *pixels++=(pixel >> 2) & 0x01 ? 0U : 255U; 457284c7d8f94022fc8106d28e9659bd4e4ff2154ffcristy *pixels++=(pixel >> 1) & 0x01 ? 0U : 255U; 458284c7d8f94022fc8106d28e9659bd4e4ff2154ffcristy *pixels++=(pixel >> 0) & 0x01 ? 0U : 255U; 459cd0817764b65f779425ef95dfd90abbcf76d0a46cristy break; 460cd0817764b65f779425ef95dfd90abbcf76d0a46cristy } 461cd0817764b65f779425ef95dfd90abbcf76d0a46cristy case 2: 462cd0817764b65f779425ef95dfd90abbcf76d0a46cristy { 463891df41d828a641db63d8bae45ca027d0e28341ddirk CheckNumberPixels(4); 464284c7d8f94022fc8106d28e9659bd4e4ff2154ffcristy *pixels++=(unsigned char) ((pixel >> 6) & 0x03); 465284c7d8f94022fc8106d28e9659bd4e4ff2154ffcristy *pixels++=(unsigned char) ((pixel >> 4) & 0x03); 466284c7d8f94022fc8106d28e9659bd4e4ff2154ffcristy *pixels++=(unsigned char) ((pixel >> 2) & 0x03); 467284c7d8f94022fc8106d28e9659bd4e4ff2154ffcristy *pixels++=(unsigned char) ((pixel & 0x03) & 0x03); 468891df41d828a641db63d8bae45ca027d0e28341ddirk break; 469891df41d828a641db63d8bae45ca027d0e28341ddirk } 470891df41d828a641db63d8bae45ca027d0e28341ddirk case 4: 471891df41d828a641db63d8bae45ca027d0e28341ddirk { 472891df41d828a641db63d8bae45ca027d0e28341ddirk CheckNumberPixels(2); 473891df41d828a641db63d8bae45ca027d0e28341ddirk *pixels++=(unsigned char) ((pixel >> 4) & 0xff); 474891df41d828a641db63d8bae45ca027d0e28341ddirk *pixels++=(unsigned char) ((pixel & 0x0f) & 0xff); 475cd0817764b65f779425ef95dfd90abbcf76d0a46cristy break; 476cd0817764b65f779425ef95dfd90abbcf76d0a46cristy } 477cd0817764b65f779425ef95dfd90abbcf76d0a46cristy default: 478cd0817764b65f779425ef95dfd90abbcf76d0a46cristy { 479891df41d828a641db63d8bae45ca027d0e28341ddirk CheckNumberPixels(1); 480284c7d8f94022fc8106d28e9659bd4e4ff2154ffcristy *pixels++=(unsigned char) pixel; 481cd0817764b65f779425ef95dfd90abbcf76d0a46cristy break; 482cd0817764b65f779425ef95dfd90abbcf76d0a46cristy } 483cd0817764b65f779425ef95dfd90abbcf76d0a46cristy } 484cd0817764b65f779425ef95dfd90abbcf76d0a46cristy } 485cd0817764b65f779425ef95dfd90abbcf76d0a46cristy continue; 486cd0817764b65f779425ef95dfd90abbcf76d0a46cristy } 487cd0817764b65f779425ef95dfd90abbcf76d0a46cristy length++; 488284c7d8f94022fc8106d28e9659bd4e4ff2154ffcristy for (j=0; j < (ssize_t) length; j++) 489cd0817764b65f779425ef95dfd90abbcf76d0a46cristy { 49030eec879c8b446b0ea9a3bb0da1a441cc8482bc4dirk CheckNumberCompactPixels; 491cd0817764b65f779425ef95dfd90abbcf76d0a46cristy switch (depth) 492cd0817764b65f779425ef95dfd90abbcf76d0a46cristy { 493cd0817764b65f779425ef95dfd90abbcf76d0a46cristy case 1: 494cd0817764b65f779425ef95dfd90abbcf76d0a46cristy { 495891df41d828a641db63d8bae45ca027d0e28341ddirk CheckNumberPixels(8); 496284c7d8f94022fc8106d28e9659bd4e4ff2154ffcristy *pixels++=(*compact_pixels >> 7) & 0x01 ? 0U : 255U; 497284c7d8f94022fc8106d28e9659bd4e4ff2154ffcristy *pixels++=(*compact_pixels >> 6) & 0x01 ? 0U : 255U; 498284c7d8f94022fc8106d28e9659bd4e4ff2154ffcristy *pixels++=(*compact_pixels >> 5) & 0x01 ? 0U : 255U; 499284c7d8f94022fc8106d28e9659bd4e4ff2154ffcristy *pixels++=(*compact_pixels >> 4) & 0x01 ? 0U : 255U; 500284c7d8f94022fc8106d28e9659bd4e4ff2154ffcristy *pixels++=(*compact_pixels >> 3) & 0x01 ? 0U : 255U; 501284c7d8f94022fc8106d28e9659bd4e4ff2154ffcristy *pixels++=(*compact_pixels >> 2) & 0x01 ? 0U : 255U; 502284c7d8f94022fc8106d28e9659bd4e4ff2154ffcristy *pixels++=(*compact_pixels >> 1) & 0x01 ? 0U : 255U; 503284c7d8f94022fc8106d28e9659bd4e4ff2154ffcristy *pixels++=(*compact_pixels >> 0) & 0x01 ? 0U : 255U; 504cd0817764b65f779425ef95dfd90abbcf76d0a46cristy break; 505cd0817764b65f779425ef95dfd90abbcf76d0a46cristy } 506cd0817764b65f779425ef95dfd90abbcf76d0a46cristy case 2: 507cd0817764b65f779425ef95dfd90abbcf76d0a46cristy { 508891df41d828a641db63d8bae45ca027d0e28341ddirk CheckNumberPixels(4); 509618a96665a51cb540c998330e660f1c7506f6b08cristy *pixels++=(*compact_pixels >> 6) & 0x03; 510618a96665a51cb540c998330e660f1c7506f6b08cristy *pixels++=(*compact_pixels >> 4) & 0x03; 511618a96665a51cb540c998330e660f1c7506f6b08cristy *pixels++=(*compact_pixels >> 2) & 0x03; 512618a96665a51cb540c998330e660f1c7506f6b08cristy *pixels++=(*compact_pixels & 0x03) & 0x03; 513891df41d828a641db63d8bae45ca027d0e28341ddirk break; 514891df41d828a641db63d8bae45ca027d0e28341ddirk } 515891df41d828a641db63d8bae45ca027d0e28341ddirk case 4: 516891df41d828a641db63d8bae45ca027d0e28341ddirk { 517891df41d828a641db63d8bae45ca027d0e28341ddirk CheckNumberPixels(2); 518891df41d828a641db63d8bae45ca027d0e28341ddirk *pixels++=(*compact_pixels >> 4) & 0xff; 519891df41d828a641db63d8bae45ca027d0e28341ddirk *pixels++=(*compact_pixels & 0x0f) & 0xff; 520cd0817764b65f779425ef95dfd90abbcf76d0a46cristy break; 521cd0817764b65f779425ef95dfd90abbcf76d0a46cristy } 522cd0817764b65f779425ef95dfd90abbcf76d0a46cristy default: 523cd0817764b65f779425ef95dfd90abbcf76d0a46cristy { 524891df41d828a641db63d8bae45ca027d0e28341ddirk CheckNumberPixels(1); 525cd0817764b65f779425ef95dfd90abbcf76d0a46cristy *pixels++=(*compact_pixels); 526cd0817764b65f779425ef95dfd90abbcf76d0a46cristy break; 527cd0817764b65f779425ef95dfd90abbcf76d0a46cristy } 528cd0817764b65f779425ef95dfd90abbcf76d0a46cristy } 529cd0817764b65f779425ef95dfd90abbcf76d0a46cristy compact_pixels++; 530cd0817764b65f779425ef95dfd90abbcf76d0a46cristy } 531cd0817764b65f779425ef95dfd90abbcf76d0a46cristy } 532cd0817764b65f779425ef95dfd90abbcf76d0a46cristy return(i); 533cd0817764b65f779425ef95dfd90abbcf76d0a46cristy} 534cd0817764b65f779425ef95dfd90abbcf76d0a46cristy 535bd8bd8572e272ce0bc730bfa0296b8f048ea2da1dirkstatic inline LayerInfo *DestroyLayerInfo(LayerInfo *layer_info, 536bd8bd8572e272ce0bc730bfa0296b8f048ea2da1dirk const ssize_t number_layers) 537bd8bd8572e272ce0bc730bfa0296b8f048ea2da1dirk{ 538bd8bd8572e272ce0bc730bfa0296b8f048ea2da1dirk ssize_t 539bd8bd8572e272ce0bc730bfa0296b8f048ea2da1dirk i; 540bd8bd8572e272ce0bc730bfa0296b8f048ea2da1dirk 541bd8bd8572e272ce0bc730bfa0296b8f048ea2da1dirk for (i=0; i<number_layers; i++) 542bd8bd8572e272ce0bc730bfa0296b8f048ea2da1dirk { 543bd8bd8572e272ce0bc730bfa0296b8f048ea2da1dirk if (layer_info[i].image != (Image *) NULL) 544bd8bd8572e272ce0bc730bfa0296b8f048ea2da1dirk layer_info[i].image=DestroyImage(layer_info[i].image); 545a41d97fa7de942f144af6cfcceba24c523775c54dirk if (layer_info[i].mask.image != (Image *) NULL) 546a41d97fa7de942f144af6cfcceba24c523775c54dirk layer_info[i].mask.image=DestroyImage(layer_info[i].mask.image); 547bd8bd8572e272ce0bc730bfa0296b8f048ea2da1dirk } 548bd8bd8572e272ce0bc730bfa0296b8f048ea2da1dirk 549bd8bd8572e272ce0bc730bfa0296b8f048ea2da1dirk return (LayerInfo *) RelinquishMagickMemory(layer_info); 550bd8bd8572e272ce0bc730bfa0296b8f048ea2da1dirk} 551bd8bd8572e272ce0bc730bfa0296b8f048ea2da1dirk 552b41f080d52a5ff2d9c235cffac1419b84028bd31dirkstatic inline size_t GetPSDPacketSize(Image *image) 5532d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy{ 554b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (image->storage_class == PseudoClass) 555b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 556b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (image->colors > 256) 557b41f080d52a5ff2d9c235cffac1419b84028bd31dirk return(2); 558b41f080d52a5ff2d9c235cffac1419b84028bd31dirk else if (image->depth > 8) 559b41f080d52a5ff2d9c235cffac1419b84028bd31dirk return(2); 560b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 561b41f080d52a5ff2d9c235cffac1419b84028bd31dirk else 562b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (image->depth > 8) 563b41f080d52a5ff2d9c235cffac1419b84028bd31dirk return(2); 564b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 565b41f080d52a5ff2d9c235cffac1419b84028bd31dirk return(1); 5662d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy} 5672d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy 5684d9863ca77e690fdde8653d1f3db0721bd25978edirkstatic inline MagickSizeType GetPSDSize(const PSDInfo *psd_info,Image *image) 5692d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy{ 5702d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy if (psd_info->version == 1) 57187038d5d4cc04fb99d6560ae95f3f07a87563323dirk return((MagickSizeType) ReadBlobLong(image)); 57287038d5d4cc04fb99d6560ae95f3f07a87563323dirk return((MagickSizeType) ReadBlobLongLong(image)); 5732d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy} 5742d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy 575b41f080d52a5ff2d9c235cffac1419b84028bd31dirkstatic inline size_t GetPSDRowSize(Image *image) 576b41f080d52a5ff2d9c235cffac1419b84028bd31dirk{ 577b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (image->depth == 1) 5785f16640725b1225e6337c62526e6577f0f88edb8dirk return(((image->columns+7)/8)*GetPSDPacketSize(image)); 579b41f080d52a5ff2d9c235cffac1419b84028bd31dirk else 580b41f080d52a5ff2d9c235cffac1419b84028bd31dirk return(image->columns*GetPSDPacketSize(image)); 581b41f080d52a5ff2d9c235cffac1419b84028bd31dirk} 582b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 583cd0817764b65f779425ef95dfd90abbcf76d0a46cristystatic const char *ModeToString(PSDImageType type) 5843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 585cd0817764b65f779425ef95dfd90abbcf76d0a46cristy switch (type) 5863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 5873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case BitmapMode: return "Bitmap"; 5883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case GrayscaleMode: return "Grayscale"; 5893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case IndexedMode: return "Indexed"; 5903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case RGBMode: return "RGB"; 5913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case CMYKMode: return "CMYK"; 5923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case MultichannelMode: return "Multichannel"; 5933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case DuotoneMode: return "Duotone"; 5943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case LabMode: return "L*A*B"; 5953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy default: return "unknown"; 5963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 5973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 5983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 599b20a1794de28edf28c46f2268914c15781482530dirkstatic MagickBooleanType NegateCMYK(Image *image,ExceptionInfo *exception) 600d9795a19984ae1bae9205b7c0fe5de75461978b3dirk{ 601d9795a19984ae1bae9205b7c0fe5de75461978b3dirk ChannelType 602d9795a19984ae1bae9205b7c0fe5de75461978b3dirk channel_mask; 603d9795a19984ae1bae9205b7c0fe5de75461978b3dirk 604b20a1794de28edf28c46f2268914c15781482530dirk MagickBooleanType 605b20a1794de28edf28c46f2268914c15781482530dirk status; 606b20a1794de28edf28c46f2268914c15781482530dirk 607d9795a19984ae1bae9205b7c0fe5de75461978b3dirk channel_mask=SetImageChannelMask(image,(ChannelType)(AllChannels &~ 608d9795a19984ae1bae9205b7c0fe5de75461978b3dirk AlphaChannel)); 609b20a1794de28edf28c46f2268914c15781482530dirk status=NegateImage(image,MagickFalse,exception); 610d9795a19984ae1bae9205b7c0fe5de75461978b3dirk (void) SetImageChannelMask(image,channel_mask); 611b20a1794de28edf28c46f2268914c15781482530dirk return(status); 612d9795a19984ae1bae9205b7c0fe5de75461978b3dirk} 613d9795a19984ae1bae9205b7c0fe5de75461978b3dirk 6147ec893210d13a7424e5a7c3200568f1bf5317040dirkstatic void ParseImageResourceBlocks(Image *image, 61518c0e4dff391a0a98e7f478d0d86bbd08f7708d0dirk const unsigned char *blocks,size_t length, 61618c0e4dff391a0a98e7f478d0d86bbd08f7708d0dirk MagickBooleanType *has_merged_image,ExceptionInfo *exception) 6173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 6183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const unsigned char 6193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *p; 6203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 6213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy StringInfo 6223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *profile; 6233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 6246befb0f8f253ef359d1e14d1e569c1a848d02daccristy unsigned int 6253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy count, 6266befb0f8f253ef359d1e14d1e569c1a848d02daccristy long_sans; 6273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 6283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned short 6293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy id, 6303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy short_sans; 6313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 6323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (length < 16) 6337ec893210d13a7424e5a7c3200568f1bf5317040dirk return; 634b3f97ae45019a91b30792a6fa42d81a2689a7025cristy profile=BlobToStringInfo((const unsigned char *) NULL,length); 6353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy SetStringInfoDatum(profile,blocks); 636d15e65928aec551b7388c2863de3e3e628e2e0ddcristy (void) SetImageProfile(image,"8bim",profile,exception); 6373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy profile=DestroyStringInfo(profile); 6383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (p=blocks; (p >= blocks) && (p < (blocks+length-16)); ) 6393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 6403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleNCompare((const char *) p,"8BIM",4) != 0) 6413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 6426befb0f8f253ef359d1e14d1e569c1a848d02daccristy p=PushLongPixel(MSBEndian,p,&long_sans); 643f11065e08c32a2c6a82e67ade789e83936724a8ecristy p=PushShortPixel(MSBEndian,p,&id); 644f11065e08c32a2c6a82e67ade789e83936724a8ecristy p=PushShortPixel(MSBEndian,p,&short_sans); 645f11065e08c32a2c6a82e67ade789e83936724a8ecristy p=PushLongPixel(MSBEndian,p,&count); 64615dd190dfd7e7a3341bdc378f4f0daba9873322cCristy if ((p+count) > (blocks+length-16)) 6477ec893210d13a7424e5a7c3200568f1bf5317040dirk return; 6483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy switch (id) 6493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 6503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case 0x03ed: 6513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 6521e4a80b77c1443fc8d04ed0e1abd9942598533decristy char 653151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy value[MagickPathExtent]; 6541e4a80b77c1443fc8d04ed0e1abd9942598533decristy 6553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned short 6563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy resolution; 6573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 6583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 6593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Resolution info. 6603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 661f11065e08c32a2c6a82e67ade789e83936724a8ecristy p=PushShortPixel(MSBEndian,p,&resolution); 6622a11befa48257796843468409d77bb8cfb129cdccristy image->resolution.x=(double) resolution; 663151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy (void) FormatLocaleString(value,MagickPathExtent,"%g",image->resolution.x); 664d15e65928aec551b7388c2863de3e3e628e2e0ddcristy (void) SetImageProperty(image,"tiff:XResolution",value,exception); 665f11065e08c32a2c6a82e67ade789e83936724a8ecristy p=PushShortPixel(MSBEndian,p,&short_sans); 666f11065e08c32a2c6a82e67ade789e83936724a8ecristy p=PushShortPixel(MSBEndian,p,&short_sans); 667f11065e08c32a2c6a82e67ade789e83936724a8ecristy p=PushShortPixel(MSBEndian,p,&short_sans); 668f11065e08c32a2c6a82e67ade789e83936724a8ecristy p=PushShortPixel(MSBEndian,p,&resolution); 6692a11befa48257796843468409d77bb8cfb129cdccristy image->resolution.y=(double) resolution; 670151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy (void) FormatLocaleString(value,MagickPathExtent,"%g",image->resolution.y); 671d15e65928aec551b7388c2863de3e3e628e2e0ddcristy (void) SetImageProperty(image,"tiff:YResolution",value,exception); 672f11065e08c32a2c6a82e67ade789e83936724a8ecristy p=PushShortPixel(MSBEndian,p,&short_sans); 673f11065e08c32a2c6a82e67ade789e83936724a8ecristy p=PushShortPixel(MSBEndian,p,&short_sans); 674f11065e08c32a2c6a82e67ade789e83936724a8ecristy p=PushShortPixel(MSBEndian,p,&short_sans); 67515893bd52474061ede50d7b38b38788d4bd66b36cristy image->units=PixelsPerInchResolution; 6763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 6773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 67818c0e4dff391a0a98e7f478d0d86bbd08f7708d0dirk case 0x0421: 67918c0e4dff391a0a98e7f478d0d86bbd08f7708d0dirk { 68018c0e4dff391a0a98e7f478d0d86bbd08f7708d0dirk if (*(p+4) == 0) 68118c0e4dff391a0a98e7f478d0d86bbd08f7708d0dirk *has_merged_image=MagickFalse; 682c337843935542dbc968a24bfe1c7a25bf264836cdirk p+=count; 683c337843935542dbc968a24bfe1c7a25bf264836cdirk break; 68418c0e4dff391a0a98e7f478d0d86bbd08f7708d0dirk } 6853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy default: 6863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 6873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy p+=count; 6883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 6893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 6903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 6913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if ((count & 0x01) != 0) 6923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy p++; 6933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 6947ec893210d13a7424e5a7c3200568f1bf5317040dirk return; 6953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 6963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 697cd0817764b65f779425ef95dfd90abbcf76d0a46cristystatic CompositeOperator PSDBlendModeToCompositeOperator(const char *mode) 69856ed31cc763800a9fb1f0df96104c354b40d2cbccristy{ 699cd0817764b65f779425ef95dfd90abbcf76d0a46cristy if (mode == (const char *) NULL) 700cd0817764b65f779425ef95dfd90abbcf76d0a46cristy return(OverCompositeOp); 701cd0817764b65f779425ef95dfd90abbcf76d0a46cristy if (LocaleNCompare(mode,"norm",4) == 0) 702cd0817764b65f779425ef95dfd90abbcf76d0a46cristy return(OverCompositeOp); 703cd0817764b65f779425ef95dfd90abbcf76d0a46cristy if (LocaleNCompare(mode,"mul ",4) == 0) 704cd0817764b65f779425ef95dfd90abbcf76d0a46cristy return(MultiplyCompositeOp); 705cd0817764b65f779425ef95dfd90abbcf76d0a46cristy if (LocaleNCompare(mode,"diss",4) == 0) 706cd0817764b65f779425ef95dfd90abbcf76d0a46cristy return(DissolveCompositeOp); 707cd0817764b65f779425ef95dfd90abbcf76d0a46cristy if (LocaleNCompare(mode,"diff",4) == 0) 708cd0817764b65f779425ef95dfd90abbcf76d0a46cristy return(DifferenceCompositeOp); 709cd0817764b65f779425ef95dfd90abbcf76d0a46cristy if (LocaleNCompare(mode,"dark",4) == 0) 710cd0817764b65f779425ef95dfd90abbcf76d0a46cristy return(DarkenCompositeOp); 711cd0817764b65f779425ef95dfd90abbcf76d0a46cristy if (LocaleNCompare(mode,"lite",4) == 0) 712cd0817764b65f779425ef95dfd90abbcf76d0a46cristy return(LightenCompositeOp); 713cd0817764b65f779425ef95dfd90abbcf76d0a46cristy if (LocaleNCompare(mode,"hue ",4) == 0) 714cd0817764b65f779425ef95dfd90abbcf76d0a46cristy return(HueCompositeOp); 715cd0817764b65f779425ef95dfd90abbcf76d0a46cristy if (LocaleNCompare(mode,"sat ",4) == 0) 716cd0817764b65f779425ef95dfd90abbcf76d0a46cristy return(SaturateCompositeOp); 717cd0817764b65f779425ef95dfd90abbcf76d0a46cristy if (LocaleNCompare(mode,"colr",4) == 0) 718cd0817764b65f779425ef95dfd90abbcf76d0a46cristy return(ColorizeCompositeOp); 719cd0817764b65f779425ef95dfd90abbcf76d0a46cristy if (LocaleNCompare(mode,"lum ",4) == 0) 720cd0817764b65f779425ef95dfd90abbcf76d0a46cristy return(LuminizeCompositeOp); 721cd0817764b65f779425ef95dfd90abbcf76d0a46cristy if (LocaleNCompare(mode,"scrn",4) == 0) 722cd0817764b65f779425ef95dfd90abbcf76d0a46cristy return(ScreenCompositeOp); 723cd0817764b65f779425ef95dfd90abbcf76d0a46cristy if (LocaleNCompare(mode,"over",4) == 0) 724cd0817764b65f779425ef95dfd90abbcf76d0a46cristy return(OverlayCompositeOp); 725cd0817764b65f779425ef95dfd90abbcf76d0a46cristy if (LocaleNCompare(mode,"hLit",4) == 0) 726216b90f9cd72e8dbcc34653fe1e040ab4f876a5ecristy return(HardLightCompositeOp); 727cd0817764b65f779425ef95dfd90abbcf76d0a46cristy if (LocaleNCompare(mode,"sLit",4) == 0) 728216b90f9cd72e8dbcc34653fe1e040ab4f876a5ecristy return(SoftLightCompositeOp); 729cd0817764b65f779425ef95dfd90abbcf76d0a46cristy if (LocaleNCompare(mode,"smud",4) == 0) 730fdc035a228cf5dbcefcb3e86f57dfbfbfd77ee13cristy return(ExclusionCompositeOp); 731cd0817764b65f779425ef95dfd90abbcf76d0a46cristy if (LocaleNCompare(mode,"div ",4) == 0) 732fdc035a228cf5dbcefcb3e86f57dfbfbfd77ee13cristy return(ColorDodgeCompositeOp); 733cd0817764b65f779425ef95dfd90abbcf76d0a46cristy if (LocaleNCompare(mode,"idiv",4) == 0) 734fdc035a228cf5dbcefcb3e86f57dfbfbfd77ee13cristy return(ColorBurnCompositeOp); 735fdc035a228cf5dbcefcb3e86f57dfbfbfd77ee13cristy if (LocaleNCompare(mode,"lbrn",4) == 0) 736fdc035a228cf5dbcefcb3e86f57dfbfbfd77ee13cristy return(LinearBurnCompositeOp); 737fdc035a228cf5dbcefcb3e86f57dfbfbfd77ee13cristy if (LocaleNCompare(mode,"lddg",4) == 0) 738fdc035a228cf5dbcefcb3e86f57dfbfbfd77ee13cristy return(LinearDodgeCompositeOp); 739fdc035a228cf5dbcefcb3e86f57dfbfbfd77ee13cristy if (LocaleNCompare(mode,"lLit",4) == 0) 740fdc035a228cf5dbcefcb3e86f57dfbfbfd77ee13cristy return(LinearLightCompositeOp); 741fdc035a228cf5dbcefcb3e86f57dfbfbfd77ee13cristy if (LocaleNCompare(mode,"vLit",4) == 0) 742fdc035a228cf5dbcefcb3e86f57dfbfbfd77ee13cristy return(VividLightCompositeOp); 743fdc035a228cf5dbcefcb3e86f57dfbfbfd77ee13cristy if (LocaleNCompare(mode,"pLit",4) == 0) 744fdc035a228cf5dbcefcb3e86f57dfbfbfd77ee13cristy return(PinLightCompositeOp); 745fdc035a228cf5dbcefcb3e86f57dfbfbfd77ee13cristy if (LocaleNCompare(mode,"hMix",4) == 0) 746fdc035a228cf5dbcefcb3e86f57dfbfbfd77ee13cristy return(HardMixCompositeOp); 747cd0817764b65f779425ef95dfd90abbcf76d0a46cristy return(OverCompositeOp); 74856ed31cc763800a9fb1f0df96104c354b40d2cbccristy} 74956ed31cc763800a9fb1f0df96104c354b40d2cbccristy 75087038d5d4cc04fb99d6560ae95f3f07a87563323dirkstatic inline void ReversePSDString(Image *image,char *p,size_t length) 75187038d5d4cc04fb99d6560ae95f3f07a87563323dirk{ 75287038d5d4cc04fb99d6560ae95f3f07a87563323dirk char 75387038d5d4cc04fb99d6560ae95f3f07a87563323dirk *q; 75487038d5d4cc04fb99d6560ae95f3f07a87563323dirk 75587038d5d4cc04fb99d6560ae95f3f07a87563323dirk if (image->endian == MSBEndian) 75687038d5d4cc04fb99d6560ae95f3f07a87563323dirk return; 75787038d5d4cc04fb99d6560ae95f3f07a87563323dirk 75887038d5d4cc04fb99d6560ae95f3f07a87563323dirk q=p+length; 75987038d5d4cc04fb99d6560ae95f3f07a87563323dirk for(--q; p < q; ++p, --q) 76087038d5d4cc04fb99d6560ae95f3f07a87563323dirk { 76187038d5d4cc04fb99d6560ae95f3f07a87563323dirk *p = *p ^ *q, 76287038d5d4cc04fb99d6560ae95f3f07a87563323dirk *q = *p ^ *q, 76387038d5d4cc04fb99d6560ae95f3f07a87563323dirk *p = *p ^ *q; 76487038d5d4cc04fb99d6560ae95f3f07a87563323dirk } 76587038d5d4cc04fb99d6560ae95f3f07a87563323dirk} 76687038d5d4cc04fb99d6560ae95f3f07a87563323dirk 767280215b9936d145dd5ee91403738ccce1333cab1dirkstatic inline void SetPSDPixel(Image *image,const size_t channels, 768280215b9936d145dd5ee91403738ccce1333cab1dirk const ssize_t type,const size_t packet_size,const Quantum pixel,Quantum *q, 769280215b9936d145dd5ee91403738ccce1333cab1dirk ExceptionInfo *exception) 770280215b9936d145dd5ee91403738ccce1333cab1dirk{ 771280215b9936d145dd5ee91403738ccce1333cab1dirk if (image->storage_class == PseudoClass) 772280215b9936d145dd5ee91403738ccce1333cab1dirk { 773280215b9936d145dd5ee91403738ccce1333cab1dirk if (packet_size == 1) 774280215b9936d145dd5ee91403738ccce1333cab1dirk SetPixelIndex(image,ScaleQuantumToChar(pixel),q); 775280215b9936d145dd5ee91403738ccce1333cab1dirk else 776280215b9936d145dd5ee91403738ccce1333cab1dirk SetPixelIndex(image,ScaleQuantumToShort(pixel),q); 777280215b9936d145dd5ee91403738ccce1333cab1dirk SetPixelViaPixelInfo(image,image->colormap+(ssize_t) 778280215b9936d145dd5ee91403738ccce1333cab1dirk ConstrainColormapIndex(image,GetPixelIndex(image,q),exception),q); 779280215b9936d145dd5ee91403738ccce1333cab1dirk return; 780280215b9936d145dd5ee91403738ccce1333cab1dirk } 781280215b9936d145dd5ee91403738ccce1333cab1dirk switch (type) 782280215b9936d145dd5ee91403738ccce1333cab1dirk { 783280215b9936d145dd5ee91403738ccce1333cab1dirk case -1: 784280215b9936d145dd5ee91403738ccce1333cab1dirk { 785280215b9936d145dd5ee91403738ccce1333cab1dirk SetPixelAlpha(image, pixel,q); 786280215b9936d145dd5ee91403738ccce1333cab1dirk break; 787280215b9936d145dd5ee91403738ccce1333cab1dirk } 788280215b9936d145dd5ee91403738ccce1333cab1dirk case -2: 789280215b9936d145dd5ee91403738ccce1333cab1dirk case 0: 790280215b9936d145dd5ee91403738ccce1333cab1dirk { 791280215b9936d145dd5ee91403738ccce1333cab1dirk SetPixelRed(image,pixel,q); 792280215b9936d145dd5ee91403738ccce1333cab1dirk if (channels == 1 || type == -2) 793280215b9936d145dd5ee91403738ccce1333cab1dirk SetPixelGray(image,pixel,q); 794280215b9936d145dd5ee91403738ccce1333cab1dirk break; 795280215b9936d145dd5ee91403738ccce1333cab1dirk } 796280215b9936d145dd5ee91403738ccce1333cab1dirk case 1: 797280215b9936d145dd5ee91403738ccce1333cab1dirk { 798280215b9936d145dd5ee91403738ccce1333cab1dirk if (image->storage_class == PseudoClass) 799280215b9936d145dd5ee91403738ccce1333cab1dirk SetPixelAlpha(image,pixel,q); 800280215b9936d145dd5ee91403738ccce1333cab1dirk else 801280215b9936d145dd5ee91403738ccce1333cab1dirk SetPixelGreen(image,pixel,q); 802280215b9936d145dd5ee91403738ccce1333cab1dirk break; 803280215b9936d145dd5ee91403738ccce1333cab1dirk } 804280215b9936d145dd5ee91403738ccce1333cab1dirk case 2: 805280215b9936d145dd5ee91403738ccce1333cab1dirk { 806280215b9936d145dd5ee91403738ccce1333cab1dirk if (image->storage_class == PseudoClass) 807280215b9936d145dd5ee91403738ccce1333cab1dirk SetPixelAlpha(image,pixel,q); 808280215b9936d145dd5ee91403738ccce1333cab1dirk else 809280215b9936d145dd5ee91403738ccce1333cab1dirk SetPixelBlue(image,pixel,q); 810280215b9936d145dd5ee91403738ccce1333cab1dirk break; 811280215b9936d145dd5ee91403738ccce1333cab1dirk } 812280215b9936d145dd5ee91403738ccce1333cab1dirk case 3: 813280215b9936d145dd5ee91403738ccce1333cab1dirk { 814280215b9936d145dd5ee91403738ccce1333cab1dirk if (image->colorspace == CMYKColorspace) 815280215b9936d145dd5ee91403738ccce1333cab1dirk SetPixelBlack(image,pixel,q); 816280215b9936d145dd5ee91403738ccce1333cab1dirk else 817280215b9936d145dd5ee91403738ccce1333cab1dirk if (image->alpha_trait != UndefinedPixelTrait) 818280215b9936d145dd5ee91403738ccce1333cab1dirk SetPixelAlpha(image,pixel,q); 819280215b9936d145dd5ee91403738ccce1333cab1dirk break; 820280215b9936d145dd5ee91403738ccce1333cab1dirk } 821280215b9936d145dd5ee91403738ccce1333cab1dirk case 4: 822280215b9936d145dd5ee91403738ccce1333cab1dirk { 823280215b9936d145dd5ee91403738ccce1333cab1dirk if ((IssRGBCompatibleColorspace(image->colorspace) != MagickFalse) && 824280215b9936d145dd5ee91403738ccce1333cab1dirk (channels > 3)) 825280215b9936d145dd5ee91403738ccce1333cab1dirk break; 826280215b9936d145dd5ee91403738ccce1333cab1dirk if (image->alpha_trait != UndefinedPixelTrait) 827280215b9936d145dd5ee91403738ccce1333cab1dirk SetPixelAlpha(image,pixel,q); 828280215b9936d145dd5ee91403738ccce1333cab1dirk break; 829280215b9936d145dd5ee91403738ccce1333cab1dirk } 830280215b9936d145dd5ee91403738ccce1333cab1dirk } 831280215b9936d145dd5ee91403738ccce1333cab1dirk} 832280215b9936d145dd5ee91403738ccce1333cab1dirk 833b20a1794de28edf28c46f2268914c15781482530dirkstatic MagickBooleanType ReadPSDChannelPixels(Image *image, 834b41f080d52a5ff2d9c235cffac1419b84028bd31dirk const size_t channels,const size_t row,const ssize_t type, 835b41f080d52a5ff2d9c235cffac1419b84028bd31dirk const unsigned char *pixels,ExceptionInfo *exception) 83656ed31cc763800a9fb1f0df96104c354b40d2cbccristy{ 83756ed31cc763800a9fb1f0df96104c354b40d2cbccristy Quantum 83856ed31cc763800a9fb1f0df96104c354b40d2cbccristy pixel; 83956ed31cc763800a9fb1f0df96104c354b40d2cbccristy 8407753b2aa64ed48fc1f9d155cf43493373fa6d0bbcristy register const unsigned char 8417753b2aa64ed48fc1f9d155cf43493373fa6d0bbcristy *p; 8427753b2aa64ed48fc1f9d155cf43493373fa6d0bbcristy 8434c08aed51c5899665ade97263692328eea4af106cristy register Quantum 84456ed31cc763800a9fb1f0df96104c354b40d2cbccristy *q; 84556ed31cc763800a9fb1f0df96104c354b40d2cbccristy 8467753b2aa64ed48fc1f9d155cf43493373fa6d0bbcristy register ssize_t 8477753b2aa64ed48fc1f9d155cf43493373fa6d0bbcristy x; 84856ed31cc763800a9fb1f0df96104c354b40d2cbccristy 84956ed31cc763800a9fb1f0df96104c354b40d2cbccristy size_t 85056ed31cc763800a9fb1f0df96104c354b40d2cbccristy packet_size; 85156ed31cc763800a9fb1f0df96104c354b40d2cbccristy 85256ed31cc763800a9fb1f0df96104c354b40d2cbccristy unsigned short 85356ed31cc763800a9fb1f0df96104c354b40d2cbccristy nibble; 85456ed31cc763800a9fb1f0df96104c354b40d2cbccristy 855b41f080d52a5ff2d9c235cffac1419b84028bd31dirk p=pixels; 856b41f080d52a5ff2d9c235cffac1419b84028bd31dirk q=GetAuthenticPixels(image,0,row,image->columns,1,exception); 857b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (q == (Quantum *) NULL) 858b41f080d52a5ff2d9c235cffac1419b84028bd31dirk return MagickFalse; 859b41f080d52a5ff2d9c235cffac1419b84028bd31dirk packet_size=GetPSDPacketSize(image); 860b41f080d52a5ff2d9c235cffac1419b84028bd31dirk for (x=0; x < (ssize_t) image->columns; x++) 86156ed31cc763800a9fb1f0df96104c354b40d2cbccristy { 862b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (packet_size == 1) 863b41f080d52a5ff2d9c235cffac1419b84028bd31dirk pixel=ScaleCharToQuantum(*p++); 864b41f080d52a5ff2d9c235cffac1419b84028bd31dirk else 865b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 866b41f080d52a5ff2d9c235cffac1419b84028bd31dirk p=PushShortPixel(MSBEndian,p,&nibble); 867b41f080d52a5ff2d9c235cffac1419b84028bd31dirk pixel=ScaleShortToQuantum(nibble); 868b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 869280215b9936d145dd5ee91403738ccce1333cab1dirk if (image->depth > 1) 87056ed31cc763800a9fb1f0df96104c354b40d2cbccristy { 871280215b9936d145dd5ee91403738ccce1333cab1dirk SetPSDPixel(image,channels,type,packet_size,pixel,q,exception); 872280215b9936d145dd5ee91403738ccce1333cab1dirk q+=GetPixelChannels(image); 873b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 874280215b9936d145dd5ee91403738ccce1333cab1dirk else 875b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 876280215b9936d145dd5ee91403738ccce1333cab1dirk ssize_t 877280215b9936d145dd5ee91403738ccce1333cab1dirk bit, 878280215b9936d145dd5ee91403738ccce1333cab1dirk number_bits; 879280215b9936d145dd5ee91403738ccce1333cab1dirk 880280215b9936d145dd5ee91403738ccce1333cab1dirk number_bits=image->columns-x; 881280215b9936d145dd5ee91403738ccce1333cab1dirk if (number_bits > 8) 882280215b9936d145dd5ee91403738ccce1333cab1dirk number_bits=8; 883280215b9936d145dd5ee91403738ccce1333cab1dirk for (bit = 0; bit < number_bits; bit++) 884280215b9936d145dd5ee91403738ccce1333cab1dirk { 885280215b9936d145dd5ee91403738ccce1333cab1dirk SetPSDPixel(image,channels,type,packet_size,(((unsigned char) pixel) 886c6e0187105ab20b12bbc661f01b54e4894e92a5bdirk & (0x01 << (7-bit))) != 0 ? 0 : QuantumRange,q,exception); 887280215b9936d145dd5ee91403738ccce1333cab1dirk q+=GetPixelChannels(image); 888280215b9936d145dd5ee91403738ccce1333cab1dirk x++; 889280215b9936d145dd5ee91403738ccce1333cab1dirk } 89062cf71319382faa2dced95488ab838ce8b796146dirk if (x != (ssize_t) image->columns) 891280215b9936d145dd5ee91403738ccce1333cab1dirk x--; 892280215b9936d145dd5ee91403738ccce1333cab1dirk continue; 89356ed31cc763800a9fb1f0df96104c354b40d2cbccristy } 89456ed31cc763800a9fb1f0df96104c354b40d2cbccristy } 895b41f080d52a5ff2d9c235cffac1419b84028bd31dirk return(SyncAuthenticPixels(image,exception)); 89656ed31cc763800a9fb1f0df96104c354b40d2cbccristy} 89756ed31cc763800a9fb1f0df96104c354b40d2cbccristy 898b20a1794de28edf28c46f2268914c15781482530dirkstatic MagickBooleanType ReadPSDChannelRaw(Image *image,const size_t channels, 899b41f080d52a5ff2d9c235cffac1419b84028bd31dirk const ssize_t type,ExceptionInfo *exception) 9003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 901b20a1794de28edf28c46f2268914c15781482530dirk MagickBooleanType 902b41f080d52a5ff2d9c235cffac1419b84028bd31dirk status; 9033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 904b41f080d52a5ff2d9c235cffac1419b84028bd31dirk size_t 905b41f080d52a5ff2d9c235cffac1419b84028bd31dirk count, 906b41f080d52a5ff2d9c235cffac1419b84028bd31dirk row_size; 9073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 908b41f080d52a5ff2d9c235cffac1419b84028bd31dirk ssize_t 909b41f080d52a5ff2d9c235cffac1419b84028bd31dirk y; 9103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 911b41f080d52a5ff2d9c235cffac1419b84028bd31dirk unsigned char 912b41f080d52a5ff2d9c235cffac1419b84028bd31dirk *pixels; 913b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 914b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (image->debug != MagickFalse) 915b41f080d52a5ff2d9c235cffac1419b84028bd31dirk (void) LogMagickEvent(CoderEvent,GetMagickModule(), 916b41f080d52a5ff2d9c235cffac1419b84028bd31dirk " layer data is RAW"); 917b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 918b41f080d52a5ff2d9c235cffac1419b84028bd31dirk row_size=GetPSDRowSize(image); 919891df41d828a641db63d8bae45ca027d0e28341ddirk pixels=(unsigned char *) AcquireQuantumMemory(row_size,sizeof(*pixels)); 920b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (pixels == (unsigned char *) NULL) 921b41f080d52a5ff2d9c235cffac1419b84028bd31dirk ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", 922b41f080d52a5ff2d9c235cffac1419b84028bd31dirk image->filename); 923b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 924b41f080d52a5ff2d9c235cffac1419b84028bd31dirk status=MagickTrue; 925b41f080d52a5ff2d9c235cffac1419b84028bd31dirk for (y=0; y < (ssize_t) image->rows; y++) 926b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 927b41f080d52a5ff2d9c235cffac1419b84028bd31dirk status=MagickFalse; 928b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 929b41f080d52a5ff2d9c235cffac1419b84028bd31dirk count=ReadBlob(image,row_size,pixels); 930b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (count != row_size) 931b41f080d52a5ff2d9c235cffac1419b84028bd31dirk break; 932b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 933b41f080d52a5ff2d9c235cffac1419b84028bd31dirk status=ReadPSDChannelPixels(image,channels,y,type,pixels,exception); 934b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (status == MagickFalse) 935b41f080d52a5ff2d9c235cffac1419b84028bd31dirk break; 936b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 937b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 938b41f080d52a5ff2d9c235cffac1419b84028bd31dirk pixels=(unsigned char *) RelinquishMagickMemory(pixels); 939b41f080d52a5ff2d9c235cffac1419b84028bd31dirk return(status); 940b41f080d52a5ff2d9c235cffac1419b84028bd31dirk} 94156ed31cc763800a9fb1f0df96104c354b40d2cbccristy 942b41f080d52a5ff2d9c235cffac1419b84028bd31dirkstatic inline MagickOffsetType *ReadPSDRLEOffsets(Image *image, 9434d9863ca77e690fdde8653d1f3db0721bd25978edirk const PSDInfo *psd_info,const size_t size) 944b41f080d52a5ff2d9c235cffac1419b84028bd31dirk{ 94556ed31cc763800a9fb1f0df96104c354b40d2cbccristy MagickOffsetType 94656ed31cc763800a9fb1f0df96104c354b40d2cbccristy *offsets; 94756ed31cc763800a9fb1f0df96104c354b40d2cbccristy 948b41f080d52a5ff2d9c235cffac1419b84028bd31dirk ssize_t 949b41f080d52a5ff2d9c235cffac1419b84028bd31dirk y; 9503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 951b41f080d52a5ff2d9c235cffac1419b84028bd31dirk offsets=(MagickOffsetType *) AcquireQuantumMemory(size,sizeof(*offsets)); 952b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if(offsets != (MagickOffsetType *) NULL) 953b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 954b41f080d52a5ff2d9c235cffac1419b84028bd31dirk for (y=0; y < (ssize_t) size; y++) 955b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 956b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (psd_info->version == 1) 95787038d5d4cc04fb99d6560ae95f3f07a87563323dirk offsets[y]=(MagickOffsetType) ReadBlobShort(image); 958b41f080d52a5ff2d9c235cffac1419b84028bd31dirk else 95987038d5d4cc04fb99d6560ae95f3f07a87563323dirk offsets[y]=(MagickOffsetType) ReadBlobLong(image); 960b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 961b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 962b41f080d52a5ff2d9c235cffac1419b84028bd31dirk return offsets; 963b41f080d52a5ff2d9c235cffac1419b84028bd31dirk} 964dede49f1361cdf0a7aa29aa281b6f6e9a565f0facristy 965b20a1794de28edf28c46f2268914c15781482530dirkstatic MagickBooleanType ReadPSDChannelRLE(Image *image,const PSDInfo *psd_info, 966b41f080d52a5ff2d9c235cffac1419b84028bd31dirk const ssize_t type,MagickOffsetType *offsets,ExceptionInfo *exception) 967b41f080d52a5ff2d9c235cffac1419b84028bd31dirk{ 968b20a1794de28edf28c46f2268914c15781482530dirk MagickBooleanType 969b41f080d52a5ff2d9c235cffac1419b84028bd31dirk status; 9703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 971dc05fc25727367020d3b64c4e5831cc36632691acristy size_t 972b41f080d52a5ff2d9c235cffac1419b84028bd31dirk length, 973b41f080d52a5ff2d9c235cffac1419b84028bd31dirk row_size; 974dc05fc25727367020d3b64c4e5831cc36632691acristy 9753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ssize_t 976dc05fc25727367020d3b64c4e5831cc36632691acristy count, 977dc05fc25727367020d3b64c4e5831cc36632691acristy y; 9783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 9793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned char 980b41f080d52a5ff2d9c235cffac1419b84028bd31dirk *compact_pixels, 981b41f080d52a5ff2d9c235cffac1419b84028bd31dirk *pixels; 9823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 983b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (image->debug != MagickFalse) 984b41f080d52a5ff2d9c235cffac1419b84028bd31dirk (void) LogMagickEvent(CoderEvent,GetMagickModule(), 985b41f080d52a5ff2d9c235cffac1419b84028bd31dirk " layer data is RLE compressed"); 9863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 987b41f080d52a5ff2d9c235cffac1419b84028bd31dirk row_size=GetPSDRowSize(image); 988891df41d828a641db63d8bae45ca027d0e28341ddirk pixels=(unsigned char *) AcquireQuantumMemory(row_size,sizeof(*pixels)); 989b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (pixels == (unsigned char *) NULL) 990b41f080d52a5ff2d9c235cffac1419b84028bd31dirk ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", 991b41f080d52a5ff2d9c235cffac1419b84028bd31dirk image->filename); 992b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 993b41f080d52a5ff2d9c235cffac1419b84028bd31dirk length=0; 994b41f080d52a5ff2d9c235cffac1419b84028bd31dirk for (y=0; y < (ssize_t) image->rows; y++) 995b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if ((MagickOffsetType) length < offsets[y]) 996b41f080d52a5ff2d9c235cffac1419b84028bd31dirk length=(size_t) offsets[y]; 997b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 998b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (length > row_size + 256) // arbitrary number 9993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 1000b41f080d52a5ff2d9c235cffac1419b84028bd31dirk pixels=(unsigned char *) RelinquishMagickMemory(pixels); 1001b41f080d52a5ff2d9c235cffac1419b84028bd31dirk ThrowBinaryException(ResourceLimitError,"InvalidLength", 1002b41f080d52a5ff2d9c235cffac1419b84028bd31dirk image->filename); 10033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 1004b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1005891df41d828a641db63d8bae45ca027d0e28341ddirk compact_pixels=(unsigned char *) AcquireQuantumMemory(length,sizeof(*pixels)); 1006b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (compact_pixels == (unsigned char *) NULL) 1007b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 1008b41f080d52a5ff2d9c235cffac1419b84028bd31dirk pixels=(unsigned char *) RelinquishMagickMemory(pixels); 1009b41f080d52a5ff2d9c235cffac1419b84028bd31dirk ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", 1010b41f080d52a5ff2d9c235cffac1419b84028bd31dirk image->filename); 1011b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 1012b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1013b41f080d52a5ff2d9c235cffac1419b84028bd31dirk (void) ResetMagickMemory(compact_pixels,0,length*sizeof(*compact_pixels)); 1014b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1015b41f080d52a5ff2d9c235cffac1419b84028bd31dirk status=MagickTrue; 1016b41f080d52a5ff2d9c235cffac1419b84028bd31dirk for (y=0; y < (ssize_t) image->rows; y++) 1017b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 1018b41f080d52a5ff2d9c235cffac1419b84028bd31dirk status=MagickFalse; 1019b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1020b41f080d52a5ff2d9c235cffac1419b84028bd31dirk count=ReadBlob(image,(size_t) offsets[y],compact_pixels); 1021b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (count != (ssize_t) offsets[y]) 1022b41f080d52a5ff2d9c235cffac1419b84028bd31dirk break; 1023b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1024b41f080d52a5ff2d9c235cffac1419b84028bd31dirk count=DecodePSDPixels((size_t) offsets[y],compact_pixels, 1025b41f080d52a5ff2d9c235cffac1419b84028bd31dirk (ssize_t) (image->depth == 1 ? 123456 : image->depth),row_size,pixels); 1026b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (count != (ssize_t) row_size) 1027b41f080d52a5ff2d9c235cffac1419b84028bd31dirk break; 1028b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1029b41f080d52a5ff2d9c235cffac1419b84028bd31dirk status=ReadPSDChannelPixels(image,psd_info->channels,y,type,pixels, 1030b41f080d52a5ff2d9c235cffac1419b84028bd31dirk exception); 1031b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (status == MagickFalse) 1032b41f080d52a5ff2d9c235cffac1419b84028bd31dirk break; 1033b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 1034b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1035b41f080d52a5ff2d9c235cffac1419b84028bd31dirk compact_pixels=(unsigned char *) RelinquishMagickMemory(compact_pixels); 1036b41f080d52a5ff2d9c235cffac1419b84028bd31dirk pixels=(unsigned char *) RelinquishMagickMemory(pixels); 1037b41f080d52a5ff2d9c235cffac1419b84028bd31dirk return(status); 1038b41f080d52a5ff2d9c235cffac1419b84028bd31dirk} 1039b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1040b41f080d52a5ff2d9c235cffac1419b84028bd31dirk#ifdef MAGICKCORE_ZLIB_DELEGATE 1041b20a1794de28edf28c46f2268914c15781482530dirkstatic MagickBooleanType ReadPSDChannelZip(Image *image,const size_t channels, 1042ff30f83b51982c82b05cab57de8093dd52396b7bcristy const ssize_t type,const PSDCompressionType compression, 1043ff30f83b51982c82b05cab57de8093dd52396b7bcristy const size_t compact_size,ExceptionInfo *exception) 1044ff30f83b51982c82b05cab57de8093dd52396b7bcristy{ 1045b20a1794de28edf28c46f2268914c15781482530dirk MagickBooleanType 1046b41f080d52a5ff2d9c235cffac1419b84028bd31dirk status; 1047b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1048b41f080d52a5ff2d9c235cffac1419b84028bd31dirk register unsigned char 1049b41f080d52a5ff2d9c235cffac1419b84028bd31dirk *p; 1050b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1051b41f080d52a5ff2d9c235cffac1419b84028bd31dirk size_t 1052b41f080d52a5ff2d9c235cffac1419b84028bd31dirk count, 1053b41f080d52a5ff2d9c235cffac1419b84028bd31dirk length, 1054b41f080d52a5ff2d9c235cffac1419b84028bd31dirk packet_size, 1055b41f080d52a5ff2d9c235cffac1419b84028bd31dirk row_size; 1056b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1057b41f080d52a5ff2d9c235cffac1419b84028bd31dirk ssize_t 1058b41f080d52a5ff2d9c235cffac1419b84028bd31dirk y; 1059b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1060b41f080d52a5ff2d9c235cffac1419b84028bd31dirk unsigned char 1061b41f080d52a5ff2d9c235cffac1419b84028bd31dirk *compact_pixels, 1062b41f080d52a5ff2d9c235cffac1419b84028bd31dirk *pixels; 1063b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1064b41f080d52a5ff2d9c235cffac1419b84028bd31dirk z_stream 1065b41f080d52a5ff2d9c235cffac1419b84028bd31dirk stream; 1066b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1067b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (image->debug != MagickFalse) 1068b41f080d52a5ff2d9c235cffac1419b84028bd31dirk (void) LogMagickEvent(CoderEvent,GetMagickModule(), 1069245cc757e4d673ce07b090b09064951f3d029896dirk " layer data is ZIP compressed"); 1070b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1071b41f080d52a5ff2d9c235cffac1419b84028bd31dirk compact_pixels=(unsigned char *) AcquireQuantumMemory(compact_size, 1072b41f080d52a5ff2d9c235cffac1419b84028bd31dirk sizeof(*compact_pixels)); 1073b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (compact_pixels == (unsigned char *) NULL) 1074b41f080d52a5ff2d9c235cffac1419b84028bd31dirk ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", 1075b41f080d52a5ff2d9c235cffac1419b84028bd31dirk image->filename); 1076b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1077b41f080d52a5ff2d9c235cffac1419b84028bd31dirk packet_size=GetPSDPacketSize(image); 1078b41f080d52a5ff2d9c235cffac1419b84028bd31dirk row_size=image->columns*packet_size; 1079b41f080d52a5ff2d9c235cffac1419b84028bd31dirk count=image->rows*row_size; 1080b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1081b41f080d52a5ff2d9c235cffac1419b84028bd31dirk pixels=(unsigned char *) AcquireQuantumMemory(count,sizeof(*pixels)); 1082b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (pixels == (unsigned char *) NULL) 1083b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 1084b41f080d52a5ff2d9c235cffac1419b84028bd31dirk compact_pixels=(unsigned char *) RelinquishMagickMemory(compact_pixels); 1085b41f080d52a5ff2d9c235cffac1419b84028bd31dirk ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", 1086b41f080d52a5ff2d9c235cffac1419b84028bd31dirk image->filename); 1087b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 1088b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1089b41f080d52a5ff2d9c235cffac1419b84028bd31dirk ResetMagickMemory(&stream, 0, sizeof(z_stream)); 1090b41f080d52a5ff2d9c235cffac1419b84028bd31dirk stream.data_type=Z_BINARY; 1091b41f080d52a5ff2d9c235cffac1419b84028bd31dirk (void) ReadBlob(image,compact_size,compact_pixels); 1092b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1093b41f080d52a5ff2d9c235cffac1419b84028bd31dirk stream.next_in=(Bytef *)compact_pixels; 10940e274112f2ad0a61de63adfc11e3e78038d55231cristy stream.avail_in=(unsigned int) compact_size; 1095b41f080d52a5ff2d9c235cffac1419b84028bd31dirk stream.next_out=(Bytef *)pixels; 10960e274112f2ad0a61de63adfc11e3e78038d55231cristy stream.avail_out=(unsigned int) count; 1097b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1098b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if(inflateInit(&stream) == Z_OK) 1099b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 1100b41f080d52a5ff2d9c235cffac1419b84028bd31dirk int 1101b41f080d52a5ff2d9c235cffac1419b84028bd31dirk ret; 1102b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1103b41f080d52a5ff2d9c235cffac1419b84028bd31dirk while (stream.avail_out > 0) 1104b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 1105b41f080d52a5ff2d9c235cffac1419b84028bd31dirk ret=inflate(&stream, Z_SYNC_FLUSH); 1106b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (ret != Z_OK && ret != Z_STREAM_END) 1107b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 1108b41f080d52a5ff2d9c235cffac1419b84028bd31dirk compact_pixels=(unsigned char *) RelinquishMagickMemory( 1109b41f080d52a5ff2d9c235cffac1419b84028bd31dirk compact_pixels); 1110b41f080d52a5ff2d9c235cffac1419b84028bd31dirk pixels=(unsigned char *) RelinquishMagickMemory(pixels); 1111b41f080d52a5ff2d9c235cffac1419b84028bd31dirk return(MagickFalse); 1112b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 1113b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 1114b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 1115b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1116b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (compression == ZipWithPrediction) 1117b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 1118b41f080d52a5ff2d9c235cffac1419b84028bd31dirk p=pixels; 1119b41f080d52a5ff2d9c235cffac1419b84028bd31dirk while(count > 0) 1120b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 1121b41f080d52a5ff2d9c235cffac1419b84028bd31dirk length=image->columns; 1122b41f080d52a5ff2d9c235cffac1419b84028bd31dirk while(--length) 1123b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 1124b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (packet_size == 2) 1125b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 1126b41f080d52a5ff2d9c235cffac1419b84028bd31dirk p[2]+=p[0]+((p[1]+p[3]) >> 8); 1127b41f080d52a5ff2d9c235cffac1419b84028bd31dirk p[3]+=p[1]; 1128b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 1129b41f080d52a5ff2d9c235cffac1419b84028bd31dirk else 1130b41f080d52a5ff2d9c235cffac1419b84028bd31dirk *(p+1)+=*p; 1131b41f080d52a5ff2d9c235cffac1419b84028bd31dirk p+=packet_size; 1132b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 1133b41f080d52a5ff2d9c235cffac1419b84028bd31dirk p+=packet_size; 1134b41f080d52a5ff2d9c235cffac1419b84028bd31dirk count-=row_size; 1135b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 1136b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 1137b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1138b41f080d52a5ff2d9c235cffac1419b84028bd31dirk status=MagickTrue; 1139b41f080d52a5ff2d9c235cffac1419b84028bd31dirk p=pixels; 1140b41f080d52a5ff2d9c235cffac1419b84028bd31dirk for (y=0; y < (ssize_t) image->rows; y++) 1141b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 1142b41f080d52a5ff2d9c235cffac1419b84028bd31dirk status=ReadPSDChannelPixels(image,channels,y,type,p,exception); 1143b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (status == MagickFalse) 1144b41f080d52a5ff2d9c235cffac1419b84028bd31dirk break; 1145b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1146b41f080d52a5ff2d9c235cffac1419b84028bd31dirk p+=row_size; 1147b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 1148b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1149b41f080d52a5ff2d9c235cffac1419b84028bd31dirk compact_pixels=(unsigned char *) RelinquishMagickMemory(compact_pixels); 1150b41f080d52a5ff2d9c235cffac1419b84028bd31dirk pixels=(unsigned char *) RelinquishMagickMemory(pixels); 1151b41f080d52a5ff2d9c235cffac1419b84028bd31dirk return(status); 1152b41f080d52a5ff2d9c235cffac1419b84028bd31dirk} 11530d67b92d9e50a025e13e4658113b31b4d3dd72cecristy#endif 1154b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1155b20a1794de28edf28c46f2268914c15781482530dirkstatic MagickBooleanType ReadPSDChannel(Image *image,const PSDInfo *psd_info, 1156a41d97fa7de942f144af6cfcceba24c523775c54dirk LayerInfo* layer_info,const size_t channel, 1157b41f080d52a5ff2d9c235cffac1419b84028bd31dirk const PSDCompressionType compression,ExceptionInfo *exception) 1158b41f080d52a5ff2d9c235cffac1419b84028bd31dirk{ 1159a41d97fa7de942f144af6cfcceba24c523775c54dirk Image 1160a41d97fa7de942f144af6cfcceba24c523775c54dirk *channel_image, 1161a41d97fa7de942f144af6cfcceba24c523775c54dirk *mask; 1162a41d97fa7de942f144af6cfcceba24c523775c54dirk 1163b41f080d52a5ff2d9c235cffac1419b84028bd31dirk MagickOffsetType 1164b41f080d52a5ff2d9c235cffac1419b84028bd31dirk offset; 1165b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1166b20a1794de28edf28c46f2268914c15781482530dirk MagickBooleanType 1167b41f080d52a5ff2d9c235cffac1419b84028bd31dirk status; 1168b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1169a41d97fa7de942f144af6cfcceba24c523775c54dirk channel_image=image; 1170a41d97fa7de942f144af6cfcceba24c523775c54dirk mask=(Image *) NULL; 1171245cc757e4d673ce07b090b09064951f3d029896dirk if (layer_info->channel_info[channel].type < -1) 1172245cc757e4d673ce07b090b09064951f3d029896dirk { 1173a41d97fa7de942f144af6cfcceba24c523775c54dirk /* 1174a41d97fa7de942f144af6cfcceba24c523775c54dirk Ignore mask that is not a user supplied layer mask, if the mask is 1175a41d97fa7de942f144af6cfcceba24c523775c54dirk disabled or if the flags have unsupported values. 1176a41d97fa7de942f144af6cfcceba24c523775c54dirk */ 1177a41d97fa7de942f144af6cfcceba24c523775c54dirk if (layer_info->channel_info[channel].type != -2 || 1178a41d97fa7de942f144af6cfcceba24c523775c54dirk (layer_info->mask.flags > 3) || (layer_info->mask.flags & 0x02)) 1179a41d97fa7de942f144af6cfcceba24c523775c54dirk { 1180a41d97fa7de942f144af6cfcceba24c523775c54dirk SeekBlob(image,layer_info->channel_info[channel].size-2,SEEK_CUR); 1181a41d97fa7de942f144af6cfcceba24c523775c54dirk return(MagickTrue); 1182a41d97fa7de942f144af6cfcceba24c523775c54dirk } 1183a41d97fa7de942f144af6cfcceba24c523775c54dirk mask=CloneImage(image,layer_info->mask.page.width, 1184a41d97fa7de942f144af6cfcceba24c523775c54dirk layer_info->mask.page.height,MagickFalse,exception); 1185a41d97fa7de942f144af6cfcceba24c523775c54dirk SetImageType(mask,GrayscaleType,exception); 1186a41d97fa7de942f144af6cfcceba24c523775c54dirk channel_image=mask; 1187245cc757e4d673ce07b090b09064951f3d029896dirk } 1188245cc757e4d673ce07b090b09064951f3d029896dirk 118955851db5384887e1bb46255bbfd1d55fa7408316dirk offset=TellBlob(image); 1190b41f080d52a5ff2d9c235cffac1419b84028bd31dirk status=MagickTrue; 1191b41f080d52a5ff2d9c235cffac1419b84028bd31dirk switch(compression) 1192b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 1193b41f080d52a5ff2d9c235cffac1419b84028bd31dirk case Raw: 1194fe3a57e5b12c38f455ae6dd3bb47dc7cb054cc43dirk status=ReadPSDChannelRaw(channel_image,psd_info->channels, 1195fe3a57e5b12c38f455ae6dd3bb47dc7cb054cc43dirk layer_info->channel_info[channel].type,exception); 1196fe3a57e5b12c38f455ae6dd3bb47dc7cb054cc43dirk break; 1197b41f080d52a5ff2d9c235cffac1419b84028bd31dirk case RLE: 1198b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 1199b41f080d52a5ff2d9c235cffac1419b84028bd31dirk MagickOffsetType 1200b41f080d52a5ff2d9c235cffac1419b84028bd31dirk *offsets; 1201b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1202a41d97fa7de942f144af6cfcceba24c523775c54dirk offsets=ReadPSDRLEOffsets(channel_image,psd_info,channel_image->rows); 1203b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (offsets == (MagickOffsetType *) NULL) 1204b41f080d52a5ff2d9c235cffac1419b84028bd31dirk ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", 1205b41f080d52a5ff2d9c235cffac1419b84028bd31dirk image->filename); 1206a41d97fa7de942f144af6cfcceba24c523775c54dirk status=ReadPSDChannelRLE(channel_image,psd_info, 1207a41d97fa7de942f144af6cfcceba24c523775c54dirk layer_info->channel_info[channel].type,offsets,exception); 1208b41f080d52a5ff2d9c235cffac1419b84028bd31dirk offsets=(MagickOffsetType *) RelinquishMagickMemory(offsets); 1209b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 1210b41f080d52a5ff2d9c235cffac1419b84028bd31dirk break; 1211b41f080d52a5ff2d9c235cffac1419b84028bd31dirk case ZipWithPrediction: 1212b41f080d52a5ff2d9c235cffac1419b84028bd31dirk case ZipWithoutPrediction: 1213b41f080d52a5ff2d9c235cffac1419b84028bd31dirk#ifdef MAGICKCORE_ZLIB_DELEGATE 1214a41d97fa7de942f144af6cfcceba24c523775c54dirk status=ReadPSDChannelZip(channel_image,layer_info->channels, 1215b41f080d52a5ff2d9c235cffac1419b84028bd31dirk layer_info->channel_info[channel].type,compression, 1216b41f080d52a5ff2d9c235cffac1419b84028bd31dirk layer_info->channel_info[channel].size-2,exception); 1217b41f080d52a5ff2d9c235cffac1419b84028bd31dirk#else 1218b41f080d52a5ff2d9c235cffac1419b84028bd31dirk (void) ThrowMagickException(exception,GetMagickModule(), 1219b41f080d52a5ff2d9c235cffac1419b84028bd31dirk MissingDelegateWarning,"DelegateLibrarySupportNotBuiltIn", 1220b41f080d52a5ff2d9c235cffac1419b84028bd31dirk "'%s' (ZLIB)",image->filename); 1221b41f080d52a5ff2d9c235cffac1419b84028bd31dirk#endif 1222b41f080d52a5ff2d9c235cffac1419b84028bd31dirk break; 1223b41f080d52a5ff2d9c235cffac1419b84028bd31dirk default: 1224b41f080d52a5ff2d9c235cffac1419b84028bd31dirk (void) ThrowMagickException(exception,GetMagickModule(),TypeWarning, 1225b41f080d52a5ff2d9c235cffac1419b84028bd31dirk "CompressionNotSupported","'%.20g'",(double) compression); 1226b41f080d52a5ff2d9c235cffac1419b84028bd31dirk break; 1227b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 1228b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 122955851db5384887e1bb46255bbfd1d55fa7408316dirk SeekBlob(image,offset+layer_info->channel_info[channel].size-2,SEEK_SET); 1230b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (status == MagickFalse) 1231d5a9132f28f00226b38417cfaee9b4938f4a1cd6dirk { 1232d5a9132f28f00226b38417cfaee9b4938f4a1cd6dirk if (mask != (Image *) NULL) 1233d5a9132f28f00226b38417cfaee9b4938f4a1cd6dirk DestroyImage(mask); 1234d5a9132f28f00226b38417cfaee9b4938f4a1cd6dirk ThrowBinaryException(CoderError,"UnableToDecompressImage", 1235d5a9132f28f00226b38417cfaee9b4938f4a1cd6dirk image->filename); 1236d5a9132f28f00226b38417cfaee9b4938f4a1cd6dirk } 1237a41d97fa7de942f144af6cfcceba24c523775c54dirk if (mask != (Image *) NULL) 1238a41d97fa7de942f144af6cfcceba24c523775c54dirk { 1239a41d97fa7de942f144af6cfcceba24c523775c54dirk if (status != MagickFalse) 1240a41d97fa7de942f144af6cfcceba24c523775c54dirk { 1241a41d97fa7de942f144af6cfcceba24c523775c54dirk PixelInfo 1242a41d97fa7de942f144af6cfcceba24c523775c54dirk color; 1243a41d97fa7de942f144af6cfcceba24c523775c54dirk 1244a41d97fa7de942f144af6cfcceba24c523775c54dirk layer_info->mask.image=CloneImage(image,image->columns,image->rows, 1245a41d97fa7de942f144af6cfcceba24c523775c54dirk MagickTrue,exception); 1246a41d97fa7de942f144af6cfcceba24c523775c54dirk layer_info->mask.image->alpha_trait=UndefinedPixelTrait; 1247a41d97fa7de942f144af6cfcceba24c523775c54dirk GetPixelInfo(layer_info->mask.image,&color); 1248a41d97fa7de942f144af6cfcceba24c523775c54dirk color.red=layer_info->mask.background == 0 ? 0 : QuantumRange; 1249a41d97fa7de942f144af6cfcceba24c523775c54dirk SetImageColor(layer_info->mask.image,&color,exception); 1250a41d97fa7de942f144af6cfcceba24c523775c54dirk (void) CompositeImage(layer_info->mask.image,mask,OverCompositeOp, 1251a41d97fa7de942f144af6cfcceba24c523775c54dirk MagickTrue,layer_info->mask.page.x,layer_info->mask.page.y, 1252a41d97fa7de942f144af6cfcceba24c523775c54dirk exception); 1253a41d97fa7de942f144af6cfcceba24c523775c54dirk } 1254a41d97fa7de942f144af6cfcceba24c523775c54dirk DestroyImage(mask); 1255a41d97fa7de942f144af6cfcceba24c523775c54dirk } 1256b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1257b41f080d52a5ff2d9c235cffac1419b84028bd31dirk return(status); 1258b41f080d52a5ff2d9c235cffac1419b84028bd31dirk} 1259b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1260b20a1794de28edf28c46f2268914c15781482530dirkstatic MagickBooleanType ReadPSDLayer(Image *image,const PSDInfo *psd_info, 1261b41f080d52a5ff2d9c235cffac1419b84028bd31dirk LayerInfo* layer_info,ExceptionInfo *exception) 1262b41f080d52a5ff2d9c235cffac1419b84028bd31dirk{ 1263b41f080d52a5ff2d9c235cffac1419b84028bd31dirk char 1264151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy message[MagickPathExtent]; 1265b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1266b20a1794de28edf28c46f2268914c15781482530dirk MagickBooleanType 1267b41f080d52a5ff2d9c235cffac1419b84028bd31dirk status; 1268b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1269b41f080d52a5ff2d9c235cffac1419b84028bd31dirk PSDCompressionType 1270b41f080d52a5ff2d9c235cffac1419b84028bd31dirk compression; 1271b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1272b41f080d52a5ff2d9c235cffac1419b84028bd31dirk ssize_t 1273b41f080d52a5ff2d9c235cffac1419b84028bd31dirk j; 1274b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1275b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (image->debug != MagickFalse) 1276b41f080d52a5ff2d9c235cffac1419b84028bd31dirk (void) LogMagickEvent(CoderEvent,GetMagickModule(), 1277b41f080d52a5ff2d9c235cffac1419b84028bd31dirk " setting up new layer image"); 1278b41f080d52a5ff2d9c235cffac1419b84028bd31dirk (void) SetImageBackgroundColor(layer_info->image,exception); 1279b41f080d52a5ff2d9c235cffac1419b84028bd31dirk layer_info->image->compose=PSDBlendModeToCompositeOperator( 1280b41f080d52a5ff2d9c235cffac1419b84028bd31dirk layer_info->blendkey); 1281b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (layer_info->visible == MagickFalse) 1282b41f080d52a5ff2d9c235cffac1419b84028bd31dirk layer_info->image->compose=NoCompositeOp; 1283b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (psd_info->mode == CMYKMode) 1284b41f080d52a5ff2d9c235cffac1419b84028bd31dirk SetImageColorspace(layer_info->image,CMYKColorspace,exception); 1285d8083a693bea157df66921cb7570880bb081dcd1cristy if ((psd_info->mode == BitmapMode) || (psd_info->mode == GrayscaleMode) || 1286b41f080d52a5ff2d9c235cffac1419b84028bd31dirk (psd_info->mode == DuotoneMode)) 1287b41f080d52a5ff2d9c235cffac1419b84028bd31dirk SetImageColorspace(layer_info->image,GRAYColorspace,exception); 1288b41f080d52a5ff2d9c235cffac1419b84028bd31dirk /* 1289b41f080d52a5ff2d9c235cffac1419b84028bd31dirk Set up some hidden attributes for folks that need them. 1290b41f080d52a5ff2d9c235cffac1419b84028bd31dirk */ 1291a41d97fa7de942f144af6cfcceba24c523775c54dirk (void) FormatLocaleString(message,MagickPathExtent,"%.20g", 1292b41f080d52a5ff2d9c235cffac1419b84028bd31dirk (double) layer_info->page.x); 1293b41f080d52a5ff2d9c235cffac1419b84028bd31dirk (void) SetImageArtifact(layer_info->image,"psd:layer.x",message); 1294151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy (void) FormatLocaleString(message,MagickPathExtent,"%.20g", 1295b41f080d52a5ff2d9c235cffac1419b84028bd31dirk (double) layer_info->page.y); 1296b41f080d52a5ff2d9c235cffac1419b84028bd31dirk (void) SetImageArtifact(layer_info->image,"psd:layer.y",message); 1297151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy (void) FormatLocaleString(message,MagickPathExtent,"%.20g",(double) 1298b41f080d52a5ff2d9c235cffac1419b84028bd31dirk layer_info->opacity); 1299b41f080d52a5ff2d9c235cffac1419b84028bd31dirk (void) SetImageArtifact(layer_info->image,"psd:layer.opacity",message); 1300b41f080d52a5ff2d9c235cffac1419b84028bd31dirk (void) SetImageProperty(layer_info->image,"label",(char *) layer_info->name, 1301b41f080d52a5ff2d9c235cffac1419b84028bd31dirk exception); 1302b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1303b41f080d52a5ff2d9c235cffac1419b84028bd31dirk status=MagickTrue; 1304b41f080d52a5ff2d9c235cffac1419b84028bd31dirk for (j=0; j < (ssize_t) layer_info->channels; j++) 1305b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 1306b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (image->debug != MagickFalse) 1307b41f080d52a5ff2d9c235cffac1419b84028bd31dirk (void) LogMagickEvent(CoderEvent,GetMagickModule(), 1308b41f080d52a5ff2d9c235cffac1419b84028bd31dirk " reading data for channel %.20g",(double) j); 1309b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 131087038d5d4cc04fb99d6560ae95f3f07a87563323dirk compression=(PSDCompressionType) ReadBlobShort(layer_info->image); 1311b41f080d52a5ff2d9c235cffac1419b84028bd31dirk layer_info->image->compression=ConvertPSDCompression(compression); 13126f20531b06ddc2852ec30506e13798363f534e53dirk if (layer_info->channel_info[j].type == -1) 13136f20531b06ddc2852ec30506e13798363f534e53dirk layer_info->image->alpha_trait=BlendPixelTrait; 1314d9795a19984ae1bae9205b7c0fe5de75461978b3dirk 13156f20531b06ddc2852ec30506e13798363f534e53dirk status=ReadPSDChannel(layer_info->image,psd_info,layer_info,j, 13166f20531b06ddc2852ec30506e13798363f534e53dirk compression,exception); 1317b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1318b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (status == MagickFalse) 1319b41f080d52a5ff2d9c235cffac1419b84028bd31dirk break; 1320b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 1321b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 13226f20531b06ddc2852ec30506e13798363f534e53dirk if (status != MagickFalse) 1323b41f080d52a5ff2d9c235cffac1419b84028bd31dirk status=CorrectPSDOpacity(layer_info,exception); 1324b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1325b20a1794de28edf28c46f2268914c15781482530dirk if ((status != MagickFalse) && 1326b20a1794de28edf28c46f2268914c15781482530dirk (layer_info->image->colorspace == CMYKColorspace)) 1327b20a1794de28edf28c46f2268914c15781482530dirk status=NegateCMYK(layer_info->image,exception); 1328b20a1794de28edf28c46f2268914c15781482530dirk 1329b20a1794de28edf28c46f2268914c15781482530dirk if ((status != MagickFalse) && (layer_info->mask.image != (Image *) NULL)) 1330a41d97fa7de942f144af6cfcceba24c523775c54dirk { 1331b20a1794de28edf28c46f2268914c15781482530dirk status=CompositeImage(layer_info->image,layer_info->mask.image, 1332b20a1794de28edf28c46f2268914c15781482530dirk CopyAlphaCompositeOp,MagickTrue,0,0,exception); 1333b20a1794de28edf28c46f2268914c15781482530dirk layer_info->mask.image=DestroyImage(layer_info->mask.image); 1334a41d97fa7de942f144af6cfcceba24c523775c54dirk } 1335b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1336b41f080d52a5ff2d9c235cffac1419b84028bd31dirk return(status); 1337b41f080d52a5ff2d9c235cffac1419b84028bd31dirk} 1338b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1339b20a1794de28edf28c46f2268914c15781482530dirkModuleExport MagickBooleanType ReadPSDLayers(Image *image, 134014c08dcd1910ecd8360f51d13885b2c9c39b655ddirk const ImageInfo *image_info,const PSDInfo *psd_info, 134114c08dcd1910ecd8360f51d13885b2c9c39b655ddirk const MagickBooleanType skip_layers,ExceptionInfo *exception) 1342b41f080d52a5ff2d9c235cffac1419b84028bd31dirk{ 1343b41f080d52a5ff2d9c235cffac1419b84028bd31dirk char 1344b41f080d52a5ff2d9c235cffac1419b84028bd31dirk type[4]; 1345b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1346b41f080d52a5ff2d9c235cffac1419b84028bd31dirk LayerInfo 1347b41f080d52a5ff2d9c235cffac1419b84028bd31dirk *layer_info; 1348b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1349b41f080d52a5ff2d9c235cffac1419b84028bd31dirk MagickSizeType 1350b41f080d52a5ff2d9c235cffac1419b84028bd31dirk size; 1351b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1352b20a1794de28edf28c46f2268914c15781482530dirk MagickBooleanType 1353b41f080d52a5ff2d9c235cffac1419b84028bd31dirk status; 1354b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1355b41f080d52a5ff2d9c235cffac1419b84028bd31dirk register ssize_t 1356b41f080d52a5ff2d9c235cffac1419b84028bd31dirk i; 1357b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1358b41f080d52a5ff2d9c235cffac1419b84028bd31dirk ssize_t 1359b41f080d52a5ff2d9c235cffac1419b84028bd31dirk count, 1360b41f080d52a5ff2d9c235cffac1419b84028bd31dirk j, 1361b41f080d52a5ff2d9c235cffac1419b84028bd31dirk number_layers; 1362b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1363b41f080d52a5ff2d9c235cffac1419b84028bd31dirk size=GetPSDSize(psd_info,image); 1364b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (size == 0) 1365b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 1366b41f080d52a5ff2d9c235cffac1419b84028bd31dirk /* 1367b41f080d52a5ff2d9c235cffac1419b84028bd31dirk Skip layers & masks. 1368b41f080d52a5ff2d9c235cffac1419b84028bd31dirk */ 136987038d5d4cc04fb99d6560ae95f3f07a87563323dirk (void) ReadBlobLong(image); 1370b41f080d52a5ff2d9c235cffac1419b84028bd31dirk count=ReadBlob(image,4,(unsigned char *) type); 137187038d5d4cc04fb99d6560ae95f3f07a87563323dirk ReversePSDString(image,type,4); 1372908a35b19a313486d17de504738fc427595918d2cristy status=MagickFalse; 1373b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if ((count == 0) || (LocaleNCompare(type,"8BIM",4) != 0)) 1374f308152b28249d599fa01dd41b1518c4ddfc5e60dirk return(MagickTrue); 1375b41f080d52a5ff2d9c235cffac1419b84028bd31dirk else 1376b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 1377b41f080d52a5ff2d9c235cffac1419b84028bd31dirk count=ReadBlob(image,4,(unsigned char *) type); 137887038d5d4cc04fb99d6560ae95f3f07a87563323dirk ReversePSDString(image,type,4); 1379b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if ((count != 0) && (LocaleNCompare(type,"Lr16",4) == 0)) 1380b41f080d52a5ff2d9c235cffac1419b84028bd31dirk size=GetPSDSize(psd_info,image); 1381b41f080d52a5ff2d9c235cffac1419b84028bd31dirk else 1382f308152b28249d599fa01dd41b1518c4ddfc5e60dirk return(MagickTrue); 1383b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 1384b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 1385b41f080d52a5ff2d9c235cffac1419b84028bd31dirk status=MagickTrue; 1386b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (size != 0) 1387b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 1388b41f080d52a5ff2d9c235cffac1419b84028bd31dirk layer_info=(LayerInfo *) NULL; 138987038d5d4cc04fb99d6560ae95f3f07a87563323dirk number_layers=(short) ReadBlobShort(image); 1390b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1391b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (number_layers < 0) 1392b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 1393b41f080d52a5ff2d9c235cffac1419b84028bd31dirk /* 13946f20531b06ddc2852ec30506e13798363f534e53dirk The first alpha channel in the merged result contains the 13956f20531b06ddc2852ec30506e13798363f534e53dirk transparency data for the merged result. 1396b41f080d52a5ff2d9c235cffac1419b84028bd31dirk */ 1397b41f080d52a5ff2d9c235cffac1419b84028bd31dirk number_layers=MagickAbsoluteValue(number_layers); 1398b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (image->debug != MagickFalse) 1399b41f080d52a5ff2d9c235cffac1419b84028bd31dirk (void) LogMagickEvent(CoderEvent,GetMagickModule(), 1400b41f080d52a5ff2d9c235cffac1419b84028bd31dirk " negative layer count corrected for"); 14016f20531b06ddc2852ec30506e13798363f534e53dirk image->alpha_trait=BlendPixelTrait; 1402b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 1403b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1404f308152b28249d599fa01dd41b1518c4ddfc5e60dirk /* 1405f308152b28249d599fa01dd41b1518c4ddfc5e60dirk We only need to know if the image has an alpha channel 1406f308152b28249d599fa01dd41b1518c4ddfc5e60dirk */ 1407fcaec62bc681e372b60f8a31681671653bc907f2dirk if (skip_layers != MagickFalse) 1408fcaec62bc681e372b60f8a31681671653bc907f2dirk return(MagickTrue); 1409fcaec62bc681e372b60f8a31681671653bc907f2dirk 1410b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (image->debug != MagickFalse) 1411b41f080d52a5ff2d9c235cffac1419b84028bd31dirk (void) LogMagickEvent(CoderEvent,GetMagickModule(), 1412b41f080d52a5ff2d9c235cffac1419b84028bd31dirk " image contains %.20g layers",(double) number_layers); 1413b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1414b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (number_layers == 0) 1415419e5adbecfc7375751e7ac2ba30be0b1d35690fdirk ThrowBinaryException(CorruptImageError,"InvalidNumberOfLayers", 1416419e5adbecfc7375751e7ac2ba30be0b1d35690fdirk image->filename); 1417b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1418b41f080d52a5ff2d9c235cffac1419b84028bd31dirk layer_info=(LayerInfo *) AcquireQuantumMemory((size_t) number_layers, 1419b41f080d52a5ff2d9c235cffac1419b84028bd31dirk sizeof(*layer_info)); 1420b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (layer_info == (LayerInfo *) NULL) 1421b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 1422b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (image->debug != MagickFalse) 1423b41f080d52a5ff2d9c235cffac1419b84028bd31dirk (void) LogMagickEvent(CoderEvent,GetMagickModule(), 1424b41f080d52a5ff2d9c235cffac1419b84028bd31dirk " allocation of LayerInfo failed"); 1425b41f080d52a5ff2d9c235cffac1419b84028bd31dirk ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", 1426b41f080d52a5ff2d9c235cffac1419b84028bd31dirk image->filename); 1427b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 1428b41f080d52a5ff2d9c235cffac1419b84028bd31dirk (void) ResetMagickMemory(layer_info,0,(size_t) number_layers* 1429b41f080d52a5ff2d9c235cffac1419b84028bd31dirk sizeof(*layer_info)); 1430b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1431b41f080d52a5ff2d9c235cffac1419b84028bd31dirk for (i=0; i < number_layers; i++) 1432b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 143387038d5d4cc04fb99d6560ae95f3f07a87563323dirk ssize_t 1434b41f080d52a5ff2d9c235cffac1419b84028bd31dirk x, 1435b41f080d52a5ff2d9c235cffac1419b84028bd31dirk y; 1436b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1437b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (image->debug != MagickFalse) 1438b41f080d52a5ff2d9c235cffac1419b84028bd31dirk (void) LogMagickEvent(CoderEvent,GetMagickModule(), 1439b41f080d52a5ff2d9c235cffac1419b84028bd31dirk " reading layer #%.20g",(double) i+1); 14401fe0b879964fa7797e3d68574d297922a47c4034Cristy layer_info[i].page.y=ReadBlobSignedLong(image); 14411fe0b879964fa7797e3d68574d297922a47c4034Cristy layer_info[i].page.x=ReadBlobSignedLong(image); 14421fe0b879964fa7797e3d68574d297922a47c4034Cristy y=ReadBlobSignedLong(image); 14431fe0b879964fa7797e3d68574d297922a47c4034Cristy x=ReadBlobSignedLong(image); 1444ca41d6217207703b616165002c165b1e1d85a2a7dirk layer_info[i].page.width=(size_t) (x-layer_info[i].page.x); 1445ca41d6217207703b616165002c165b1e1d85a2a7dirk layer_info[i].page.height=(size_t) (y-layer_info[i].page.y); 144687038d5d4cc04fb99d6560ae95f3f07a87563323dirk layer_info[i].channels=ReadBlobShort(image); 1447b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (layer_info[i].channels > MaxPSDChannels) 1448b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 1449bd8bd8572e272ce0bc730bfa0296b8f048ea2da1dirk layer_info=DestroyLayerInfo(layer_info,number_layers); 1450b41f080d52a5ff2d9c235cffac1419b84028bd31dirk ThrowBinaryException(CorruptImageError,"MaximumChannelsExceeded", 1451419e5adbecfc7375751e7ac2ba30be0b1d35690fdirk image->filename); 1452b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 1453b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (image->debug != MagickFalse) 1454b41f080d52a5ff2d9c235cffac1419b84028bd31dirk (void) LogMagickEvent(CoderEvent,GetMagickModule(), 1455b41f080d52a5ff2d9c235cffac1419b84028bd31dirk " offset(%.20g,%.20g), size(%.20g,%.20g), channels=%.20g", 1456b41f080d52a5ff2d9c235cffac1419b84028bd31dirk (double) layer_info[i].page.x,(double) layer_info[i].page.y, 1457b41f080d52a5ff2d9c235cffac1419b84028bd31dirk (double) layer_info[i].page.height,(double) 1458b41f080d52a5ff2d9c235cffac1419b84028bd31dirk layer_info[i].page.width,(double) layer_info[i].channels); 1459b41f080d52a5ff2d9c235cffac1419b84028bd31dirk for (j=0; j < (ssize_t) layer_info[i].channels; j++) 1460b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 146187038d5d4cc04fb99d6560ae95f3f07a87563323dirk layer_info[i].channel_info[j].type=(short) ReadBlobShort(image); 1462b41f080d52a5ff2d9c235cffac1419b84028bd31dirk layer_info[i].channel_info[j].size=(size_t) GetPSDSize(psd_info, 1463b41f080d52a5ff2d9c235cffac1419b84028bd31dirk image); 1464b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (image->debug != MagickFalse) 1465b41f080d52a5ff2d9c235cffac1419b84028bd31dirk (void) LogMagickEvent(CoderEvent,GetMagickModule(), 1466b41f080d52a5ff2d9c235cffac1419b84028bd31dirk " channel[%.20g]: type=%.20g, size=%.20g",(double) j, 1467b41f080d52a5ff2d9c235cffac1419b84028bd31dirk (double) layer_info[i].channel_info[j].type, 1468b41f080d52a5ff2d9c235cffac1419b84028bd31dirk (double) layer_info[i].channel_info[j].size); 1469b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 1470b41f080d52a5ff2d9c235cffac1419b84028bd31dirk count=ReadBlob(image,4,(unsigned char *) type); 147187038d5d4cc04fb99d6560ae95f3f07a87563323dirk ReversePSDString(image,type,4); 1472b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if ((count == 0) || (LocaleNCompare(type,"8BIM",4) != 0)) 1473b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 1474b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (image->debug != MagickFalse) 1475b41f080d52a5ff2d9c235cffac1419b84028bd31dirk (void) LogMagickEvent(CoderEvent,GetMagickModule(), 1476b41f080d52a5ff2d9c235cffac1419b84028bd31dirk " layer type was %.4s instead of 8BIM", type); 1477bd8bd8572e272ce0bc730bfa0296b8f048ea2da1dirk layer_info=DestroyLayerInfo(layer_info,number_layers); 1478b41f080d52a5ff2d9c235cffac1419b84028bd31dirk ThrowBinaryException(CorruptImageError,"ImproperImageHeader", 1479b41f080d52a5ff2d9c235cffac1419b84028bd31dirk image->filename); 1480b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 1481b41f080d52a5ff2d9c235cffac1419b84028bd31dirk count=ReadBlob(image,4,(unsigned char *) layer_info[i].blendkey); 148287038d5d4cc04fb99d6560ae95f3f07a87563323dirk ReversePSDString(image,layer_info[i].blendkey,4); 1483b52a4b752ce10edce4c5ddb441480635ff7c7283dirk layer_info[i].opacity=(Quantum) ScaleCharToQuantum((unsigned char) 1484d8083a693bea157df66921cb7570880bb081dcd1cristy ReadBlobByte(image)); 1485b41f080d52a5ff2d9c235cffac1419b84028bd31dirk layer_info[i].clipping=(unsigned char) ReadBlobByte(image); 1486b41f080d52a5ff2d9c235cffac1419b84028bd31dirk layer_info[i].flags=(unsigned char) ReadBlobByte(image); 1487b41f080d52a5ff2d9c235cffac1419b84028bd31dirk layer_info[i].visible=!(layer_info[i].flags & 0x02); 1488b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (image->debug != MagickFalse) 1489b41f080d52a5ff2d9c235cffac1419b84028bd31dirk (void) LogMagickEvent(CoderEvent,GetMagickModule(), 1490b41f080d52a5ff2d9c235cffac1419b84028bd31dirk " blend=%.4s, opacity=%.20g, clipping=%s, flags=%d, visible=%s", 1491b41f080d52a5ff2d9c235cffac1419b84028bd31dirk layer_info[i].blendkey,(double) layer_info[i].opacity, 1492b41f080d52a5ff2d9c235cffac1419b84028bd31dirk layer_info[i].clipping ? "true" : "false",layer_info[i].flags, 1493b41f080d52a5ff2d9c235cffac1419b84028bd31dirk layer_info[i].visible ? "true" : "false"); 1494b41f080d52a5ff2d9c235cffac1419b84028bd31dirk (void) ReadBlobByte(image); /* filler */ 1495b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 149687038d5d4cc04fb99d6560ae95f3f07a87563323dirk size=ReadBlobLong(image); 1497b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (size != 0) 1498b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 1499b41f080d52a5ff2d9c235cffac1419b84028bd31dirk MagickSizeType 1500b41f080d52a5ff2d9c235cffac1419b84028bd31dirk combined_length, 1501b41f080d52a5ff2d9c235cffac1419b84028bd31dirk length; 1502b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1503b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (image->debug != MagickFalse) 1504b41f080d52a5ff2d9c235cffac1419b84028bd31dirk (void) LogMagickEvent(CoderEvent,GetMagickModule(), 1505b41f080d52a5ff2d9c235cffac1419b84028bd31dirk " layer contains additional info"); 150687038d5d4cc04fb99d6560ae95f3f07a87563323dirk length=ReadBlobLong(image); 1507b41f080d52a5ff2d9c235cffac1419b84028bd31dirk combined_length=length+4; 1508b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (length != 0) 1509b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 1510b41f080d52a5ff2d9c235cffac1419b84028bd31dirk /* 1511b41f080d52a5ff2d9c235cffac1419b84028bd31dirk Layer mask info. 1512b41f080d52a5ff2d9c235cffac1419b84028bd31dirk */ 15131fe0b879964fa7797e3d68574d297922a47c4034Cristy layer_info[i].mask.page.y=ReadBlobSignedLong(image); 15141fe0b879964fa7797e3d68574d297922a47c4034Cristy layer_info[i].mask.page.x=ReadBlobSignedLong(image); 151587038d5d4cc04fb99d6560ae95f3f07a87563323dirk layer_info[i].mask.page.height=(size_t) (ReadBlobLong(image)- 151687038d5d4cc04fb99d6560ae95f3f07a87563323dirk layer_info[i].mask.page.y); 151787038d5d4cc04fb99d6560ae95f3f07a87563323dirk layer_info[i].mask.page.width=(size_t) (ReadBlobLong(image)- 151887038d5d4cc04fb99d6560ae95f3f07a87563323dirk layer_info[i].mask.page.x); 1519a41d97fa7de942f144af6cfcceba24c523775c54dirk layer_info[i].mask.background=(unsigned char) ReadBlobByte( 1520a41d97fa7de942f144af6cfcceba24c523775c54dirk image); 1521a41d97fa7de942f144af6cfcceba24c523775c54dirk layer_info[i].mask.flags=(unsigned char) ReadBlobByte(image); 1522a41d97fa7de942f144af6cfcceba24c523775c54dirk if (!(layer_info[i].mask.flags & 0x01)) 1523a41d97fa7de942f144af6cfcceba24c523775c54dirk { 1524a41d97fa7de942f144af6cfcceba24c523775c54dirk layer_info[i].mask.page.y=layer_info[i].mask.page.y- 1525a41d97fa7de942f144af6cfcceba24c523775c54dirk layer_info[i].page.y; 1526a41d97fa7de942f144af6cfcceba24c523775c54dirk layer_info[i].mask.page.x=layer_info[i].mask.page.x- 1527a41d97fa7de942f144af6cfcceba24c523775c54dirk layer_info[i].page.x; 1528a41d97fa7de942f144af6cfcceba24c523775c54dirk } 1529b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (image->debug != MagickFalse) 1530b41f080d52a5ff2d9c235cffac1419b84028bd31dirk (void) LogMagickEvent(CoderEvent,GetMagickModule(), 1531b41f080d52a5ff2d9c235cffac1419b84028bd31dirk " layer mask: offset(%.20g,%.20g), size(%.20g,%.20g), length=%.20g", 1532a41d97fa7de942f144af6cfcceba24c523775c54dirk (double) layer_info[i].mask.page.x,(double) 1533a41d97fa7de942f144af6cfcceba24c523775c54dirk layer_info[i].mask.page.y,(double) layer_info[i].mask.page.width, 1534a41d97fa7de942f144af6cfcceba24c523775c54dirk (double) layer_info[i].mask.page.height,(double) 1535a41d97fa7de942f144af6cfcceba24c523775c54dirk ((MagickOffsetType) length)-18); 1536b41f080d52a5ff2d9c235cffac1419b84028bd31dirk /* 1537b41f080d52a5ff2d9c235cffac1419b84028bd31dirk Skip over the rest of the layer mask information. 1538b41f080d52a5ff2d9c235cffac1419b84028bd31dirk */ 1539a41d97fa7de942f144af6cfcceba24c523775c54dirk if (DiscardBlobBytes(image,(MagickSizeType) (length-18)) == MagickFalse) 1540b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 1541bd8bd8572e272ce0bc730bfa0296b8f048ea2da1dirk layer_info=DestroyLayerInfo(layer_info,number_layers); 1542419e5adbecfc7375751e7ac2ba30be0b1d35690fdirk ThrowBinaryException(CorruptImageError,"UnexpectedEndOfFile", 1543419e5adbecfc7375751e7ac2ba30be0b1d35690fdirk image->filename); 1544b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 1545b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 154687038d5d4cc04fb99d6560ae95f3f07a87563323dirk length=ReadBlobLong(image); 1547b41f080d52a5ff2d9c235cffac1419b84028bd31dirk combined_length+=length+4; 1548b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (length != 0) 1549b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 1550b41f080d52a5ff2d9c235cffac1419b84028bd31dirk /* 1551b41f080d52a5ff2d9c235cffac1419b84028bd31dirk Layer blending ranges info. 1552b41f080d52a5ff2d9c235cffac1419b84028bd31dirk */ 1553b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (image->debug != MagickFalse) 1554b41f080d52a5ff2d9c235cffac1419b84028bd31dirk (void) LogMagickEvent(CoderEvent,GetMagickModule(), 1555b41f080d52a5ff2d9c235cffac1419b84028bd31dirk " layer blending ranges: length=%.20g",(double) 1556b41f080d52a5ff2d9c235cffac1419b84028bd31dirk ((MagickOffsetType) length)); 1557b41f080d52a5ff2d9c235cffac1419b84028bd31dirk /* 1558b41f080d52a5ff2d9c235cffac1419b84028bd31dirk We read it, but don't use it... 1559b41f080d52a5ff2d9c235cffac1419b84028bd31dirk */ 1560b41f080d52a5ff2d9c235cffac1419b84028bd31dirk for (j=0; j < (ssize_t) (length); j+=8) 1561b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 156287038d5d4cc04fb99d6560ae95f3f07a87563323dirk size_t blend_source=ReadBlobLong(image); 156387038d5d4cc04fb99d6560ae95f3f07a87563323dirk size_t blend_dest=ReadBlobLong(image); 1564b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (image->debug != MagickFalse) 1565b41f080d52a5ff2d9c235cffac1419b84028bd31dirk (void) LogMagickEvent(CoderEvent,GetMagickModule(), 1566b41f080d52a5ff2d9c235cffac1419b84028bd31dirk " source(%x), dest(%x)",(unsigned int) 1567b41f080d52a5ff2d9c235cffac1419b84028bd31dirk blend_source,(unsigned int) blend_dest); 1568b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 1569b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 1570b41f080d52a5ff2d9c235cffac1419b84028bd31dirk /* 1571b41f080d52a5ff2d9c235cffac1419b84028bd31dirk Layer name. 1572b41f080d52a5ff2d9c235cffac1419b84028bd31dirk */ 1573b41f080d52a5ff2d9c235cffac1419b84028bd31dirk length=(size_t) ReadBlobByte(image); 1574b41f080d52a5ff2d9c235cffac1419b84028bd31dirk combined_length+=length+1; 1575f084319814dd6d347d596618a528c44d26e4a34adirk if (length > 0) 1576a41d97fa7de942f144af6cfcceba24c523775c54dirk (void) ReadBlob(image,(size_t) length++,layer_info[i].name); 1577a41d97fa7de942f144af6cfcceba24c523775c54dirk layer_info[i].name[length]='\0'; 1578b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (image->debug != MagickFalse) 1579b41f080d52a5ff2d9c235cffac1419b84028bd31dirk (void) LogMagickEvent(CoderEvent,GetMagickModule(), 1580b41f080d52a5ff2d9c235cffac1419b84028bd31dirk " layer name: %s",layer_info[i].name); 1581b41f080d52a5ff2d9c235cffac1419b84028bd31dirk /* 1582b41f080d52a5ff2d9c235cffac1419b84028bd31dirk Skip the rest of the variable data until we support it. 1583b41f080d52a5ff2d9c235cffac1419b84028bd31dirk */ 1584b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (image->debug != MagickFalse) 1585b41f080d52a5ff2d9c235cffac1419b84028bd31dirk (void) LogMagickEvent(CoderEvent,GetMagickModule(), 1586b41f080d52a5ff2d9c235cffac1419b84028bd31dirk " unsupported data: length=%.20g",(double) 1587b41f080d52a5ff2d9c235cffac1419b84028bd31dirk ((MagickOffsetType) (size-combined_length))); 15881b875d28a6423d6314bc1da914ade6d086cfe252cristy if (DiscardBlobBytes(image,(MagickSizeType) (size-combined_length)) == MagickFalse) 1589b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 1590bd8bd8572e272ce0bc730bfa0296b8f048ea2da1dirk layer_info=DestroyLayerInfo(layer_info,number_layers); 1591b41f080d52a5ff2d9c235cffac1419b84028bd31dirk ThrowBinaryException(CorruptImageError, 1592b41f080d52a5ff2d9c235cffac1419b84028bd31dirk "UnexpectedEndOfFile",image->filename); 1593b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 1594b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 1595b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 1596b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1597b41f080d52a5ff2d9c235cffac1419b84028bd31dirk for (i=0; i < number_layers; i++) 1598b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 1599b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if ((layer_info[i].page.width == 0) || 1600b41f080d52a5ff2d9c235cffac1419b84028bd31dirk (layer_info[i].page.height == 0)) 1601b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 1602b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (image->debug != MagickFalse) 1603b41f080d52a5ff2d9c235cffac1419b84028bd31dirk (void) LogMagickEvent(CoderEvent,GetMagickModule(), 1604b41f080d52a5ff2d9c235cffac1419b84028bd31dirk " layer data is empty"); 1605b41f080d52a5ff2d9c235cffac1419b84028bd31dirk continue; 1606b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 1607b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1608b41f080d52a5ff2d9c235cffac1419b84028bd31dirk /* 1609b41f080d52a5ff2d9c235cffac1419b84028bd31dirk Allocate layered image. 1610b41f080d52a5ff2d9c235cffac1419b84028bd31dirk */ 1611b41f080d52a5ff2d9c235cffac1419b84028bd31dirk layer_info[i].image=CloneImage(image,layer_info[i].page.width, 1612b41f080d52a5ff2d9c235cffac1419b84028bd31dirk layer_info[i].page.height,MagickFalse,exception); 1613b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (layer_info[i].image == (Image *) NULL) 1614b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 1615bd8bd8572e272ce0bc730bfa0296b8f048ea2da1dirk layer_info=DestroyLayerInfo(layer_info,number_layers); 1616b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (image->debug != MagickFalse) 1617b41f080d52a5ff2d9c235cffac1419b84028bd31dirk (void) LogMagickEvent(CoderEvent,GetMagickModule(), 1618b41f080d52a5ff2d9c235cffac1419b84028bd31dirk " allocation of image for layer %.20g failed",(double) i); 1619b41f080d52a5ff2d9c235cffac1419b84028bd31dirk ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", 1620b41f080d52a5ff2d9c235cffac1419b84028bd31dirk image->filename); 1621b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 1622b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 1623b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 16244d9863ca77e690fdde8653d1f3db0721bd25978edirk if (image_info->ping == MagickFalse) 1625b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 16264d9863ca77e690fdde8653d1f3db0721bd25978edirk for (i=0; i < number_layers; i++) 1627b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 16284d9863ca77e690fdde8653d1f3db0721bd25978edirk if (layer_info[i].image == (Image *) NULL) 1629b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 16304d9863ca77e690fdde8653d1f3db0721bd25978edirk for (j=0; j < layer_info[i].channels; j++) 16314d9863ca77e690fdde8653d1f3db0721bd25978edirk { 16321b875d28a6423d6314bc1da914ade6d086cfe252cristy if (DiscardBlobBytes(image,(MagickSizeType) 16334d9863ca77e690fdde8653d1f3db0721bd25978edirk layer_info[i].channel_info[j].size) == MagickFalse) 16344d9863ca77e690fdde8653d1f3db0721bd25978edirk { 16354d9863ca77e690fdde8653d1f3db0721bd25978edirk layer_info=DestroyLayerInfo(layer_info,number_layers); 16364d9863ca77e690fdde8653d1f3db0721bd25978edirk ThrowBinaryException(CorruptImageError, 16374d9863ca77e690fdde8653d1f3db0721bd25978edirk "UnexpectedEndOfFile",image->filename); 16384d9863ca77e690fdde8653d1f3db0721bd25978edirk } 16394d9863ca77e690fdde8653d1f3db0721bd25978edirk } 16404d9863ca77e690fdde8653d1f3db0721bd25978edirk continue; 1641b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 1642b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 16434d9863ca77e690fdde8653d1f3db0721bd25978edirk if (image->debug != MagickFalse) 16444d9863ca77e690fdde8653d1f3db0721bd25978edirk (void) LogMagickEvent(CoderEvent,GetMagickModule(), 16454d9863ca77e690fdde8653d1f3db0721bd25978edirk " reading data for layer %.20g",(double) i); 1646b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 16474d9863ca77e690fdde8653d1f3db0721bd25978edirk status=ReadPSDLayer(image,psd_info,&layer_info[i],exception); 16484d9863ca77e690fdde8653d1f3db0721bd25978edirk if (status == MagickFalse) 16494d9863ca77e690fdde8653d1f3db0721bd25978edirk break; 1650b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 16514d9863ca77e690fdde8653d1f3db0721bd25978edirk status=SetImageProgress(image,LoadImagesTag,i,(MagickSizeType) 16524d9863ca77e690fdde8653d1f3db0721bd25978edirk number_layers); 16534d9863ca77e690fdde8653d1f3db0721bd25978edirk if (status == MagickFalse) 16544d9863ca77e690fdde8653d1f3db0721bd25978edirk break; 16554d9863ca77e690fdde8653d1f3db0721bd25978edirk } 16564d9863ca77e690fdde8653d1f3db0721bd25978edirk } 1657b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1658b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (status != MagickFalse) 1659b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 1660b41f080d52a5ff2d9c235cffac1419b84028bd31dirk for (i=0; i < number_layers; i++) 1661b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 1662b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (layer_info[i].image == (Image *) NULL) 1663b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 1664b41f080d52a5ff2d9c235cffac1419b84028bd31dirk for (j=i; j < number_layers - 1; j++) 1665b41f080d52a5ff2d9c235cffac1419b84028bd31dirk layer_info[j] = layer_info[j+1]; 1666b41f080d52a5ff2d9c235cffac1419b84028bd31dirk number_layers--; 1667b41f080d52a5ff2d9c235cffac1419b84028bd31dirk i--; 1668b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 1669b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 1670b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1671b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (number_layers > 0) 1672b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 1673b41f080d52a5ff2d9c235cffac1419b84028bd31dirk for (i=0; i < number_layers; i++) 1674b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 1675b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (i > 0) 1676b41f080d52a5ff2d9c235cffac1419b84028bd31dirk layer_info[i].image->previous=layer_info[i-1].image; 1677b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (i < (number_layers-1)) 1678b41f080d52a5ff2d9c235cffac1419b84028bd31dirk layer_info[i].image->next=layer_info[i+1].image; 1679b41f080d52a5ff2d9c235cffac1419b84028bd31dirk layer_info[i].image->page=layer_info[i].page; 1680b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 1681b41f080d52a5ff2d9c235cffac1419b84028bd31dirk image->next=layer_info[0].image; 1682b41f080d52a5ff2d9c235cffac1419b84028bd31dirk layer_info[0].image->previous=image; 1683b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 1684bd9f1e7d1bd2c8e2cf7895d133c5c5b5cd3526b6dirk layer_info=(LayerInfo *) RelinquishMagickMemory(layer_info); 1685b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 1686bd9f1e7d1bd2c8e2cf7895d133c5c5b5cd3526b6dirk else 1687bd9f1e7d1bd2c8e2cf7895d133c5c5b5cd3526b6dirk layer_info=DestroyLayerInfo(layer_info,number_layers); 1688b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 1689b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1690b41f080d52a5ff2d9c235cffac1419b84028bd31dirk return(status); 1691b41f080d52a5ff2d9c235cffac1419b84028bd31dirk} 1692b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1693b20a1794de28edf28c46f2268914c15781482530dirkstatic MagickBooleanType ReadPSDMergedImage(const ImageInfo *image_info, 1694b20a1794de28edf28c46f2268914c15781482530dirk Image *image,const PSDInfo *psd_info,ExceptionInfo *exception) 1695b41f080d52a5ff2d9c235cffac1419b84028bd31dirk{ 1696b41f080d52a5ff2d9c235cffac1419b84028bd31dirk MagickOffsetType 1697b41f080d52a5ff2d9c235cffac1419b84028bd31dirk *offsets; 1698b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1699b20a1794de28edf28c46f2268914c15781482530dirk MagickBooleanType 1700b41f080d52a5ff2d9c235cffac1419b84028bd31dirk status; 1701b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1702b41f080d52a5ff2d9c235cffac1419b84028bd31dirk PSDCompressionType 1703b41f080d52a5ff2d9c235cffac1419b84028bd31dirk compression; 1704b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1705b41f080d52a5ff2d9c235cffac1419b84028bd31dirk register ssize_t 1706b41f080d52a5ff2d9c235cffac1419b84028bd31dirk i; 1707b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1708b41f080d52a5ff2d9c235cffac1419b84028bd31dirk compression=(PSDCompressionType) ReadBlobMSBShort(image); 1709b41f080d52a5ff2d9c235cffac1419b84028bd31dirk image->compression=ConvertPSDCompression(compression); 1710b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1711b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (compression != Raw && compression != RLE) 1712b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 1713b41f080d52a5ff2d9c235cffac1419b84028bd31dirk (void) ThrowMagickException(exception,GetMagickModule(), 1714b41f080d52a5ff2d9c235cffac1419b84028bd31dirk TypeWarning,"CompressionNotSupported","'%.20g'",(double) compression); 1715b41f080d52a5ff2d9c235cffac1419b84028bd31dirk return(MagickFalse); 1716b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 1717b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1718b41f080d52a5ff2d9c235cffac1419b84028bd31dirk offsets=(MagickOffsetType *) NULL; 1719b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (compression == RLE) 1720b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 1721b41f080d52a5ff2d9c235cffac1419b84028bd31dirk offsets=ReadPSDRLEOffsets(image,psd_info,image->rows*psd_info->channels); 1722b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (offsets == (MagickOffsetType *) NULL) 1723b41f080d52a5ff2d9c235cffac1419b84028bd31dirk ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", 1724b41f080d52a5ff2d9c235cffac1419b84028bd31dirk image->filename); 1725b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 1726b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1727b41f080d52a5ff2d9c235cffac1419b84028bd31dirk status=MagickTrue; 1728b41f080d52a5ff2d9c235cffac1419b84028bd31dirk for (i=0; i < (ssize_t) psd_info->channels; i++) 1729b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 1730b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (compression == RLE) 1731b41f080d52a5ff2d9c235cffac1419b84028bd31dirk status=ReadPSDChannelRLE(image,psd_info,i,offsets+(i*image->rows), 1732b41f080d52a5ff2d9c235cffac1419b84028bd31dirk exception); 1733b41f080d52a5ff2d9c235cffac1419b84028bd31dirk else 1734b41f080d52a5ff2d9c235cffac1419b84028bd31dirk status=ReadPSDChannelRaw(image,psd_info->channels,i,exception); 1735b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1736b20a1794de28edf28c46f2268914c15781482530dirk if (status != MagickFalse) 1737b20a1794de28edf28c46f2268914c15781482530dirk status=SetImageProgress(image,LoadImagesTag,i,psd_info->channels); 1738b20a1794de28edf28c46f2268914c15781482530dirk 1739b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (status == MagickFalse) 1740b41f080d52a5ff2d9c235cffac1419b84028bd31dirk break; 1741b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 1742b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1743b20a1794de28edf28c46f2268914c15781482530dirk if ((status != MagickFalse) && (image->colorspace == CMYKColorspace)) 1744b20a1794de28edf28c46f2268914c15781482530dirk status=NegateCMYK(image,exception); 1745b20a1794de28edf28c46f2268914c15781482530dirk 1746b20a1794de28edf28c46f2268914c15781482530dirk if (status != MagickFalse) 1747b20a1794de28edf28c46f2268914c15781482530dirk status=CorrectPSDAlphaBlend(image_info,image,exception); 1748b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1749b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (offsets != (MagickOffsetType *) NULL) 1750b41f080d52a5ff2d9c235cffac1419b84028bd31dirk offsets=(MagickOffsetType *) RelinquishMagickMemory(offsets); 1751b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1752b41f080d52a5ff2d9c235cffac1419b84028bd31dirk return(status); 1753b41f080d52a5ff2d9c235cffac1419b84028bd31dirk} 1754b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 175590de83d3fe5221a8896ab53556c2e7992078a96ccristystatic Image *ReadPSDImage(const ImageInfo *image_info,ExceptionInfo *exception) 1756b41f080d52a5ff2d9c235cffac1419b84028bd31dirk{ 1757b41f080d52a5ff2d9c235cffac1419b84028bd31dirk Image 1758b41f080d52a5ff2d9c235cffac1419b84028bd31dirk *image; 1759b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1760b41f080d52a5ff2d9c235cffac1419b84028bd31dirk MagickBooleanType 176118c0e4dff391a0a98e7f478d0d86bbd08f7708d0dirk has_merged_image, 1762a41d97fa7de942f144af6cfcceba24c523775c54dirk skip_layers; 1763b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1764b41f080d52a5ff2d9c235cffac1419b84028bd31dirk MagickOffsetType 1765b41f080d52a5ff2d9c235cffac1419b84028bd31dirk offset; 1766b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1767b41f080d52a5ff2d9c235cffac1419b84028bd31dirk MagickSizeType 1768b41f080d52a5ff2d9c235cffac1419b84028bd31dirk length; 1769b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1770b20a1794de28edf28c46f2268914c15781482530dirk MagickBooleanType 1771a41d97fa7de942f144af6cfcceba24c523775c54dirk status; 1772a41d97fa7de942f144af6cfcceba24c523775c54dirk 1773b41f080d52a5ff2d9c235cffac1419b84028bd31dirk PSDInfo 1774b41f080d52a5ff2d9c235cffac1419b84028bd31dirk psd_info; 1775b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1776b41f080d52a5ff2d9c235cffac1419b84028bd31dirk register ssize_t 1777b41f080d52a5ff2d9c235cffac1419b84028bd31dirk i; 1778b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1779b41f080d52a5ff2d9c235cffac1419b84028bd31dirk ssize_t 1780b41f080d52a5ff2d9c235cffac1419b84028bd31dirk count; 1781b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1782b41f080d52a5ff2d9c235cffac1419b84028bd31dirk unsigned char 1783b41f080d52a5ff2d9c235cffac1419b84028bd31dirk *data; 1784b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1785b41f080d52a5ff2d9c235cffac1419b84028bd31dirk /* 1786b41f080d52a5ff2d9c235cffac1419b84028bd31dirk Open image file. 1787b41f080d52a5ff2d9c235cffac1419b84028bd31dirk */ 1788b41f080d52a5ff2d9c235cffac1419b84028bd31dirk assert(image_info != (const ImageInfo *) NULL); 1789e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy assert(image_info->signature == MagickCoreSignature); 1790b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (image_info->debug != MagickFalse) 1791b41f080d52a5ff2d9c235cffac1419b84028bd31dirk (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", 1792b41f080d52a5ff2d9c235cffac1419b84028bd31dirk image_info->filename); 1793b41f080d52a5ff2d9c235cffac1419b84028bd31dirk assert(exception != (ExceptionInfo *) NULL); 1794e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy assert(exception->signature == MagickCoreSignature); 1795b41f080d52a5ff2d9c235cffac1419b84028bd31dirk 1796b41f080d52a5ff2d9c235cffac1419b84028bd31dirk image=AcquireImage(image_info,exception); 1797b41f080d52a5ff2d9c235cffac1419b84028bd31dirk status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); 1798b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (status == MagickFalse) 1799b41f080d52a5ff2d9c235cffac1419b84028bd31dirk { 1800b41f080d52a5ff2d9c235cffac1419b84028bd31dirk image=DestroyImageList(image); 1801b41f080d52a5ff2d9c235cffac1419b84028bd31dirk return((Image *) NULL); 1802b41f080d52a5ff2d9c235cffac1419b84028bd31dirk } 1803b41f080d52a5ff2d9c235cffac1419b84028bd31dirk /* 1804b41f080d52a5ff2d9c235cffac1419b84028bd31dirk Read image header. 1805b41f080d52a5ff2d9c235cffac1419b84028bd31dirk */ 1806fc16b54cdf77910dd5014ce819440662ced29d09dirk image->endian=MSBEndian; 1807b41f080d52a5ff2d9c235cffac1419b84028bd31dirk count=ReadBlob(image,4,(unsigned char *) psd_info.signature); 1808b41f080d52a5ff2d9c235cffac1419b84028bd31dirk psd_info.version=ReadBlobMSBShort(image); 1809b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if ((count == 0) || (LocaleNCompare(psd_info.signature,"8BPS",4) != 0) || 1810b41f080d52a5ff2d9c235cffac1419b84028bd31dirk ((psd_info.version != 1) && (psd_info.version != 2))) 1811b41f080d52a5ff2d9c235cffac1419b84028bd31dirk ThrowReaderException(CorruptImageError,"ImproperImageHeader"); 1812f308152b28249d599fa01dd41b1518c4ddfc5e60dirk (void) ReadBlob(image,6,psd_info.reserved); 1813b41f080d52a5ff2d9c235cffac1419b84028bd31dirk psd_info.channels=ReadBlobMSBShort(image); 1814b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (psd_info.channels > MaxPSDChannels) 1815b41f080d52a5ff2d9c235cffac1419b84028bd31dirk ThrowReaderException(CorruptImageError,"MaximumChannelsExceeded"); 1816b41f080d52a5ff2d9c235cffac1419b84028bd31dirk psd_info.rows=ReadBlobMSBLong(image); 1817b41f080d52a5ff2d9c235cffac1419b84028bd31dirk psd_info.columns=ReadBlobMSBLong(image); 1818b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if ((psd_info.version == 1) && ((psd_info.rows > 30000) || 1819b41f080d52a5ff2d9c235cffac1419b84028bd31dirk (psd_info.columns > 30000))) 1820b41f080d52a5ff2d9c235cffac1419b84028bd31dirk ThrowReaderException(CorruptImageError,"ImproperImageHeader"); 1821b41f080d52a5ff2d9c235cffac1419b84028bd31dirk psd_info.depth=ReadBlobMSBShort(image); 1822b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if ((psd_info.depth != 1) && (psd_info.depth != 8) && (psd_info.depth != 16)) 1823b41f080d52a5ff2d9c235cffac1419b84028bd31dirk ThrowReaderException(CorruptImageError,"ImproperImageHeader"); 1824b41f080d52a5ff2d9c235cffac1419b84028bd31dirk psd_info.mode=ReadBlobMSBShort(image); 1825b41f080d52a5ff2d9c235cffac1419b84028bd31dirk if (image->debug != MagickFalse) 18263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) LogMagickEvent(CoderEvent,GetMagickModule(), 1827e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy " Image is %.20g x %.20g with channels=%.20g, depth=%.20g, mode=%s", 1828e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy (double) psd_info.columns,(double) psd_info.rows,(double) 1829e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy psd_info.channels,(double) psd_info.depth,ModeToString((PSDImageType) 1830e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy psd_info.mode)); 18313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 18323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Initialize image. 18333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 18343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->depth=psd_info.depth; 18353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->columns=psd_info.columns; 18363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->rows=psd_info.rows; 1837acabb847a592ca5e430c1c0949d03acfc0b78bb9cristy status=SetImageExtent(image,image->columns,image->rows,exception); 1838acabb847a592ca5e430c1c0949d03acfc0b78bb9cristy if (status == MagickFalse) 1839acabb847a592ca5e430c1c0949d03acfc0b78bb9cristy return(DestroyImageList(image)); 1840ea1a8aa04a9fe1500104284407c1cc06d20da699cristy if (SetImageBackgroundColor(image,exception) == MagickFalse) 184195524f92fc346f548f202d36ffc6a17fdbd1b1cbcristy { 184295524f92fc346f548f202d36ffc6a17fdbd1b1cbcristy image=DestroyImageList(image); 184395524f92fc346f548f202d36ffc6a17fdbd1b1cbcristy return((Image *) NULL); 184495524f92fc346f548f202d36ffc6a17fdbd1b1cbcristy } 18453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (psd_info.mode == LabMode) 1846e2c4f18a7274c0c5c6231a2f3d73741a87d583facristy SetImageColorspace(image,LabColorspace,exception); 18473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (psd_info.mode == CMYKMode) 184884affaa1fd31c85f2c323db093508352c1df05abdirk { 184984affaa1fd31c85f2c323db093508352c1df05abdirk SetImageColorspace(image,CMYKColorspace,exception); 1850deca4044d29506bb0d54806e44bdbe3c802eb430dirk image->alpha_trait=psd_info.channels > 4 ? BlendPixelTrait : 185184affaa1fd31c85f2c323db093508352c1df05abdirk UndefinedPixelTrait; 185284affaa1fd31c85f2c323db093508352c1df05abdirk } 185384affaa1fd31c85f2c323db093508352c1df05abdirk else if ((psd_info.mode == BitmapMode) || (psd_info.mode == GrayscaleMode) || 18543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (psd_info.mode == DuotoneMode)) 18553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 1856afd0fd11c04ff6716f320206eba3a64a2ca95a09cristy status=AcquireImageColormap(image,psd_info.depth != 16 ? 256 : 65536, 1857afd0fd11c04ff6716f320206eba3a64a2ca95a09cristy exception); 1858afd0fd11c04ff6716f320206eba3a64a2ca95a09cristy if (status == MagickFalse) 185952cf7f1d54f12223fd4ca0c2a428811c003f81ddcristy ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); 18603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->debug != MagickFalse) 18613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) LogMagickEvent(CoderEvent,GetMagickModule(), 1862dede49f1361cdf0a7aa29aa281b6f6e9a565f0facristy " Image colormap allocated"); 1863e2c4f18a7274c0c5c6231a2f3d73741a87d583facristy SetImageColorspace(image,GRAYColorspace,exception); 1864deca4044d29506bb0d54806e44bdbe3c802eb430dirk image->alpha_trait=psd_info.channels > 1 ? BlendPixelTrait : 186584affaa1fd31c85f2c323db093508352c1df05abdirk UndefinedPixelTrait; 18663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 186784affaa1fd31c85f2c323db093508352c1df05abdirk else 1868deca4044d29506bb0d54806e44bdbe3c802eb430dirk image->alpha_trait=psd_info.channels > 3 ? BlendPixelTrait : 186984affaa1fd31c85f2c323db093508352c1df05abdirk UndefinedPixelTrait; 18703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 18713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Read PSD raster colormap only present for indexed and duotone images. 18723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 18733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy length=ReadBlobMSBLong(image); 18743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (length != 0) 18753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 18763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->debug != MagickFalse) 18773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) LogMagickEvent(CoderEvent,GetMagickModule(), 18783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy " reading colormap"); 18793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (psd_info.mode == DuotoneMode) 18803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 18813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 18823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Duotone image data; the format of this data is undocumented. 18833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 188456ed31cc763800a9fb1f0df96104c354b40d2cbccristy data=(unsigned char *) AcquireQuantumMemory((size_t) length, 188556ed31cc763800a9fb1f0df96104c354b40d2cbccristy sizeof(*data)); 18863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (data == (unsigned char *) NULL) 18873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); 1888f308152b28249d599fa01dd41b1518c4ddfc5e60dirk (void) ReadBlob(image,(size_t) length,data); 18893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy data=(unsigned char *) RelinquishMagickMemory(data); 18903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 18913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 18923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 189318a9b97ccf4867621620ac1d81c38f5d81e1f4c9cristy size_t 189418a9b97ccf4867621620ac1d81c38f5d81e1f4c9cristy number_colors; 189518a9b97ccf4867621620ac1d81c38f5d81e1f4c9cristy 18963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 18973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Read PSD raster colormap. 18983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 189918a9b97ccf4867621620ac1d81c38f5d81e1f4c9cristy number_colors=length/3; 190018a9b97ccf4867621620ac1d81c38f5d81e1f4c9cristy if (number_colors > 65536) 190118a9b97ccf4867621620ac1d81c38f5d81e1f4c9cristy ThrowReaderException(CorruptImageError,"ImproperImageHeader"); 190218a9b97ccf4867621620ac1d81c38f5d81e1f4c9cristy if (AcquireImageColormap(image,number_colors,exception) == MagickFalse) 19033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); 1904bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (i=0; i < (ssize_t) image->colors; i++) 19053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->colormap[i].red=ScaleCharToQuantum((unsigned char) 19063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ReadBlobByte(image)); 1907bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (i=0; i < (ssize_t) image->colors; i++) 19083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->colormap[i].green=ScaleCharToQuantum((unsigned char) 19093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ReadBlobByte(image)); 1910bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (i=0; i < (ssize_t) image->colors; i++) 19113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->colormap[i].blue=ScaleCharToQuantum((unsigned char) 19123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ReadBlobByte(image)); 19138a46d827a124555f0c48fb2368ec1bba8e079ab6cristy image->alpha_trait=UndefinedPixelTrait; 19143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 19153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 1916198fffab4daf8aea88badd9c629350e5b26ec32fdirk if ((image->depth == 1) && (image->storage_class != PseudoClass)) 1917198fffab4daf8aea88badd9c629350e5b26ec32fdirk ThrowReaderException(CorruptImageError, "ImproperImageHeader"); 191818c0e4dff391a0a98e7f478d0d86bbd08f7708d0dirk has_merged_image=MagickTrue; 19193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy length=ReadBlobMSBLong(image); 19203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (length != 0) 19213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 19223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned char 19233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *blocks; 19243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 19253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 19263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Image resources block. 19273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 19283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->debug != MagickFalse) 19293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) LogMagickEvent(CoderEvent,GetMagickModule(), 19302b9582a27910c7baaeb04b7e969638328fa70095cristy " reading image resource blocks - %.20g bytes",(double) 19312b9582a27910c7baaeb04b7e969638328fa70095cristy ((MagickOffsetType) length)); 19327ec893210d13a7424e5a7c3200568f1bf5317040dirk blocks=(unsigned char *) AcquireQuantumMemory((size_t) length, 193356ed31cc763800a9fb1f0df96104c354b40d2cbccristy sizeof(*blocks)); 19343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (blocks == (unsigned char *) NULL) 19353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); 193656ed31cc763800a9fb1f0df96104c354b40d2cbccristy count=ReadBlob(image,(size_t) length,blocks); 19374b1b9c0522628887195bad3a6723f7000b0c9a58dirk if ((count != (ssize_t) length) || (length < 4) || 19383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (LocaleNCompare((char *) blocks,"8BIM",4) != 0)) 19393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 19403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy blocks=(unsigned char *) RelinquishMagickMemory(blocks); 19413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ThrowReaderException(CorruptImageError,"ImproperImageHeader"); 19423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 19437ec893210d13a7424e5a7c3200568f1bf5317040dirk ParseImageResourceBlocks(image,blocks,(size_t) length,&has_merged_image, 19447ec893210d13a7424e5a7c3200568f1bf5317040dirk exception); 19453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy blocks=(unsigned char *) RelinquishMagickMemory(blocks); 19463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 19473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 19483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Layer and mask block. 19493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 19502d3d87fbdee6704f11aad6e75d00847fe10f4d0ecristy length=GetPSDSize(&psd_info,image); 19513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (length == 8) 19523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 19533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy length=ReadBlobMSBLong(image); 19543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy length=ReadBlobMSBLong(image); 19553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 1956b41f080d52a5ff2d9c235cffac1419b84028bd31dirk offset=TellBlob(image); 1957b41f080d52a5ff2d9c235cffac1419b84028bd31dirk skip_layers=MagickFalse; 195818c0e4dff391a0a98e7f478d0d86bbd08f7708d0dirk if ((image_info->number_scenes == 1) && (image_info->scene == 0) && 195918c0e4dff391a0a98e7f478d0d86bbd08f7708d0dirk (has_merged_image != MagickFalse)) 1960d4297029a6faeb030aa4da519db921992dda664fcristy { 1961374b8ad2958410591db2e8c42e9b65ef89655e00cristy if (image->debug != MagickFalse) 1962374b8ad2958410591db2e8c42e9b65ef89655e00cristy (void) LogMagickEvent(CoderEvent,GetMagickModule(), 1963374b8ad2958410591db2e8c42e9b65ef89655e00cristy " read composite only"); 1964b41f080d52a5ff2d9c235cffac1419b84028bd31dirk skip_layers=MagickTrue; 1965d4297029a6faeb030aa4da519db921992dda664fcristy } 19663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (length == 0) 19673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 19683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->debug != MagickFalse) 19693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) LogMagickEvent(CoderEvent,GetMagickModule(), 19703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy " image has no layers"); 19713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 19723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 19733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 19744d9863ca77e690fdde8653d1f3db0721bd25978edirk if (ReadPSDLayers(image,image_info,&psd_info,skip_layers,exception) != 19754d9863ca77e690fdde8653d1f3db0721bd25978edirk MagickTrue) 19766f20531b06ddc2852ec30506e13798363f534e53dirk { 19776f20531b06ddc2852ec30506e13798363f534e53dirk (void) CloseBlob(image); 1978419e5adbecfc7375751e7ac2ba30be0b1d35690fdirk image=DestroyImageList(image); 19796f20531b06ddc2852ec30506e13798363f534e53dirk return((Image *) NULL); 19806f20531b06ddc2852ec30506e13798363f534e53dirk } 19813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1982b41f080d52a5ff2d9c235cffac1419b84028bd31dirk /* 1983b41f080d52a5ff2d9c235cffac1419b84028bd31dirk Skip the rest of the layer and mask information. 1984b41f080d52a5ff2d9c235cffac1419b84028bd31dirk */ 1985b41f080d52a5ff2d9c235cffac1419b84028bd31dirk SeekBlob(image,offset+length,SEEK_SET); 19863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 19874d9863ca77e690fdde8653d1f3db0721bd25978edirk /* 198889e226084238a1611a572467a330e6e7145059becristy If we are only "pinging" the image, then we're done - so return. 198989e226084238a1611a572467a330e6e7145059becristy */ 199089e226084238a1611a572467a330e6e7145059becristy if (image_info->ping != MagickFalse) 199189e226084238a1611a572467a330e6e7145059becristy { 199289e226084238a1611a572467a330e6e7145059becristy (void) CloseBlob(image); 199389e226084238a1611a572467a330e6e7145059becristy return(GetFirstImageInList(image)); 199489e226084238a1611a572467a330e6e7145059becristy } 199589e226084238a1611a572467a330e6e7145059becristy /* 1996b41f080d52a5ff2d9c235cffac1419b84028bd31dirk Read the precombined layer, present for PSD < 4 compatibility. 19973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 19983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->debug != MagickFalse) 19993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) LogMagickEvent(CoderEvent,GetMagickModule(), 20003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy " reading the precombined layer"); 200190de83d3fe5221a8896ab53556c2e7992078a96ccristy if ((has_merged_image != MagickFalse) || (GetImageListLength(image) == 1)) 2002b20a1794de28edf28c46f2268914c15781482530dirk has_merged_image=(MagickBooleanType) ReadPSDMergedImage(image_info,image, 2003b20a1794de28edf28c46f2268914c15781482530dirk &psd_info,exception); 200490de83d3fe5221a8896ab53556c2e7992078a96ccristy if ((has_merged_image == MagickFalse) && (GetImageListLength(image) == 1) && 200590de83d3fe5221a8896ab53556c2e7992078a96ccristy (length != 0)) 20062de94f5ff88944751b5d625aed674d56b59237afdirk { 20072de94f5ff88944751b5d625aed674d56b59237afdirk SeekBlob(image,offset,SEEK_SET); 200890de83d3fe5221a8896ab53556c2e7992078a96ccristy status=ReadPSDLayers(image,image_info,&psd_info,MagickFalse,exception); 200990de83d3fe5221a8896ab53556c2e7992078a96ccristy if (status != MagickTrue) 20102de94f5ff88944751b5d625aed674d56b59237afdirk { 20112de94f5ff88944751b5d625aed674d56b59237afdirk (void) CloseBlob(image); 2012b9ed408ffc0401e23dfd98b843dd4ae4313c0255dirk image=DestroyImageList(image); 20132de94f5ff88944751b5d625aed674d56b59237afdirk return((Image *) NULL); 20142de94f5ff88944751b5d625aed674d56b59237afdirk } 20152de94f5ff88944751b5d625aed674d56b59237afdirk } 201690de83d3fe5221a8896ab53556c2e7992078a96ccristy if ((has_merged_image == MagickFalse) && (GetImageListLength(image) > 1)) 201718c0e4dff391a0a98e7f478d0d86bbd08f7708d0dirk { 201818c0e4dff391a0a98e7f478d0d86bbd08f7708d0dirk Image 201918c0e4dff391a0a98e7f478d0d86bbd08f7708d0dirk *merged; 202018c0e4dff391a0a98e7f478d0d86bbd08f7708d0dirk 202118c0e4dff391a0a98e7f478d0d86bbd08f7708d0dirk SetImageAlphaChannel(image,TransparentAlphaChannel,exception); 202218c0e4dff391a0a98e7f478d0d86bbd08f7708d0dirk image->background_color.alpha=TransparentAlpha; 20237b5a0d558aa402f0d0a853c97866c14856a10be9dirk image->background_color.alpha_trait=BlendPixelTrait; 202418c0e4dff391a0a98e7f478d0d86bbd08f7708d0dirk merged=MergeImageLayers(image,FlattenLayer,exception); 202518c0e4dff391a0a98e7f478d0d86bbd08f7708d0dirk ReplaceImageInList(&image,merged); 202618c0e4dff391a0a98e7f478d0d86bbd08f7708d0dirk } 20273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) CloseBlob(image); 20283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(GetFirstImageInList(image)); 20293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 20303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 20313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 20323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 20333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 20343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 20353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 20363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% R e g i s t e r P S D I m a g e % 20373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 20383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 20393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 20403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 20413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 20423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% RegisterPSDImage() adds properties for the PSD image format to 20433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% the list of supported formats. The properties include the image format 20443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% tag, a method to read and/or write the format, whether the format 20453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% supports the saving of more than one frame to the same file or blob, 20463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% whether the format supports native in-memory I/O, and a brief 20473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% description of the format. 20483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 20493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% The format of the RegisterPSDImage method is: 20503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 2051bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy% size_t RegisterPSDImage(void) 20523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 20533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 2054bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyModuleExport size_t RegisterPSDImage(void) 20553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 20563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy MagickInfo 20573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *entry; 20583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 205906b627a07ff44e1ff93ef1288c9f428066ded10ddirk entry=AcquireMagickInfo("PSD","PSB","Adobe Large Document Format"); 2060b42330138c186026c567ffb0cce21aa06137b730cristy entry->decoder=(DecodeImageHandler *) ReadPSDImage; 2061b42330138c186026c567ffb0cce21aa06137b730cristy entry->encoder=(EncodeImageHandler *) WritePSDImage; 2062b42330138c186026c567ffb0cce21aa06137b730cristy entry->magick=(IsImageFormatHandler *) IsPSD; 206308e9a113db499034abb5ad8d59b42f8eca3c641cdirk entry->flags|=CoderSeekableStreamFlag; 2064b42330138c186026c567ffb0cce21aa06137b730cristy (void) RegisterMagickInfo(entry); 206506b627a07ff44e1ff93ef1288c9f428066ded10ddirk entry=AcquireMagickInfo("PSD","PSD","Adobe Photoshop bitmap"); 20663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy entry->decoder=(DecodeImageHandler *) ReadPSDImage; 20673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy entry->encoder=(EncodeImageHandler *) WritePSDImage; 20683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy entry->magick=(IsImageFormatHandler *) IsPSD; 206908e9a113db499034abb5ad8d59b42f8eca3c641cdirk entry->flags|=CoderSeekableStreamFlag; 20703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) RegisterMagickInfo(entry); 20713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickImageCoderSignature); 20723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 20733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 20743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 20753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 20763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 20773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 20783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 20793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% U n r e g i s t e r P S D I m a g e % 20803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 20813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 20823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 20833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 20843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 20853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% UnregisterPSDImage() removes format registrations made by the 20863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% PSD module from the list of supported formats. 20873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 20883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% The format of the UnregisterPSDImage method is: 20893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 20903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% UnregisterPSDImage(void) 20913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 20923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 20933ed852eea50f9d4cd633efb8c2b054b8e33c253cristyModuleExport void UnregisterPSDImage(void) 20943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 2095b42330138c186026c567ffb0cce21aa06137b730cristy (void) UnregisterMagickInfo("PSB"); 20963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) UnregisterMagickInfo("PSD"); 20973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 20983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 20993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 21003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 21013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 21023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 21033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 21043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% W r i t e P S D I m a g e % 21053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 21063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 21073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 21083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 21093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 2110b1459bce38004e27d61bef953617d25747264ff4cristy% WritePSDImage() writes an image in the Adobe Photoshop encoded image format. 21113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 21123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% The format of the WritePSDImage method is: 21133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 21141ab941fc759aa277e7f3a6050d149edfa4b29446dirk% MagickBooleanType WritePSDImage(const ImageInfo *image_info,Image *image, 21151ab941fc759aa277e7f3a6050d149edfa4b29446dirk% ExceptionInfo *exception) 21163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 21173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows. 21183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 21193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o image_info: the image info. 21203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 21213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o image: The image. 21223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 21233a37efd7ece979e9c63dc8f2f2d3816bab8b1156cristy% o exception: return any errors or warnings in this structure. 21243a37efd7ece979e9c63dc8f2f2d3816bab8b1156cristy% 21253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 21263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 212750aea4a7536abc82a6877cd256987666d14d54d0cristystatic inline ssize_t SetPSDOffset(const PSDInfo *psd_info,Image *image, 2128f0460eee0be6e6f31666d8eb784eb002399ff39fcristy const size_t offset) 2129f0460eee0be6e6f31666d8eb784eb002399ff39fcristy{ 2130f0460eee0be6e6f31666d8eb784eb002399ff39fcristy if (psd_info->version == 1) 213156ed31cc763800a9fb1f0df96104c354b40d2cbccristy return(WriteBlobMSBShort(image,(unsigned short) offset)); 213256ed31cc763800a9fb1f0df96104c354b40d2cbccristy return(WriteBlobMSBLong(image,(unsigned short) offset)); 2133f0460eee0be6e6f31666d8eb784eb002399ff39fcristy} 2134f0460eee0be6e6f31666d8eb784eb002399ff39fcristy 213550aea4a7536abc82a6877cd256987666d14d54d0cristystatic inline ssize_t SetPSDSize(const PSDInfo *psd_info,Image *image, 2136f0460eee0be6e6f31666d8eb784eb002399ff39fcristy const MagickSizeType size) 2137f0460eee0be6e6f31666d8eb784eb002399ff39fcristy{ 2138f0460eee0be6e6f31666d8eb784eb002399ff39fcristy if (psd_info->version == 1) 213956ed31cc763800a9fb1f0df96104c354b40d2cbccristy return(WriteBlobMSBLong(image,(unsigned int) size)); 2140f0460eee0be6e6f31666d8eb784eb002399ff39fcristy return(WriteBlobMSBLongLong(image,size)); 2141f0460eee0be6e6f31666d8eb784eb002399ff39fcristy} 2142f0460eee0be6e6f31666d8eb784eb002399ff39fcristy 21434aff1576adab1eae438d2d5b3ac2dde8418ccba8cristystatic size_t PSDPackbitsEncodeImage(Image *image,const size_t length, 2144018f07f7333b25743d0afff892450cebdb905c1acristy const unsigned char *pixels,unsigned char *compact_pixels, 2145018f07f7333b25743d0afff892450cebdb905c1acristy ExceptionInfo *exception) 21464aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy{ 21474aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy int 21484aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy count; 21494aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy 2150bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy register ssize_t 21514aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy i, 21524aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy j; 21534aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy 21544aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy register unsigned char 21554aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy *q; 21564aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy 21574aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy unsigned char 21584aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy *packbits; 21594aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy 21604aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy /* 21614aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy Compress pixels with Packbits encoding. 21624aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy */ 21634aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy assert(image != (Image *) NULL); 2164e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy assert(image->signature == MagickCoreSignature); 21654aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy if (image->debug != MagickFalse) 21664aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 21674aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy assert(pixels != (unsigned char *) NULL); 21684aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy packbits=(unsigned char *) AcquireQuantumMemory(128UL,sizeof(*packbits)); 21694aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy if (packbits == (unsigned char *) NULL) 21704aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed", 21714aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy image->filename); 2172b1459bce38004e27d61bef953617d25747264ff4cristy q=compact_pixels; 2173bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (i=(ssize_t) length; i != 0; ) 21744aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy { 21754aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy switch (i) 21764aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy { 21774aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy case 1: 21784aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy { 21794aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy i--; 21804aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy *q++=(unsigned char) 0; 21814aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy *q++=(*pixels); 21824aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy break; 21834aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy } 21844aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy case 2: 21854aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy { 21864aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy i-=2; 21874aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy *q++=(unsigned char) 1; 21884aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy *q++=(*pixels); 21894aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy *q++=pixels[1]; 21904aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy break; 21914aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy } 21924aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy case 3: 21934aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy { 21944aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy i-=3; 21954aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy if ((*pixels == *(pixels+1)) && (*(pixels+1) == *(pixels+2))) 21964aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy { 21974aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy *q++=(unsigned char) ((256-3)+1); 21984aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy *q++=(*pixels); 21994aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy break; 22004aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy } 22014aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy *q++=(unsigned char) 2; 22024aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy *q++=(*pixels); 22034aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy *q++=pixels[1]; 22044aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy *q++=pixels[2]; 22054aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy break; 22064aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy } 22074aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy default: 22084aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy { 22094aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy if ((*pixels == *(pixels+1)) && (*(pixels+1) == *(pixels+2))) 22104aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy { 22114aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy /* 22124aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy Packed run. 22134aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy */ 22144aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy count=3; 2215bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy while (((ssize_t) count < i) && (*pixels == *(pixels+count))) 22164aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy { 22174aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy count++; 22184aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy if (count >= 127) 22194aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy break; 22204aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy } 22214aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy i-=count; 22224aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy *q++=(unsigned char) ((256-count)+1); 22234aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy *q++=(*pixels); 22244aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy pixels+=count; 22254aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy break; 22264aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy } 22274aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy /* 22284aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy Literal run. 22294aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy */ 22304aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy count=0; 22314aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy while ((*(pixels+count) != *(pixels+count+1)) || 22324aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy (*(pixels+count+1) != *(pixels+count+2))) 22334aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy { 22344aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy packbits[count+1]=pixels[count]; 22354aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy count++; 2236bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy if (((ssize_t) count >= (i-3)) || (count >= 127)) 22374aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy break; 22384aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy } 22394aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy i-=count; 22404aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy *packbits=(unsigned char) (count-1); 2241bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (j=0; j <= (ssize_t) count; j++) 22424aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy *q++=packbits[j]; 22434aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy pixels+=count; 22444aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy break; 22454aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy } 22464aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy } 22474aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy } 22484aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy *q++=(unsigned char) 128; /* EOD marker */ 22494aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy packbits=(unsigned char *) RelinquishMagickMemory(packbits); 2250b1459bce38004e27d61bef953617d25747264ff4cristy return((size_t) (q-compact_pixels)); 22514aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy} 22524aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy 2253875e28af6da774727babef3e455b967d02a146f5cristystatic void WritePackbitsLength(const PSDInfo *psd_info, 2254a20214eef4b9c5e1797527b0a6273899a9062f9ccristy const ImageInfo *image_info,Image *image,Image *next_image, 2255018f07f7333b25743d0afff892450cebdb905c1acristy unsigned char *compact_pixels,const QuantumType quantum_type, 2256018f07f7333b25743d0afff892450cebdb905c1acristy ExceptionInfo *exception) 22573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 22583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy QuantumInfo 22593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *quantum_info; 22603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 22614c08aed51c5899665ade97263692328eea4af106cristy register const Quantum 22623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *p; 22633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 22643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy size_t 22654aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy length, 22663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy packet_size; 22673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 226875f85ae6350dcd7d4f771f8fc1b7da27027ac50dcristy ssize_t 226975f85ae6350dcd7d4f771f8fc1b7da27027ac50dcristy y; 227075f85ae6350dcd7d4f771f8fc1b7da27027ac50dcristy 2271a20214eef4b9c5e1797527b0a6273899a9062f9ccristy unsigned char 2272a20214eef4b9c5e1797527b0a6273899a9062f9ccristy *pixels; 2273a20214eef4b9c5e1797527b0a6273899a9062f9ccristy 2274a20214eef4b9c5e1797527b0a6273899a9062f9ccristy if (next_image->depth > 8) 2275a20214eef4b9c5e1797527b0a6273899a9062f9ccristy next_image->depth=16; 2276a20214eef4b9c5e1797527b0a6273899a9062f9ccristy packet_size=next_image->depth > 8UL ? 2UL : 1UL; 2277da16f16767eb31921af855f17bda465fffc4e000cristy (void) packet_size; 22785f766ef8b0cd9906c2c3a56d845828380a251073cristy quantum_info=AcquireQuantumInfo(image_info,image); 2279b3f97ae45019a91b30792a6fa42d81a2689a7025cristy pixels=(unsigned char *) GetQuantumPixels(quantum_info); 2280a20214eef4b9c5e1797527b0a6273899a9062f9ccristy for (y=0; y < (ssize_t) next_image->rows; y++) 22814aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy { 2282c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy p=GetVirtualPixels(next_image,0,y,next_image->columns,1,exception); 22834c08aed51c5899665ade97263692328eea4af106cristy if (p == (const Quantum *) NULL) 22844aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy break; 2285a20214eef4b9c5e1797527b0a6273899a9062f9ccristy length=ExportQuantumPixels(next_image,(CacheView *) NULL,quantum_info, 2286c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy quantum_type,pixels,exception); 2287018f07f7333b25743d0afff892450cebdb905c1acristy length=PSDPackbitsEncodeImage(image,length,pixels,compact_pixels, 2288018f07f7333b25743d0afff892450cebdb905c1acristy exception); 2289875e28af6da774727babef3e455b967d02a146f5cristy (void) SetPSDOffset(psd_info,image,length); 22904aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy } 22914aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy quantum_info=DestroyQuantumInfo(quantum_info); 22924aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy} 22934aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy 2294875e28af6da774727babef3e455b967d02a146f5cristystatic void WriteOneChannel(const PSDInfo *psd_info,const ImageInfo *image_info, 2295a20214eef4b9c5e1797527b0a6273899a9062f9ccristy Image *image,Image *next_image,unsigned char *compact_pixels, 2296018f07f7333b25743d0afff892450cebdb905c1acristy const QuantumType quantum_type,const MagickBooleanType compression_flag, 2297018f07f7333b25743d0afff892450cebdb905c1acristy ExceptionInfo *exception) 22984aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy{ 22994aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy int 23004aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy y; 23014aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy 23020910f24d34e1f8b06dc47ed189a1dde40c6eac83cristy MagickBooleanType 23030910f24d34e1f8b06dc47ed189a1dde40c6eac83cristy monochrome; 23040910f24d34e1f8b06dc47ed189a1dde40c6eac83cristy 23054aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy QuantumInfo 23064aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy *quantum_info; 23074aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy 23084c08aed51c5899665ade97263692328eea4af106cristy register const Quantum 23094aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy *p; 23104aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy 2311bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy register ssize_t 23120910f24d34e1f8b06dc47ed189a1dde40c6eac83cristy i; 23130910f24d34e1f8b06dc47ed189a1dde40c6eac83cristy 23144aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy size_t 23154aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy length, 23164aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy packet_size; 23174aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy 2318a20214eef4b9c5e1797527b0a6273899a9062f9ccristy unsigned char 2319a20214eef4b9c5e1797527b0a6273899a9062f9ccristy *pixels; 2320a20214eef4b9c5e1797527b0a6273899a9062f9ccristy 232150aea4a7536abc82a6877cd256987666d14d54d0cristy (void) psd_info; 23224aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy if ((compression_flag != MagickFalse) && 2323a20214eef4b9c5e1797527b0a6273899a9062f9ccristy (next_image->compression != RLECompression)) 23244aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy (void) WriteBlobMSBShort(image,0); 2325a20214eef4b9c5e1797527b0a6273899a9062f9ccristy if (next_image->depth > 8) 2326a20214eef4b9c5e1797527b0a6273899a9062f9ccristy next_image->depth=16; 2327a7014c80705e61fe66ccd14bfca87bfe9cffe87fdirk monochrome=IsImageMonochrome(image) && (image->depth == 1) ? 2328c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy MagickTrue : MagickFalse; 2329a20214eef4b9c5e1797527b0a6273899a9062f9ccristy packet_size=next_image->depth > 8UL ? 2UL : 1UL; 2330da16f16767eb31921af855f17bda465fffc4e000cristy (void) packet_size; 23315f766ef8b0cd9906c2c3a56d845828380a251073cristy quantum_info=AcquireQuantumInfo(image_info,image); 2332b3f97ae45019a91b30792a6fa42d81a2689a7025cristy pixels=(unsigned char *) GetQuantumPixels(quantum_info); 2333a20214eef4b9c5e1797527b0a6273899a9062f9ccristy for (y=0; y < (ssize_t) next_image->rows; y++) 23343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 2335c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy p=GetVirtualPixels(next_image,0,y,next_image->columns,1,exception); 23364c08aed51c5899665ade97263692328eea4af106cristy if (p == (const Quantum *) NULL) 23374aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy break; 2338a20214eef4b9c5e1797527b0a6273899a9062f9ccristy length=ExportQuantumPixels(next_image,(CacheView *) NULL,quantum_info, 2339c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy quantum_type,pixels,exception); 23400910f24d34e1f8b06dc47ed189a1dde40c6eac83cristy if (monochrome != MagickFalse) 2341bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (i=0; i < (ssize_t) length; i++) 23420910f24d34e1f8b06dc47ed189a1dde40c6eac83cristy pixels[i]=(~pixels[i]); 2343a20214eef4b9c5e1797527b0a6273899a9062f9ccristy if (next_image->compression != RLECompression) 23444aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy (void) WriteBlob(image,length,pixels); 23454aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy else 23464aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy { 2347018f07f7333b25743d0afff892450cebdb905c1acristy length=PSDPackbitsEncodeImage(image,length,pixels,compact_pixels, 2348018f07f7333b25743d0afff892450cebdb905c1acristy exception); 2349b1459bce38004e27d61bef953617d25747264ff4cristy (void) WriteBlob(image,length,compact_pixels); 23504aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy } 23513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 23523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy quantum_info=DestroyQuantumInfo(quantum_info); 23533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 23543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2355875e28af6da774727babef3e455b967d02a146f5cristystatic MagickBooleanType WriteImageChannels(const PSDInfo *psd_info, 2356a20214eef4b9c5e1797527b0a6273899a9062f9ccristy const ImageInfo *image_info,Image *image,Image *next_image, 2357018f07f7333b25743d0afff892450cebdb905c1acristy const MagickBooleanType separate,ExceptionInfo *exception) 23583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 23593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy size_t 23603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy channels, 23613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy packet_size; 23623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 23633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned char 2364a20214eef4b9c5e1797527b0a6273899a9062f9ccristy *compact_pixels; 23653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 23663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 2367875e28af6da774727babef3e455b967d02a146f5cristy Write uncompressed pixels as separate planes. 23683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 23693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy channels=1; 2370a20214eef4b9c5e1797527b0a6273899a9062f9ccristy packet_size=next_image->depth > 8UL ? 2UL : 1UL; 2371a20214eef4b9c5e1797527b0a6273899a9062f9ccristy compact_pixels=(unsigned char *) NULL; 2372a20214eef4b9c5e1797527b0a6273899a9062f9ccristy if (next_image->compression == RLECompression) 23734aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy { 2374533ea3b9047c67f9af49703de672f6c2e443f747Cristy compact_pixels=(unsigned char *) AcquireQuantumMemory((9*channels* 23756f1879d498bcc5cce12fe0c5decb8dbc0f608e5ddirk next_image->columns)+1,packet_size*sizeof(*compact_pixels)); 2376a20214eef4b9c5e1797527b0a6273899a9062f9ccristy if (compact_pixels == (unsigned char *) NULL) 2377a20214eef4b9c5e1797527b0a6273899a9062f9ccristy ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed"); 23784aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy } 2379a7014c80705e61fe66ccd14bfca87bfe9cffe87fdirk if (IsImageGray(next_image) != MagickFalse) 23803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 2381a20214eef4b9c5e1797527b0a6273899a9062f9ccristy if (next_image->compression == RLECompression) 23824aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy { 23834aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy /* 23844aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy Packbits compression. 23854aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy */ 23864aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy (void) WriteBlobMSBShort(image,1); 2387a20214eef4b9c5e1797527b0a6273899a9062f9ccristy WritePackbitsLength(psd_info,image_info,image,next_image, 2388018f07f7333b25743d0afff892450cebdb905c1acristy compact_pixels,GrayQuantum,exception); 238917f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy if (next_image->alpha_trait != UndefinedPixelTrait) 2390a20214eef4b9c5e1797527b0a6273899a9062f9ccristy WritePackbitsLength(psd_info,image_info,image,next_image, 2391018f07f7333b25743d0afff892450cebdb905c1acristy compact_pixels,AlphaQuantum,exception); 23924aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy } 2393a20214eef4b9c5e1797527b0a6273899a9062f9ccristy WriteOneChannel(psd_info,image_info,image,next_image,compact_pixels, 2394c9e9ea32a13414a2574a54089c9b2facb6f8ea13dirk GrayQuantum,MagickTrue,exception); 239517f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy if (next_image->alpha_trait != UndefinedPixelTrait) 2396a20214eef4b9c5e1797527b0a6273899a9062f9ccristy WriteOneChannel(psd_info,image_info,image,next_image,compact_pixels, 2397c9e9ea32a13414a2574a54089c9b2facb6f8ea13dirk AlphaQuantum,separate,exception); 23986886a7561ce8dffd35ccc6803665933f4e66c2d7cristy (void) SetImageProgress(image,SaveImagesTag,0,1); 23990910f24d34e1f8b06dc47ed189a1dde40c6eac83cristy } 24000910f24d34e1f8b06dc47ed189a1dde40c6eac83cristy else 2401a20214eef4b9c5e1797527b0a6273899a9062f9ccristy if (next_image->storage_class == PseudoClass) 24020910f24d34e1f8b06dc47ed189a1dde40c6eac83cristy { 2403a20214eef4b9c5e1797527b0a6273899a9062f9ccristy if (next_image->compression == RLECompression) 24040910f24d34e1f8b06dc47ed189a1dde40c6eac83cristy { 24050910f24d34e1f8b06dc47ed189a1dde40c6eac83cristy /* 24060910f24d34e1f8b06dc47ed189a1dde40c6eac83cristy Packbits compression. 24070910f24d34e1f8b06dc47ed189a1dde40c6eac83cristy */ 24080910f24d34e1f8b06dc47ed189a1dde40c6eac83cristy (void) WriteBlobMSBShort(image,1); 2409a20214eef4b9c5e1797527b0a6273899a9062f9ccristy WritePackbitsLength(psd_info,image_info,image,next_image, 2410018f07f7333b25743d0afff892450cebdb905c1acristy compact_pixels,IndexQuantum,exception); 241117f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy if (next_image->alpha_trait != UndefinedPixelTrait) 2412a20214eef4b9c5e1797527b0a6273899a9062f9ccristy WritePackbitsLength(psd_info,image_info,image,next_image, 2413018f07f7333b25743d0afff892450cebdb905c1acristy compact_pixels,AlphaQuantum,exception); 24140910f24d34e1f8b06dc47ed189a1dde40c6eac83cristy } 2415a20214eef4b9c5e1797527b0a6273899a9062f9ccristy WriteOneChannel(psd_info,image_info,image,next_image,compact_pixels, 2416c9e9ea32a13414a2574a54089c9b2facb6f8ea13dirk IndexQuantum,MagickTrue,exception); 241717f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy if (next_image->alpha_trait != UndefinedPixelTrait) 2418a20214eef4b9c5e1797527b0a6273899a9062f9ccristy WriteOneChannel(psd_info,image_info,image,next_image,compact_pixels, 2419c9e9ea32a13414a2574a54089c9b2facb6f8ea13dirk AlphaQuantum,separate,exception); 24200910f24d34e1f8b06dc47ed189a1dde40c6eac83cristy (void) SetImageProgress(image,SaveImagesTag,0,1); 24210910f24d34e1f8b06dc47ed189a1dde40c6eac83cristy } 24220910f24d34e1f8b06dc47ed189a1dde40c6eac83cristy else 24230910f24d34e1f8b06dc47ed189a1dde40c6eac83cristy { 2424a20214eef4b9c5e1797527b0a6273899a9062f9ccristy if (next_image->colorspace == CMYKColorspace) 2425d9795a19984ae1bae9205b7c0fe5de75461978b3dirk (void) NegateCMYK(next_image,exception); 2426a20214eef4b9c5e1797527b0a6273899a9062f9ccristy if (next_image->compression == RLECompression) 24270910f24d34e1f8b06dc47ed189a1dde40c6eac83cristy { 24280910f24d34e1f8b06dc47ed189a1dde40c6eac83cristy /* 24290910f24d34e1f8b06dc47ed189a1dde40c6eac83cristy Packbits compression. 24300910f24d34e1f8b06dc47ed189a1dde40c6eac83cristy */ 24310910f24d34e1f8b06dc47ed189a1dde40c6eac83cristy (void) WriteBlobMSBShort(image,1); 2432a20214eef4b9c5e1797527b0a6273899a9062f9ccristy WritePackbitsLength(psd_info,image_info,image,next_image, 2433018f07f7333b25743d0afff892450cebdb905c1acristy compact_pixels,RedQuantum,exception); 2434a20214eef4b9c5e1797527b0a6273899a9062f9ccristy WritePackbitsLength(psd_info,image_info,image,next_image, 2435018f07f7333b25743d0afff892450cebdb905c1acristy compact_pixels,GreenQuantum,exception); 2436a20214eef4b9c5e1797527b0a6273899a9062f9ccristy WritePackbitsLength(psd_info,image_info,image,next_image, 2437018f07f7333b25743d0afff892450cebdb905c1acristy compact_pixels,BlueQuantum,exception); 2438a20214eef4b9c5e1797527b0a6273899a9062f9ccristy if (next_image->colorspace == CMYKColorspace) 2439a20214eef4b9c5e1797527b0a6273899a9062f9ccristy WritePackbitsLength(psd_info,image_info,image,next_image, 2440018f07f7333b25743d0afff892450cebdb905c1acristy compact_pixels,BlackQuantum,exception); 244117f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy if (next_image->alpha_trait != UndefinedPixelTrait) 2442a20214eef4b9c5e1797527b0a6273899a9062f9ccristy WritePackbitsLength(psd_info,image_info,image,next_image, 2443018f07f7333b25743d0afff892450cebdb905c1acristy compact_pixels,AlphaQuantum,exception); 24440910f24d34e1f8b06dc47ed189a1dde40c6eac83cristy } 24450910f24d34e1f8b06dc47ed189a1dde40c6eac83cristy (void) SetImageProgress(image,SaveImagesTag,0,6); 2446a20214eef4b9c5e1797527b0a6273899a9062f9ccristy WriteOneChannel(psd_info,image_info,image,next_image,compact_pixels, 2447c9e9ea32a13414a2574a54089c9b2facb6f8ea13dirk RedQuantum,MagickTrue,exception); 2448860cc73bed4db1b0d7e3913dabb8236a50d14e82cristy (void) SetImageProgress(image,SaveImagesTag,1,6); 2449a20214eef4b9c5e1797527b0a6273899a9062f9ccristy WriteOneChannel(psd_info,image_info,image,next_image,compact_pixels, 2450c9e9ea32a13414a2574a54089c9b2facb6f8ea13dirk GreenQuantum,separate,exception); 2451860cc73bed4db1b0d7e3913dabb8236a50d14e82cristy (void) SetImageProgress(image,SaveImagesTag,2,6); 2452a20214eef4b9c5e1797527b0a6273899a9062f9ccristy WriteOneChannel(psd_info,image_info,image,next_image,compact_pixels, 2453c9e9ea32a13414a2574a54089c9b2facb6f8ea13dirk BlueQuantum,separate,exception); 2454860cc73bed4db1b0d7e3913dabb8236a50d14e82cristy (void) SetImageProgress(image,SaveImagesTag,3,6); 2455a20214eef4b9c5e1797527b0a6273899a9062f9ccristy if (next_image->colorspace == CMYKColorspace) 2456a20214eef4b9c5e1797527b0a6273899a9062f9ccristy WriteOneChannel(psd_info,image_info,image,next_image,compact_pixels, 2457c9e9ea32a13414a2574a54089c9b2facb6f8ea13dirk BlackQuantum,separate,exception); 2458860cc73bed4db1b0d7e3913dabb8236a50d14e82cristy (void) SetImageProgress(image,SaveImagesTag,4,6); 245917f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy if (next_image->alpha_trait != UndefinedPixelTrait) 2460a20214eef4b9c5e1797527b0a6273899a9062f9ccristy WriteOneChannel(psd_info,image_info,image,next_image,compact_pixels, 2461c9e9ea32a13414a2574a54089c9b2facb6f8ea13dirk AlphaQuantum,separate,exception); 24620910f24d34e1f8b06dc47ed189a1dde40c6eac83cristy (void) SetImageProgress(image,SaveImagesTag,5,6); 2463a20214eef4b9c5e1797527b0a6273899a9062f9ccristy if (next_image->colorspace == CMYKColorspace) 2464d9795a19984ae1bae9205b7c0fe5de75461978b3dirk (void) NegateCMYK(next_image,exception); 24650910f24d34e1f8b06dc47ed189a1dde40c6eac83cristy } 2466a20214eef4b9c5e1797527b0a6273899a9062f9ccristy if (next_image->compression == RLECompression) 2467a20214eef4b9c5e1797527b0a6273899a9062f9ccristy compact_pixels=(unsigned char *) RelinquishMagickMemory(compact_pixels); 24683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickTrue); 24693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 24703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 24713ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void WritePascalString(Image* inImage,const char *inString,int inPad) 24723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 24733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy size_t 2474a20214eef4b9c5e1797527b0a6273899a9062f9ccristy length; 24753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2476a20214eef4b9c5e1797527b0a6273899a9062f9ccristy register ssize_t 2477a20214eef4b9c5e1797527b0a6273899a9062f9ccristy i; 24783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2479a20214eef4b9c5e1797527b0a6273899a9062f9ccristy /* 2480a20214eef4b9c5e1797527b0a6273899a9062f9ccristy Max length is 255. 2481a20214eef4b9c5e1797527b0a6273899a9062f9ccristy */ 2482a20214eef4b9c5e1797527b0a6273899a9062f9ccristy length=(strlen(inString) > 255UL ) ? 255UL : strlen(inString); 2483a20214eef4b9c5e1797527b0a6273899a9062f9ccristy if (length == 0) 2484a20214eef4b9c5e1797527b0a6273899a9062f9ccristy (void) WriteBlobByte(inImage,0); 24853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 2486a20214eef4b9c5e1797527b0a6273899a9062f9ccristy { 2487a20214eef4b9c5e1797527b0a6273899a9062f9ccristy (void) WriteBlobByte(inImage,(unsigned char) length); 2488a20214eef4b9c5e1797527b0a6273899a9062f9ccristy (void) WriteBlob(inImage, length, (const unsigned char *) inString); 2489a20214eef4b9c5e1797527b0a6273899a9062f9ccristy } 2490a20214eef4b9c5e1797527b0a6273899a9062f9ccristy length++; 2491a20214eef4b9c5e1797527b0a6273899a9062f9ccristy if ((length % inPad) == 0) 24923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return; 2493a20214eef4b9c5e1797527b0a6273899a9062f9ccristy for (i=0; i < (ssize_t) (inPad-(length % inPad)); i++) 24943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(inImage,0); 24953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 24963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 24973ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic void WriteResolutionResourceBlock(Image *image) 24983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 249956ed31cc763800a9fb1f0df96104c354b40d2cbccristy double 250056ed31cc763800a9fb1f0df96104c354b40d2cbccristy x_resolution, 250156ed31cc763800a9fb1f0df96104c354b40d2cbccristy y_resolution; 25023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 25033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unsigned short 25043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy units; 25053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 25063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->units == PixelsPerCentimeterResolution) 25073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 250887dabf6eb2a2d342eb36a734809075fa19cb5778dirk x_resolution=2.54*65536.0*image->resolution.x+0.5; 25092a11befa48257796843468409d77bb8cfb129cdccristy y_resolution=2.54*65536.0*image->resolution.y+0.5; 25103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy units=2; 25113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 251287dabf6eb2a2d342eb36a734809075fa19cb5778dirk else 251387dabf6eb2a2d342eb36a734809075fa19cb5778dirk { 251487dabf6eb2a2d342eb36a734809075fa19cb5778dirk x_resolution=65536.0*image->resolution.x+0.5; 251587dabf6eb2a2d342eb36a734809075fa19cb5778dirk y_resolution=65536.0*image->resolution.y+0.5; 251687dabf6eb2a2d342eb36a734809075fa19cb5778dirk units=1; 251787dabf6eb2a2d342eb36a734809075fa19cb5778dirk } 25183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlob(image,4,(const unsigned char *) "8BIM"); 25193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobMSBShort(image,0x03ED); 25203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobMSBShort(image,0); 25213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobMSBLong(image,16); /* resource size */ 252256ed31cc763800a9fb1f0df96104c354b40d2cbccristy (void) WriteBlobMSBLong(image,(unsigned int) (x_resolution+0.5)); 25233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobMSBShort(image,units); /* horizontal resolution unit */ 25243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobMSBShort(image,units); /* width unit */ 252556ed31cc763800a9fb1f0df96104c354b40d2cbccristy (void) WriteBlobMSBLong(image,(unsigned int) (y_resolution+0.5)); 25263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobMSBShort(image,units); /* vertical resolution unit */ 25273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobMSBShort(image,units); /* height unit */ 25283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 25293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2530d4d3f74b0a58d6fcab96da6e943c4755810db3f5cristystatic void RemoveICCProfileFromResourceBlock(StringInfo *bim_profile) 2531d4d3f74b0a58d6fcab96da6e943c4755810db3f5cristy{ 25320b796e6c8c90cf5ec9e6a295504220d055c9e0a6cristy register const unsigned char 2533d4d3f74b0a58d6fcab96da6e943c4755810db3f5cristy *p; 2534d4d3f74b0a58d6fcab96da6e943c4755810db3f5cristy 2535d4d3f74b0a58d6fcab96da6e943c4755810db3f5cristy size_t 2536d4d3f74b0a58d6fcab96da6e943c4755810db3f5cristy length; 2537d4d3f74b0a58d6fcab96da6e943c4755810db3f5cristy 2538d4d3f74b0a58d6fcab96da6e943c4755810db3f5cristy unsigned char 2539d4d3f74b0a58d6fcab96da6e943c4755810db3f5cristy *datum; 2540d4d3f74b0a58d6fcab96da6e943c4755810db3f5cristy 25416befb0f8f253ef359d1e14d1e569c1a848d02daccristy unsigned int 2542d4d3f74b0a58d6fcab96da6e943c4755810db3f5cristy count, 25436befb0f8f253ef359d1e14d1e569c1a848d02daccristy long_sans; 2544d4d3f74b0a58d6fcab96da6e943c4755810db3f5cristy 2545d4d3f74b0a58d6fcab96da6e943c4755810db3f5cristy unsigned short 2546d4d3f74b0a58d6fcab96da6e943c4755810db3f5cristy id, 2547d4d3f74b0a58d6fcab96da6e943c4755810db3f5cristy short_sans; 2548d4d3f74b0a58d6fcab96da6e943c4755810db3f5cristy 2549d4d3f74b0a58d6fcab96da6e943c4755810db3f5cristy length=GetStringInfoLength(bim_profile); 2550d4d3f74b0a58d6fcab96da6e943c4755810db3f5cristy if (length < 16) 25510b796e6c8c90cf5ec9e6a295504220d055c9e0a6cristy return; 2552d4d3f74b0a58d6fcab96da6e943c4755810db3f5cristy datum=GetStringInfoDatum(bim_profile); 2553d4d3f74b0a58d6fcab96da6e943c4755810db3f5cristy for (p=datum; (p >= datum) && (p < (datum+length-16)); ) 2554d4d3f74b0a58d6fcab96da6e943c4755810db3f5cristy { 25554176bb21071b87cc8a0d0867db402999db941569cristy register unsigned char 25564176bb21071b87cc8a0d0867db402999db941569cristy *q; 25574176bb21071b87cc8a0d0867db402999db941569cristy 25584176bb21071b87cc8a0d0867db402999db941569cristy q=(unsigned char *) p; 2559d4d3f74b0a58d6fcab96da6e943c4755810db3f5cristy if (LocaleNCompare((const char *) p,"8BIM",4) != 0) 2560d4d3f74b0a58d6fcab96da6e943c4755810db3f5cristy break; 25616befb0f8f253ef359d1e14d1e569c1a848d02daccristy p=PushLongPixel(MSBEndian,p,&long_sans); 2562d4d3f74b0a58d6fcab96da6e943c4755810db3f5cristy p=PushShortPixel(MSBEndian,p,&id); 2563d4d3f74b0a58d6fcab96da6e943c4755810db3f5cristy p=PushShortPixel(MSBEndian,p,&short_sans); 2564d4d3f74b0a58d6fcab96da6e943c4755810db3f5cristy p=PushLongPixel(MSBEndian,p,&count); 2565d4d3f74b0a58d6fcab96da6e943c4755810db3f5cristy if (id == 0x0000040f) 2566d4d3f74b0a58d6fcab96da6e943c4755810db3f5cristy { 25674812e816a9c3da93003aaea1d0b1db9ccf8ce40ddirk ssize_t 25684812e816a9c3da93003aaea1d0b1db9ccf8ce40ddirk quantum; 25694812e816a9c3da93003aaea1d0b1db9ccf8ce40ddirk 25704812e816a9c3da93003aaea1d0b1db9ccf8ce40ddirk quantum=PSDQuantum(count)+12; 25714812e816a9c3da93003aaea1d0b1db9ccf8ce40ddirk if ((quantum >= 12) && (q+quantum < (datum+length-16))) 257282e2049862a8b8a999e160734ad64fb6cc3b145fCristy { 25734812e816a9c3da93003aaea1d0b1db9ccf8ce40ddirk (void) CopyMagickMemory(q,q+quantum,length-quantum-(q-datum)); 25744812e816a9c3da93003aaea1d0b1db9ccf8ce40ddirk SetStringInfoLength(bim_profile,length-quantum); 257582e2049862a8b8a999e160734ad64fb6cc3b145fCristy } 2576d4d3f74b0a58d6fcab96da6e943c4755810db3f5cristy break; 2577d4d3f74b0a58d6fcab96da6e943c4755810db3f5cristy } 2578d4d3f74b0a58d6fcab96da6e943c4755810db3f5cristy p+=count; 2579d4d3f74b0a58d6fcab96da6e943c4755810db3f5cristy if ((count & 0x01) != 0) 2580d4d3f74b0a58d6fcab96da6e943c4755810db3f5cristy p++; 2581d4d3f74b0a58d6fcab96da6e943c4755810db3f5cristy } 2582d4d3f74b0a58d6fcab96da6e943c4755810db3f5cristy} 2583d4d3f74b0a58d6fcab96da6e943c4755810db3f5cristy 2584f11065e08c32a2c6a82e67ade789e83936724a8ecristystatic void RemoveResolutionFromResourceBlock(StringInfo *bim_profile) 2585f11065e08c32a2c6a82e67ade789e83936724a8ecristy{ 2586f11065e08c32a2c6a82e67ade789e83936724a8ecristy register const unsigned char 2587f11065e08c32a2c6a82e67ade789e83936724a8ecristy *p; 2588f11065e08c32a2c6a82e67ade789e83936724a8ecristy 2589f11065e08c32a2c6a82e67ade789e83936724a8ecristy size_t 2590f11065e08c32a2c6a82e67ade789e83936724a8ecristy length; 2591f11065e08c32a2c6a82e67ade789e83936724a8ecristy 2592f11065e08c32a2c6a82e67ade789e83936724a8ecristy unsigned char 2593f11065e08c32a2c6a82e67ade789e83936724a8ecristy *datum; 2594f11065e08c32a2c6a82e67ade789e83936724a8ecristy 25956befb0f8f253ef359d1e14d1e569c1a848d02daccristy unsigned int 2596f11065e08c32a2c6a82e67ade789e83936724a8ecristy count, 25976befb0f8f253ef359d1e14d1e569c1a848d02daccristy long_sans; 2598f11065e08c32a2c6a82e67ade789e83936724a8ecristy 2599f11065e08c32a2c6a82e67ade789e83936724a8ecristy unsigned short 2600f11065e08c32a2c6a82e67ade789e83936724a8ecristy id, 2601f11065e08c32a2c6a82e67ade789e83936724a8ecristy short_sans; 2602f11065e08c32a2c6a82e67ade789e83936724a8ecristy 2603f11065e08c32a2c6a82e67ade789e83936724a8ecristy length=GetStringInfoLength(bim_profile); 2604f11065e08c32a2c6a82e67ade789e83936724a8ecristy if (length < 16) 2605f11065e08c32a2c6a82e67ade789e83936724a8ecristy return; 2606f11065e08c32a2c6a82e67ade789e83936724a8ecristy datum=GetStringInfoDatum(bim_profile); 2607f11065e08c32a2c6a82e67ade789e83936724a8ecristy for (p=datum; (p >= datum) && (p < (datum+length-16)); ) 2608f11065e08c32a2c6a82e67ade789e83936724a8ecristy { 2609f11065e08c32a2c6a82e67ade789e83936724a8ecristy register unsigned char 2610f11065e08c32a2c6a82e67ade789e83936724a8ecristy *q; 2611f11065e08c32a2c6a82e67ade789e83936724a8ecristy 26124f2c04ea6673863b87ac7f186cbb0d911f74085cdirk ssize_t 26134f2c04ea6673863b87ac7f186cbb0d911f74085cdirk cnt; 26144f2c04ea6673863b87ac7f186cbb0d911f74085cdirk 2615f11065e08c32a2c6a82e67ade789e83936724a8ecristy q=(unsigned char *) p; 2616f11065e08c32a2c6a82e67ade789e83936724a8ecristy if (LocaleNCompare((const char *) p,"8BIM",4) != 0) 26174f2c04ea6673863b87ac7f186cbb0d911f74085cdirk return; 26186befb0f8f253ef359d1e14d1e569c1a848d02daccristy p=PushLongPixel(MSBEndian,p,&long_sans); 2619f11065e08c32a2c6a82e67ade789e83936724a8ecristy p=PushShortPixel(MSBEndian,p,&id); 2620f11065e08c32a2c6a82e67ade789e83936724a8ecristy p=PushShortPixel(MSBEndian,p,&short_sans); 2621f11065e08c32a2c6a82e67ade789e83936724a8ecristy p=PushLongPixel(MSBEndian,p,&count); 26224f2c04ea6673863b87ac7f186cbb0d911f74085cdirk cnt=PSDQuantum(count); 26234f2c04ea6673863b87ac7f186cbb0d911f74085cdirk if (cnt < 0) 26244f2c04ea6673863b87ac7f186cbb0d911f74085cdirk return; 26254f2c04ea6673863b87ac7f186cbb0d911f74085cdirk if ((id == 0x000003ed) && (cnt < (ssize_t) (length-12))) 2626f11065e08c32a2c6a82e67ade789e83936724a8ecristy { 26274f2c04ea6673863b87ac7f186cbb0d911f74085cdirk (void) CopyMagickMemory(q,q+cnt+12,length-(cnt+12)-(q-datum)); 26284f2c04ea6673863b87ac7f186cbb0d911f74085cdirk SetStringInfoLength(bim_profile,length-(cnt+12)); 2629f11065e08c32a2c6a82e67ade789e83936724a8ecristy break; 2630f11065e08c32a2c6a82e67ade789e83936724a8ecristy } 2631f11065e08c32a2c6a82e67ade789e83936724a8ecristy p+=count; 2632f11065e08c32a2c6a82e67ade789e83936724a8ecristy if ((count & 0x01) != 0) 2633f11065e08c32a2c6a82e67ade789e83936724a8ecristy p++; 2634f11065e08c32a2c6a82e67ade789e83936724a8ecristy } 2635f11065e08c32a2c6a82e67ade789e83936724a8ecristy} 2636f11065e08c32a2c6a82e67ade789e83936724a8ecristy 26374f2c04ea6673863b87ac7f186cbb0d911f74085cdirkstatic MagickBooleanType WritePSDImage(const ImageInfo *image_info, 26384f2c04ea6673863b87ac7f186cbb0d911f74085cdirk Image *image,ExceptionInfo *exception) 26393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 26403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const char 2641a20214eef4b9c5e1797527b0a6273899a9062f9ccristy *property; 26423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 26433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const StringInfo 2644749d215867cacb414d8d675c4fc532cc25b473aecristy *icc_profile; 26453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2646a20214eef4b9c5e1797527b0a6273899a9062f9ccristy Image 2647a20214eef4b9c5e1797527b0a6273899a9062f9ccristy *base_image, 2648a20214eef4b9c5e1797527b0a6273899a9062f9ccristy *next_image; 2649a20214eef4b9c5e1797527b0a6273899a9062f9ccristy 26503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy MagickBooleanType 26513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy status; 26523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2653875e28af6da774727babef3e455b967d02a146f5cristy PSDInfo 2654875e28af6da774727babef3e455b967d02a146f5cristy psd_info; 2655875e28af6da774727babef3e455b967d02a146f5cristy 2656bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy register ssize_t 26573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy i; 26583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 26593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy size_t 2660a20214eef4b9c5e1797527b0a6273899a9062f9ccristy channel_size, 2661a20214eef4b9c5e1797527b0a6273899a9062f9ccristy channelLength, 2662a20214eef4b9c5e1797527b0a6273899a9062f9ccristy layer_count, 2663a20214eef4b9c5e1797527b0a6273899a9062f9ccristy layer_info_size, 2664749d215867cacb414d8d675c4fc532cc25b473aecristy length, 26653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy num_channels, 2666a20214eef4b9c5e1797527b0a6273899a9062f9ccristy packet_size, 2667a20214eef4b9c5e1797527b0a6273899a9062f9ccristy rounded_layer_info_size; 26683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 26690b796e6c8c90cf5ec9e6a295504220d055c9e0a6cristy StringInfo 26700b796e6c8c90cf5ec9e6a295504220d055c9e0a6cristy *bim_profile; 26710b796e6c8c90cf5ec9e6a295504220d055c9e0a6cristy 26723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 267356ed31cc763800a9fb1f0df96104c354b40d2cbccristy Open image file. 26743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 26753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image_info != (const ImageInfo *) NULL); 2676e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy assert(image_info->signature == MagickCoreSignature); 26773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image != (Image *) NULL); 2678e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy assert(image->signature == MagickCoreSignature); 26793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->debug != MagickFalse) 26803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 26813a37efd7ece979e9c63dc8f2f2d3816bab8b1156cristy assert(exception != (ExceptionInfo *) NULL); 2682e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy assert(exception->signature == MagickCoreSignature); 26833a37efd7ece979e9c63dc8f2f2d3816bab8b1156cristy status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception); 26843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (status == MagickFalse) 26853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(status); 26863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy packet_size=(size_t) (image->depth > 8 ? 6 : 3); 268717f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy if (image->alpha_trait != UndefinedPixelTrait) 26883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy packet_size+=image->depth > 8 ? 2 : 1; 2689875e28af6da774727babef3e455b967d02a146f5cristy psd_info.version=1; 2690875e28af6da774727babef3e455b967d02a146f5cristy if ((LocaleCompare(image_info->magick,"PSB") == 0) || 2691875e28af6da774727babef3e455b967d02a146f5cristy (image->columns > 30000) || (image->rows > 30000)) 2692875e28af6da774727babef3e455b967d02a146f5cristy psd_info.version=2; 269350aea4a7536abc82a6877cd256987666d14d54d0cristy (void) WriteBlob(image,4,(const unsigned char *) "8BPS"); 2694875e28af6da774727babef3e455b967d02a146f5cristy (void) WriteBlobMSBShort(image,psd_info.version); /* version */ 2695875e28af6da774727babef3e455b967d02a146f5cristy for (i=1; i <= 6; i++) 2696875e28af6da774727babef3e455b967d02a146f5cristy (void) WriteBlobByte(image, 0); /* 6 bytes of reserved */ 2697f4be669d7182ed9b584a71897c0e05e98fe074d0dirk if (SetImageGray(image,exception) != MagickFalse) 269817f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy num_channels=(image->alpha_trait != UndefinedPixelTrait ? 2UL : 1UL); 26993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 2700e1f8f29cea243595203167f070a0f1a193e45c67dirk if ((image_info->type != TrueColorType) && (image_info->type != 2701e1f8f29cea243595203167f070a0f1a193e45c67dirk TrueColorAlphaType) && (image->storage_class == PseudoClass)) 270217f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy num_channels=(image->alpha_trait != UndefinedPixelTrait ? 2UL : 1UL); 27030910f24d34e1f8b06dc47ed189a1dde40c6eac83cristy else 27040910f24d34e1f8b06dc47ed189a1dde40c6eac83cristy { 2705e1f8f29cea243595203167f070a0f1a193e45c67dirk if (image->storage_class == PseudoClass) 2706e1f8f29cea243595203167f070a0f1a193e45c67dirk (void) SetImageStorageClass(image,DirectClass,exception); 27070910f24d34e1f8b06dc47ed189a1dde40c6eac83cristy if (image->colorspace != CMYKColorspace) 270817f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy num_channels=(image->alpha_trait != UndefinedPixelTrait ? 4UL : 3UL); 27090910f24d34e1f8b06dc47ed189a1dde40c6eac83cristy else 271017f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy num_channels=(image->alpha_trait != UndefinedPixelTrait ? 5UL : 4UL); 27110910f24d34e1f8b06dc47ed189a1dde40c6eac83cristy } 27123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobMSBShort(image,(unsigned short) num_channels); 271356ed31cc763800a9fb1f0df96104c354b40d2cbccristy (void) WriteBlobMSBLong(image,(unsigned int) image->rows); 271456ed31cc763800a9fb1f0df96104c354b40d2cbccristy (void) WriteBlobMSBLong(image,(unsigned int) image->columns); 2715a7014c80705e61fe66ccd14bfca87bfe9cffe87fdirk if (IsImageGray(image) != MagickFalse) 27163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 27172045da39100ca0b2ebba13a936c20cad331109a2cristy MagickBooleanType 27182045da39100ca0b2ebba13a936c20cad331109a2cristy monochrome; 27192045da39100ca0b2ebba13a936c20cad331109a2cristy 27200910f24d34e1f8b06dc47ed189a1dde40c6eac83cristy /* 27210910f24d34e1f8b06dc47ed189a1dde40c6eac83cristy Write depth & mode. 27220910f24d34e1f8b06dc47ed189a1dde40c6eac83cristy */ 2723a7014c80705e61fe66ccd14bfca87bfe9cffe87fdirk monochrome=IsImageMonochrome(image) && (image->depth == 1) ? 27243a37efd7ece979e9c63dc8f2f2d3816bab8b1156cristy MagickTrue : MagickFalse; 2725284c7d8f94022fc8106d28e9659bd4e4ff2154ffcristy (void) WriteBlobMSBShort(image,(unsigned short) 2726284c7d8f94022fc8106d28e9659bd4e4ff2154ffcristy (monochrome != MagickFalse ? 1 : image->depth > 8 ? 16 : 8)); 27272b9582a27910c7baaeb04b7e969638328fa70095cristy (void) WriteBlobMSBShort(image,(unsigned short) 27282b9582a27910c7baaeb04b7e969638328fa70095cristy (monochrome != MagickFalse ? BitmapMode : GrayscaleMode)); 27293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 27303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 27313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 2732a20214eef4b9c5e1797527b0a6273899a9062f9ccristy (void) WriteBlobMSBShort(image,(unsigned short) (image->storage_class == 2733a20214eef4b9c5e1797527b0a6273899a9062f9ccristy PseudoClass ? 8 : image->depth > 8 ? 16 : 8)); 273487dabf6eb2a2d342eb36a734809075fa19cb5778dirk 27354884539133c16f7f3eba25e60eea5c92d4cecbdacristy if (((image_info->colorspace != UndefinedColorspace) || 27360910f24d34e1f8b06dc47ed189a1dde40c6eac83cristy (image->colorspace != CMYKColorspace)) && 27374884539133c16f7f3eba25e60eea5c92d4cecbdacristy (image_info->colorspace != CMYKColorspace)) 27380910f24d34e1f8b06dc47ed189a1dde40c6eac83cristy { 2739af8d391906d11f0a1f2bbf4e2adbc4995c852d33cristy (void) TransformImageColorspace(image,sRGBColorspace,exception); 27400910f24d34e1f8b06dc47ed189a1dde40c6eac83cristy (void) WriteBlobMSBShort(image,(unsigned short) 27412045da39100ca0b2ebba13a936c20cad331109a2cristy (image->storage_class == PseudoClass ? IndexedMode : RGBMode)); 27420910f24d34e1f8b06dc47ed189a1dde40c6eac83cristy } 27430910f24d34e1f8b06dc47ed189a1dde40c6eac83cristy else 27440910f24d34e1f8b06dc47ed189a1dde40c6eac83cristy { 27454884539133c16f7f3eba25e60eea5c92d4cecbdacristy if (image->colorspace != CMYKColorspace) 2746e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy (void) TransformImageColorspace(image,CMYKColorspace,exception); 27472045da39100ca0b2ebba13a936c20cad331109a2cristy (void) WriteBlobMSBShort(image,CMYKMode); 27480910f24d34e1f8b06dc47ed189a1dde40c6eac83cristy } 27493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 2750a7014c80705e61fe66ccd14bfca87bfe9cffe87fdirk if ((IsImageGray(image) != MagickFalse) || 2751ca9ddb09fab00b5f9769a42eba261eca7974f2abcristy (image->storage_class == DirectClass) || (image->colors > 256)) 27523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobMSBLong(image,0); 27533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 27543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 27553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 27563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Write PSD raster colormap. 27573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 27583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobMSBLong(image,768); 2759bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (i=0; i < (ssize_t) image->colors; i++) 27603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,ScaleQuantumToChar(image->colormap[i].red)); 27613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for ( ; i < 256; i++) 27623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,0); 2763bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (i=0; i < (ssize_t) image->colors; i++) 2764a20214eef4b9c5e1797527b0a6273899a9062f9ccristy (void) WriteBlobByte(image,ScaleQuantumToChar( 2765a20214eef4b9c5e1797527b0a6273899a9062f9ccristy image->colormap[i].green)); 27663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for ( ; i < 256; i++) 27673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,0); 2768bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (i=0; i < (ssize_t) image->colors; i++) 27693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,ScaleQuantumToChar(image->colormap[i].blue)); 27703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for ( ; i < 256; i++) 27713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) WriteBlobByte(image,0); 27723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 27733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 27743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Image resource block. 27753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 2776749d215867cacb414d8d675c4fc532cc25b473aecristy length=28; /* 0x03EB */ 27770b796e6c8c90cf5ec9e6a295504220d055c9e0a6cristy bim_profile=(StringInfo *) GetImageProfile(image,"8bim"); 2778749d215867cacb414d8d675c4fc532cc25b473aecristy icc_profile=GetImageProfile(image,"icc"); 2779d4d3f74b0a58d6fcab96da6e943c4755810db3f5cristy if (bim_profile != (StringInfo *) NULL) 2780416dbd5933171784acf1f262219d9fdc5bae2342cristy { 27810b796e6c8c90cf5ec9e6a295504220d055c9e0a6cristy bim_profile=CloneStringInfo(bim_profile); 2782d4d3f74b0a58d6fcab96da6e943c4755810db3f5cristy if (icc_profile != (StringInfo *) NULL) 2783d4d3f74b0a58d6fcab96da6e943c4755810db3f5cristy RemoveICCProfileFromResourceBlock(bim_profile); 2784f11065e08c32a2c6a82e67ade789e83936724a8ecristy RemoveResolutionFromResourceBlock(bim_profile); 2785d4d3f74b0a58d6fcab96da6e943c4755810db3f5cristy length+=PSDQuantum(GetStringInfoLength(bim_profile)); 2786416dbd5933171784acf1f262219d9fdc5bae2342cristy } 27870b796e6c8c90cf5ec9e6a295504220d055c9e0a6cristy if (icc_profile != (const StringInfo *) NULL) 2788d4d3f74b0a58d6fcab96da6e943c4755810db3f5cristy length+=PSDQuantum(GetStringInfoLength(icc_profile))+12; 2789284c7d8f94022fc8106d28e9659bd4e4ff2154ffcristy (void) WriteBlobMSBLong(image,(unsigned int) length); 2790f11065e08c32a2c6a82e67ade789e83936724a8ecristy WriteResolutionResourceBlock(image); 27914176bb21071b87cc8a0d0867db402999db941569cristy if (bim_profile != (StringInfo *) NULL) 27924176bb21071b87cc8a0d0867db402999db941569cristy { 27934176bb21071b87cc8a0d0867db402999db941569cristy (void) WriteBlob(image,GetStringInfoLength(bim_profile), 27944176bb21071b87cc8a0d0867db402999db941569cristy GetStringInfoDatum(bim_profile)); 27954176bb21071b87cc8a0d0867db402999db941569cristy bim_profile=DestroyStringInfo(bim_profile); 27964176bb21071b87cc8a0d0867db402999db941569cristy } 2797749d215867cacb414d8d675c4fc532cc25b473aecristy if (icc_profile != (StringInfo *) NULL) 2798e636559dfadfdb115cc93f223315052a1ee89238cristy { 2799749d215867cacb414d8d675c4fc532cc25b473aecristy (void) WriteBlob(image,4,(const unsigned char *) "8BIM"); 28004176bb21071b87cc8a0d0867db402999db941569cristy (void) WriteBlobMSBShort(image,0x0000040F); 2801749d215867cacb414d8d675c4fc532cc25b473aecristy (void) WriteBlobMSBShort(image,0); 2802284c7d8f94022fc8106d28e9659bd4e4ff2154ffcristy (void) WriteBlobMSBLong(image,(unsigned int) GetStringInfoLength( 2803284c7d8f94022fc8106d28e9659bd4e4ff2154ffcristy icc_profile)); 2804749d215867cacb414d8d675c4fc532cc25b473aecristy (void) WriteBlob(image,GetStringInfoLength(icc_profile), 2805749d215867cacb414d8d675c4fc532cc25b473aecristy GetStringInfoDatum(icc_profile)); 2806e195f269ded3cc73598398d43649ad5adca19e44cristy if ((MagickOffsetType) GetStringInfoLength(icc_profile) != 28072045da39100ca0b2ebba13a936c20cad331109a2cristy PSDQuantum(GetStringInfoLength(icc_profile))) 2808749d215867cacb414d8d675c4fc532cc25b473aecristy (void) WriteBlobByte(image,0); 2809e636559dfadfdb115cc93f223315052a1ee89238cristy } 28104884539133c16f7f3eba25e60eea5c92d4cecbdacristy layer_count=0; 28114884539133c16f7f3eba25e60eea5c92d4cecbdacristy layer_info_size=2; 28122837bcc0d895233e6d0034f88c5e86c15564bd1acristy base_image=GetNextImageInList(image); 2813332ee36cfe05c954c18d72184dc690a57b0c9c8bdirk if (base_image == (Image *) NULL) 28142837bcc0d895233e6d0034f88c5e86c15564bd1acristy base_image=image; 2815a20214eef4b9c5e1797527b0a6273899a9062f9ccristy next_image=base_image; 2816332ee36cfe05c954c18d72184dc690a57b0c9c8bdirk while (next_image != (Image *) NULL) 2817a20214eef4b9c5e1797527b0a6273899a9062f9ccristy { 2818a20214eef4b9c5e1797527b0a6273899a9062f9ccristy packet_size=next_image->depth > 8 ? 2UL : 1UL; 2819a7014c80705e61fe66ccd14bfca87bfe9cffe87fdirk if (IsImageGray(next_image) != MagickFalse) 282017f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy num_channels=next_image->alpha_trait != UndefinedPixelTrait ? 2UL : 1UL; 28213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 2822a20214eef4b9c5e1797527b0a6273899a9062f9ccristy if (next_image->storage_class == PseudoClass) 282317f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy num_channels=next_image->alpha_trait != UndefinedPixelTrait ? 2UL : 1UL; 28242045da39100ca0b2ebba13a936c20cad331109a2cristy else 2825a20214eef4b9c5e1797527b0a6273899a9062f9ccristy if (next_image->colorspace != CMYKColorspace) 282617f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy num_channels=next_image->alpha_trait != UndefinedPixelTrait ? 4UL : 3UL; 28272045da39100ca0b2ebba13a936c20cad331109a2cristy else 282817f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy num_channels=next_image->alpha_trait != UndefinedPixelTrait ? 5UL : 4UL; 2829a20214eef4b9c5e1797527b0a6273899a9062f9ccristy channelLength=(size_t) (next_image->columns*next_image->rows*packet_size+2); 28304884539133c16f7f3eba25e60eea5c92d4cecbdacristy layer_info_size+=(size_t) (4*4+2+num_channels*6+(psd_info.version == 1 ? 8 : 28314884539133c16f7f3eba25e60eea5c92d4cecbdacristy 16)+4*1+4+num_channels*channelLength); 2832d15e65928aec551b7388c2863de3e3e628e2e0ddcristy property=(const char *) GetImageProperty(next_image,"label",exception); 2833a20214eef4b9c5e1797527b0a6273899a9062f9ccristy if (property == (const char *) NULL) 2834a20214eef4b9c5e1797527b0a6273899a9062f9ccristy layer_info_size+=16; 2835de9b8f5fafbde437b76e3cc037ae5ad481b01906cristy else 2836de9b8f5fafbde437b76e3cc037ae5ad481b01906cristy { 2837a20214eef4b9c5e1797527b0a6273899a9062f9ccristy size_t 2838c93932ae0fce511e693d0cf9b969af16a3e50175dirk layer_length; 2839a20214eef4b9c5e1797527b0a6273899a9062f9ccristy 2840c93932ae0fce511e693d0cf9b969af16a3e50175dirk layer_length=strlen(property); 2841c93932ae0fce511e693d0cf9b969af16a3e50175dirk layer_info_size+=8+layer_length+(4-(layer_length % 4)); 2842de9b8f5fafbde437b76e3cc037ae5ad481b01906cristy } 28434aff1576adab1eae438d2d5b3ac2dde8418ccba8cristy layer_count++; 2844a20214eef4b9c5e1797527b0a6273899a9062f9ccristy next_image=GetNextImageInList(next_image); 28453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 2846144f1b6af9d28fe66ee98ffd9fd1233bd55a45dacristy if (layer_count == 0) 2847875e28af6da774727babef3e455b967d02a146f5cristy (void) SetPSDSize(&psd_info,image,0); 28483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 2849a20214eef4b9c5e1797527b0a6273899a9062f9ccristy { 28508e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy CompressionType 28518e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy compression; 28528e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy 28538e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy (void) SetPSDSize(&psd_info,image,layer_info_size+ 28548e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy (psd_info.version == 1 ? 8 : 16)); 28558e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy if ((layer_info_size/2) != ((layer_info_size+1)/2)) 28568e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy rounded_layer_info_size=layer_info_size+1; 28578e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy else 28588e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy rounded_layer_info_size=layer_info_size; 28598e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy (void) SetPSDSize(&psd_info,image,rounded_layer_info_size); 28601730317bbf49f1aea1dea206578f9f319ad98f8edirk if (image->alpha_trait != UndefinedPixelTrait) 28618fb7ed503852cf10e782ef6b8bf24436ca83e3bbdirk (void) WriteBlobMSBShort(image,-(unsigned short) layer_count); 28628fb7ed503852cf10e782ef6b8bf24436ca83e3bbdirk else 28638fb7ed503852cf10e782ef6b8bf24436ca83e3bbdirk (void) WriteBlobMSBShort(image,(unsigned short) layer_count); 28648e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy layer_count=1; 28658e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy compression=base_image->compression; 2866f2a82ee6e25411cb280db708ff26ab55cece1945cristy for (next_image=base_image; next_image != NULL; ) 28678e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy { 28688e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy next_image->compression=NoCompression; 2869a4e5f47ec63e62952af27cc1f0d4ece75e2db3a6cristy (void) WriteBlobMSBLong(image,(unsigned int) next_image->page.y); 2870a4e5f47ec63e62952af27cc1f0d4ece75e2db3a6cristy (void) WriteBlobMSBLong(image,(unsigned int) next_image->page.x); 28710e274112f2ad0a61de63adfc11e3e78038d55231cristy (void) WriteBlobMSBLong(image,(unsigned int) (next_image->page.y+ 28720e274112f2ad0a61de63adfc11e3e78038d55231cristy next_image->rows)); 28730e274112f2ad0a61de63adfc11e3e78038d55231cristy (void) WriteBlobMSBLong(image,(unsigned int) (next_image->page.x+ 28740e274112f2ad0a61de63adfc11e3e78038d55231cristy next_image->columns)); 28758e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy packet_size=next_image->depth > 8 ? 2UL : 1UL; 28768e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy channel_size=(unsigned int) ((packet_size*next_image->rows* 28778e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy next_image->columns)+2); 2878a7014c80705e61fe66ccd14bfca87bfe9cffe87fdirk if ((IsImageGray(next_image) != MagickFalse) || 28798e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy (next_image->storage_class == PseudoClass)) 28808e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy { 2881a20214eef4b9c5e1797527b0a6273899a9062f9ccristy (void) WriteBlobMSBShort(image,(unsigned short) 288217f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy (next_image->alpha_trait != UndefinedPixelTrait ? 2 : 1)); 2883a20214eef4b9c5e1797527b0a6273899a9062f9ccristy (void) WriteBlobMSBShort(image,0); 2884a20214eef4b9c5e1797527b0a6273899a9062f9ccristy (void) SetPSDSize(&psd_info,image,channel_size); 288517f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy if (next_image->alpha_trait != UndefinedPixelTrait) 2886a20214eef4b9c5e1797527b0a6273899a9062f9ccristy { 2887a20214eef4b9c5e1797527b0a6273899a9062f9ccristy (void) WriteBlobMSBShort(image,(unsigned short) -1); 2888a20214eef4b9c5e1797527b0a6273899a9062f9ccristy (void) SetPSDSize(&psd_info,image,channel_size); 2889a20214eef4b9c5e1797527b0a6273899a9062f9ccristy } 2890a20214eef4b9c5e1797527b0a6273899a9062f9ccristy } 28918e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy else 28928e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy if (next_image->colorspace != CMYKColorspace) 28938e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy { 28948e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy (void) WriteBlobMSBShort(image,(unsigned short) 289517f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy (next_image->alpha_trait != UndefinedPixelTrait ? 4 : 3)); 28968e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy (void) WriteBlobMSBShort(image,0); 28978e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy (void) SetPSDSize(&psd_info,image,channel_size); 28988e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy (void) WriteBlobMSBShort(image,1); 28998e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy (void) SetPSDSize(&psd_info,image,channel_size); 29008e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy (void) WriteBlobMSBShort(image,2); 29018e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy (void) SetPSDSize(&psd_info,image,channel_size); 290217f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy if (next_image->alpha_trait != UndefinedPixelTrait) 29038e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy { 29048e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy (void) WriteBlobMSBShort(image,(unsigned short) -1); 29058e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy (void) SetPSDSize(&psd_info,image,channel_size); 29068e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy } 29078e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy } 29088e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy else 29098e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy { 29108e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy (void) WriteBlobMSBShort(image,(unsigned short) 29118a46d827a124555f0c48fb2368ec1bba8e079ab6cristy (next_image->alpha_trait ? 5 : 4)); 29128e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy (void) WriteBlobMSBShort(image,0); 29138e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy (void) SetPSDSize(&psd_info,image,channel_size); 29148e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy (void) WriteBlobMSBShort(image,1); 29158e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy (void) SetPSDSize(&psd_info,image,channel_size); 29168e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy (void) WriteBlobMSBShort(image,2); 29178e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy (void) SetPSDSize(&psd_info,image,channel_size); 29188e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy (void) WriteBlobMSBShort(image,3); 29198e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy (void) SetPSDSize(&psd_info,image,channel_size); 29208a46d827a124555f0c48fb2368ec1bba8e079ab6cristy if (next_image->alpha_trait) 29218e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy { 29228e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy (void) WriteBlobMSBShort(image,(unsigned short) -1); 29238e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy (void) SetPSDSize(&psd_info,image,channel_size); 29248e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy } 29258e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy } 29268e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy (void) WriteBlob(image,4,(const unsigned char *) "8BIM"); 29278e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy (void) WriteBlob(image,4,(const unsigned char *) 29288e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy CompositeOperatorToPSDBlendMode(next_image->compose)); 29298e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy (void) WriteBlobByte(image,255); /* layer opacity */ 29308e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy (void) WriteBlobByte(image,0); 293148febd6e7503d789df337420cf150dfbb49726b5dirk (void) WriteBlobByte(image,next_image->compose==NoCompositeOp ? 293248febd6e7503d789df337420cf150dfbb49726b5dirk 1 << 0x02 : 1); /* layer properties - visible, etc. */ 29338e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy (void) WriteBlobByte(image,0); 2934d15e65928aec551b7388c2863de3e3e628e2e0ddcristy property=(const char *) GetImageProperty(next_image,"label",exception); 29358e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy if (property == (const char *) NULL) 29368e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy { 293793b02b797c4127ce2b06dbd3b2d75ecc33fca759dirk char 2938151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy layer_name[MagickPathExtent]; 29397a1ce136b85a452a6c38798bd7ece426eb48f2f9cristy 29408e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy (void) WriteBlobMSBLong(image,16); 29418e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy (void) WriteBlobMSBLong(image,0); 29428e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy (void) WriteBlobMSBLong(image,0); 2943151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy (void) FormatLocaleString(layer_name,MagickPathExtent,"L%04ld",(long) 29447a1ce136b85a452a6c38798bd7ece426eb48f2f9cristy layer_count++); 29457a1ce136b85a452a6c38798bd7ece426eb48f2f9cristy WritePascalString(image,layer_name,4); 29468e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy } 29478e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy else 29488e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy { 29498e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy size_t 2950c93932ae0fce511e693d0cf9b969af16a3e50175dirk label_length; 29518e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy 2952c93932ae0fce511e693d0cf9b969af16a3e50175dirk label_length=strlen(property); 2953c93932ae0fce511e693d0cf9b969af16a3e50175dirk (void) WriteBlobMSBLong(image,(unsigned int) (label_length+(4- 2954c93932ae0fce511e693d0cf9b969af16a3e50175dirk (label_length % 4))+8)); 29558e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy (void) WriteBlobMSBLong(image,0); 29568e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy (void) WriteBlobMSBLong(image,0); 29578e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy WritePascalString(image,property,4); 29588e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy } 29598e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy next_image=GetNextImageInList(next_image); 29608e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy } 29618e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy /* 29628e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy Now the image data! 29638e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy */ 29648e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy next_image=base_image; 29658e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy while (next_image != NULL) 29668e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy { 29678e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy status=WriteImageChannels(&psd_info,image_info,image,next_image, 2968018f07f7333b25743d0afff892450cebdb905c1acristy MagickTrue,exception); 29698e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy next_image=GetNextImageInList(next_image); 29708e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy } 29718e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy (void) WriteBlobMSBLong(image,0); /* user mask data */ 29728e9bd3e0de0cb1d12ed15b95b74bd616d3721eefcristy base_image->compression=compression; 2973144f1b6af9d28fe66ee98ffd9fd1233bd55a45dacristy } 2974144f1b6af9d28fe66ee98ffd9fd1233bd55a45dacristy /* 2975144f1b6af9d28fe66ee98ffd9fd1233bd55a45dacristy Write composite image. 2976144f1b6af9d28fe66ee98ffd9fd1233bd55a45dacristy */ 2977f308152b28249d599fa01dd41b1518c4ddfc5e60dirk if (status != MagickFalse) 2978f308152b28249d599fa01dd41b1518c4ddfc5e60dirk status=WriteImageChannels(&psd_info,image_info,image,image,MagickFalse, 2979f308152b28249d599fa01dd41b1518c4ddfc5e60dirk exception); 29803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) CloseBlob(image); 29813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(status); 29823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 2983