cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 1 | /* |
| 2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 3 | % % |
| 4 | % % |
| 5 | % % |
| 6 | % X X PPPP SSSSS % |
| 7 | % X X P P SS % |
| 8 | % X PPPP SSS % |
| 9 | % X X P SS % |
| 10 | % X X P SSSSS % |
| 11 | % % |
| 12 | % % |
| 13 | % Read/Write Microsoft XML Paper Specification Format % |
| 14 | % % |
| 15 | % Software Design % |
cristy | de984cd | 2013-12-01 14:49:27 +0000 | [diff] [blame] | 16 | % Cristy % |
Cristy | c60d328 | 2020-07-26 09:55:35 -0400 | [diff] [blame] | 17 | % January 2008 % |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 18 | % % |
| 19 | % % |
Cristy | d842011 | 2021-01-01 14:52:00 -0500 | [diff] [blame] | 20 | % Copyright 1999-2021 ImageMagick Studio LLC, a non-profit organization % |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 21 | % dedicated to making software imaging solutions freely available. % |
| 22 | % % |
| 23 | % You may not use this file except in compliance with the License. You may % |
| 24 | % obtain a copy of the License at % |
| 25 | % % |
Cristy | 83d74de | 2018-10-13 10:17:25 -0400 | [diff] [blame] | 26 | % https://imagemagick.org/script/license.php % |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 27 | % % |
| 28 | % Unless required by applicable law or agreed to in writing, software % |
| 29 | % distributed under the License is distributed on an "AS IS" BASIS, % |
| 30 | % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % |
| 31 | % See the License for the specific language governing permissions and % |
| 32 | % limitations under the License. % |
| 33 | % % |
| 34 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 35 | % |
| 36 | % |
| 37 | */ |
| 38 | |
| 39 | /* |
| 40 | Include declarations. |
| 41 | */ |
cristy | 4c08aed | 2011-07-01 19:47:50 +0000 | [diff] [blame] | 42 | #include "MagickCore/studio.h" |
cristy | c634861 | 2013-04-05 14:24:24 +0000 | [diff] [blame] | 43 | #include "MagickCore/artifact.h" |
Cristy | c60d328 | 2020-07-26 09:55:35 -0400 | [diff] [blame] | 44 | #include "MagickCore/attribute.h" |
cristy | 4c08aed | 2011-07-01 19:47:50 +0000 | [diff] [blame] | 45 | #include "MagickCore/blob.h" |
| 46 | #include "MagickCore/blob-private.h" |
Cristy | c60d328 | 2020-07-26 09:55:35 -0400 | [diff] [blame] | 47 | #include "MagickCore/cache.h" |
cristy | 4c08aed | 2011-07-01 19:47:50 +0000 | [diff] [blame] | 48 | #include "MagickCore/color.h" |
| 49 | #include "MagickCore/color-private.h" |
| 50 | #include "MagickCore/colorspace.h" |
Cristy | c60d328 | 2020-07-26 09:55:35 -0400 | [diff] [blame] | 51 | #include "MagickCore/colorspace-private.h" |
cristy | 4c08aed | 2011-07-01 19:47:50 +0000 | [diff] [blame] | 52 | #include "MagickCore/constitute.h" |
| 53 | #include "MagickCore/delegate.h" |
Cristy | c60d328 | 2020-07-26 09:55:35 -0400 | [diff] [blame] | 54 | #include "MagickCore/delegate-private.h" |
cristy | 4c08aed | 2011-07-01 19:47:50 +0000 | [diff] [blame] | 55 | #include "MagickCore/draw.h" |
| 56 | #include "MagickCore/exception.h" |
| 57 | #include "MagickCore/exception-private.h" |
| 58 | #include "MagickCore/geometry.h" |
| 59 | #include "MagickCore/image.h" |
| 60 | #include "MagickCore/image-private.h" |
| 61 | #include "MagickCore/list.h" |
| 62 | #include "MagickCore/magick.h" |
| 63 | #include "MagickCore/memory_.h" |
Cristy | c60d328 | 2020-07-26 09:55:35 -0400 | [diff] [blame] | 64 | #include "MagickCore/module.h" |
cristy | 4c08aed | 2011-07-01 19:47:50 +0000 | [diff] [blame] | 65 | #include "MagickCore/monitor.h" |
| 66 | #include "MagickCore/monitor-private.h" |
Cristy | c60d328 | 2020-07-26 09:55:35 -0400 | [diff] [blame] | 67 | #include "MagickCore/nt-base-private.h" |
cristy | c689f1f | 2011-10-05 21:13:24 +0000 | [diff] [blame] | 68 | #include "MagickCore/option.h" |
cristy | 4c08aed | 2011-07-01 19:47:50 +0000 | [diff] [blame] | 69 | #include "MagickCore/profile.h" |
| 70 | #include "MagickCore/resource_.h" |
Cristy | c60d328 | 2020-07-26 09:55:35 -0400 | [diff] [blame] | 71 | #include "MagickCore/pixel-accessor.h" |
| 72 | #include "MagickCore/property.h" |
cristy | 4c08aed | 2011-07-01 19:47:50 +0000 | [diff] [blame] | 73 | #include "MagickCore/quantum-private.h" |
| 74 | #include "MagickCore/static.h" |
| 75 | #include "MagickCore/string_.h" |
Cristy | c60d328 | 2020-07-26 09:55:35 -0400 | [diff] [blame] | 76 | #include "MagickCore/string-private.h" |
| 77 | #include "MagickCore/timer-private.h" |
cristy | 4c08aed | 2011-07-01 19:47:50 +0000 | [diff] [blame] | 78 | #include "MagickCore/token.h" |
| 79 | #include "MagickCore/transform.h" |
| 80 | #include "MagickCore/utility.h" |
Cristy | c60d328 | 2020-07-26 09:55:35 -0400 | [diff] [blame] | 81 | #include "coders/bytebuffer-private.h" |
| 82 | #include "coders/ghostscript-private.h" |
| 83 | |
| 84 | /* |
| 85 | Typedef declaractions. |
| 86 | */ |
| 87 | typedef struct _XPSInfo |
| 88 | { |
| 89 | MagickBooleanType |
| 90 | cmyk; |
| 91 | |
| 92 | SegmentInfo |
| 93 | bounds; |
| 94 | |
| 95 | unsigned long |
| 96 | columns, |
| 97 | rows; |
| 98 | |
| 99 | StringInfo |
| 100 | *icc_profile, |
| 101 | *photoshop_profile, |
| 102 | *xmp_profile; |
| 103 | } XPSInfo; |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 104 | |
| 105 | /* |
| 106 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 107 | % % |
| 108 | % % |
| 109 | % % |
| 110 | % R e a d X P S I m a g e % |
| 111 | % % |
| 112 | % % |
| 113 | % % |
| 114 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 115 | % |
| 116 | % ReadXPSImage() reads a Printer Control Language image file and returns it. |
| 117 | % It allocates the memory necessary for the new Image structure and returns a |
| 118 | % pointer to the new image. |
| 119 | % |
Cristy | c60d328 | 2020-07-26 09:55:35 -0400 | [diff] [blame] | 120 | % The format of the ReadPSImage method is: |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 121 | % |
Cristy | c60d328 | 2020-07-26 09:55:35 -0400 | [diff] [blame] | 122 | % Image *ReadPSImage(const ImageInfo *image_info,ExceptionInfo *exception) |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 123 | % |
| 124 | % A description of each parameter follows: |
| 125 | % |
| 126 | % o image_info: the image info. |
| 127 | % |
| 128 | % o exception: return any errors or warnings in this structure. |
| 129 | % |
| 130 | */ |
Cristy | c60d328 | 2020-07-26 09:55:35 -0400 | [diff] [blame] | 131 | |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 132 | static Image *ReadXPSImage(const ImageInfo *image_info,ExceptionInfo *exception) |
| 133 | { |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 134 | char |
cristy | 151b66d | 2015-04-15 10:50:31 +0000 | [diff] [blame] | 135 | command[MagickPathExtent], |
cristy | 5181656 | 2015-04-12 13:18:38 +0000 | [diff] [blame] | 136 | *density, |
cristy | 151b66d | 2015-04-15 10:50:31 +0000 | [diff] [blame] | 137 | filename[MagickPathExtent], |
Cristy | c60d328 | 2020-07-26 09:55:35 -0400 | [diff] [blame] | 138 | input_filename[MagickPathExtent], |
| 139 | message[MagickPathExtent], |
| 140 | *options; |
| 141 | |
| 142 | const char |
| 143 | *option; |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 144 | |
| 145 | const DelegateInfo |
| 146 | *delegate_info; |
| 147 | |
Cristy | c60d328 | 2020-07-26 09:55:35 -0400 | [diff] [blame] | 148 | GeometryInfo |
| 149 | geometry_info; |
| 150 | |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 151 | Image |
| 152 | *image, |
Cristy | c60d328 | 2020-07-26 09:55:35 -0400 | [diff] [blame] | 153 | *next, |
| 154 | *postscript_image; |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 155 | |
| 156 | ImageInfo |
| 157 | *read_info; |
| 158 | |
| 159 | MagickBooleanType |
Cristy | c60d328 | 2020-07-26 09:55:35 -0400 | [diff] [blame] | 160 | fitPage, |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 161 | status; |
| 162 | |
Cristy | c60d328 | 2020-07-26 09:55:35 -0400 | [diff] [blame] | 163 | MagickStatusType |
| 164 | flags; |
| 165 | |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 166 | PointInfo |
Cristy | c60d328 | 2020-07-26 09:55:35 -0400 | [diff] [blame] | 167 | delta, |
| 168 | resolution; |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 169 | |
| 170 | RectangleInfo |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 171 | page; |
| 172 | |
Cristy | f2dc1dd | 2020-12-28 13:59:26 -0500 | [diff] [blame] | 173 | ssize_t |
Cristy | c60d328 | 2020-07-26 09:55:35 -0400 | [diff] [blame] | 174 | i; |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 175 | |
Cristy | c60d328 | 2020-07-26 09:55:35 -0400 | [diff] [blame] | 176 | unsigned long |
| 177 | scene; |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 178 | |
Cristy | c60d328 | 2020-07-26 09:55:35 -0400 | [diff] [blame] | 179 | /* |
| 180 | Open image file. |
| 181 | */ |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 182 | assert(image_info != (const ImageInfo *) NULL); |
cristy | e1c94d9 | 2015-06-28 12:16:33 +0000 | [diff] [blame] | 183 | assert(image_info->signature == MagickCoreSignature); |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 184 | if (image_info->debug != MagickFalse) |
| 185 | (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", |
| 186 | image_info->filename); |
| 187 | assert(exception != (ExceptionInfo *) NULL); |
cristy | e1c94d9 | 2015-06-28 12:16:33 +0000 | [diff] [blame] | 188 | assert(exception->signature == MagickCoreSignature); |
cristy | 9950d57 | 2011-10-01 18:22:35 +0000 | [diff] [blame] | 189 | image=AcquireImage(image_info,exception); |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 190 | status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); |
| 191 | if (status == MagickFalse) |
| 192 | { |
| 193 | image=DestroyImageList(image); |
| 194 | return((Image *) NULL); |
| 195 | } |
| 196 | status=AcquireUniqueSymbolicLink(image_info->filename,input_filename); |
| 197 | if (status == MagickFalse) |
| 198 | { |
| 199 | ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile", |
| 200 | image_info->filename); |
| 201 | image=DestroyImageList(image); |
| 202 | return((Image *) NULL); |
| 203 | } |
| 204 | /* |
| 205 | Set the page density. |
| 206 | */ |
| 207 | delta.x=DefaultResolution; |
| 208 | delta.y=DefaultResolution; |
cristy | 2a11bef | 2011-10-28 18:33:11 +0000 | [diff] [blame] | 209 | if ((image->resolution.x == 0.0) || (image->resolution.y == 0.0)) |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 210 | { |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 211 | flags=ParseGeometry(PSDensityGeometry,&geometry_info); |
cristy | 2a11bef | 2011-10-28 18:33:11 +0000 | [diff] [blame] | 212 | image->resolution.x=geometry_info.rho; |
| 213 | image->resolution.y=geometry_info.sigma; |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 214 | if ((flags & SigmaValue) == 0) |
cristy | 2a11bef | 2011-10-28 18:33:11 +0000 | [diff] [blame] | 215 | image->resolution.y=image->resolution.x; |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 216 | } |
Cristy | c60d328 | 2020-07-26 09:55:35 -0400 | [diff] [blame] | 217 | if (image_info->density != (char *) NULL) |
| 218 | { |
| 219 | flags=ParseGeometry(image_info->density,&geometry_info); |
| 220 | image->resolution.x=geometry_info.rho; |
| 221 | image->resolution.y=geometry_info.sigma; |
| 222 | if ((flags & SigmaValue) == 0) |
| 223 | image->resolution.y=image->resolution.x; |
| 224 | } |
| 225 | (void) ParseAbsoluteGeometry(PSPageGeometry,&page); |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 226 | if (image_info->page != (char *) NULL) |
| 227 | (void) ParseAbsoluteGeometry(image_info->page,&page); |
Cristy | c60d328 | 2020-07-26 09:55:35 -0400 | [diff] [blame] | 228 | resolution=image->resolution; |
| 229 | page.width=(size_t) ((ssize_t) ceil((double) (page.width*resolution.x/ |
| 230 | delta.x)-0.5)); |
| 231 | page.height=(size_t) ((ssize_t) ceil((double) (page.height*resolution.y/ |
| 232 | delta.y)-0.5)); |
| 233 | fitPage=MagickFalse; |
| 234 | option=GetImageOption(image_info,"xps:fit-page"); |
| 235 | if (option != (char *) NULL) |
| 236 | { |
| 237 | char |
| 238 | *page_geometry; |
| 239 | |
| 240 | page_geometry=GetPageGeometry(option); |
| 241 | flags=ParseMetaGeometry(page_geometry,&page.x,&page.y,&page.width, |
| 242 | &page.height); |
| 243 | if (flags == NoValue) |
| 244 | { |
| 245 | (void) ThrowMagickException(exception,GetMagickModule(),OptionError, |
| 246 | "InvalidGeometry","`%s'",option); |
| 247 | page_geometry=DestroyString(page_geometry); |
| 248 | image=DestroyImage(image); |
| 249 | return((Image *) NULL); |
| 250 | } |
| 251 | page.width=(size_t) ((ssize_t) ceil((double) (page.width* |
| 252 | image->resolution.x/delta.x)-0.5)); |
| 253 | page.height=(size_t) ((ssize_t) ceil((double) (page.height* |
| 254 | image->resolution.y/delta.y) -0.5)); |
| 255 | page_geometry=DestroyString(page_geometry); |
| 256 | fitPage=MagickTrue; |
| 257 | } |
| 258 | /* |
| 259 | Render Postscript with the Ghostscript delegate. |
| 260 | */ |
| 261 | delegate_info=GetDelegateInfo("xps:color",(char *) NULL,exception); |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 262 | if (delegate_info == (const DelegateInfo *) NULL) |
Cristy | 041b4c5 | 2018-02-04 15:11:57 -0500 | [diff] [blame] | 263 | { |
Cristy | c60d328 | 2020-07-26 09:55:35 -0400 | [diff] [blame] | 264 | image=DestroyImageList(image); |
Cristy | 041b4c5 | 2018-02-04 15:11:57 -0500 | [diff] [blame] | 265 | return((Image *) NULL); |
| 266 | } |
cristy | 5181656 | 2015-04-12 13:18:38 +0000 | [diff] [blame] | 267 | density=AcquireString(""); |
| 268 | options=AcquireString(""); |
Cristy | c60d328 | 2020-07-26 09:55:35 -0400 | [diff] [blame] | 269 | (void) FormatLocaleString(density,MagickPathExtent,"%gx%g",resolution.x, |
| 270 | resolution.y); |
Cristy | 89c5c75 | 2020-12-18 13:04:39 +0000 | [diff] [blame] | 271 | if (image_info->ping != MagickFalse) |
| 272 | (void) FormatLocaleString(density,MagickPathExtent,"2.0x2.0"); |
cristy | 151b66d | 2015-04-15 10:50:31 +0000 | [diff] [blame] | 273 | (void) FormatLocaleString(options,MagickPathExtent,"-g%.20gx%.20g ",(double) |
cristy | e8c25f9 | 2010-06-03 00:53:06 +0000 | [diff] [blame] | 274 | page.width,(double) page.height); |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 275 | read_info=CloneImageInfo(image_info); |
| 276 | *read_info->magick='\0'; |
| 277 | if (read_info->number_scenes != 0) |
| 278 | { |
Cristy | c60d328 | 2020-07-26 09:55:35 -0400 | [diff] [blame] | 279 | char |
| 280 | pages[MagickPathExtent]; |
| 281 | |
| 282 | (void) FormatLocaleString(pages,MagickPathExtent,"-dFirstPage=%.20g " |
| 283 | "-dLastPage=%.20g ",(double) read_info->scene+1,(double) |
| 284 | (read_info->scene+read_info->number_scenes)); |
| 285 | (void) ConcatenateMagickString(options,pages,MagickPathExtent); |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 286 | read_info->number_scenes=0; |
| 287 | if (read_info->scenes != (char *) NULL) |
| 288 | *read_info->scenes='\0'; |
| 289 | } |
Cristy | c60d328 | 2020-07-26 09:55:35 -0400 | [diff] [blame] | 290 | if (*image_info->magick == 'E') |
| 291 | { |
| 292 | option=GetImageOption(image_info,"xps:use-cropbox"); |
| 293 | if ((option == (const char *) NULL) || |
| 294 | (IsStringTrue(option) != MagickFalse)) |
| 295 | (void) ConcatenateMagickString(options,"-dEPSCrop ",MagickPathExtent); |
| 296 | if (fitPage != MagickFalse) |
| 297 | (void) ConcatenateMagickString(options,"-dEPSFitPage ", |
| 298 | MagickPathExtent); |
| 299 | } |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 300 | (void) AcquireUniqueFilename(read_info->filename); |
Cristy | c60d328 | 2020-07-26 09:55:35 -0400 | [diff] [blame] | 301 | (void) RelinquishUniqueFileResource(read_info->filename); |
| 302 | (void) ConcatenateMagickString(read_info->filename,"%d",MagickPathExtent); |
| 303 | (void) CopyMagickString(filename,read_info->filename,MagickPathExtent); |
cristy | 151b66d | 2015-04-15 10:50:31 +0000 | [diff] [blame] | 304 | (void) FormatLocaleString(command,MagickPathExtent, |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 305 | GetDelegateCommands(delegate_info), |
| 306 | read_info->antialias != MagickFalse ? 4 : 1, |
| 307 | read_info->antialias != MagickFalse ? 4 : 1,density,options, |
| 308 | read_info->filename,input_filename); |
cristy | 5181656 | 2015-04-12 13:18:38 +0000 | [diff] [blame] | 309 | options=DestroyString(options); |
| 310 | density=DestroyString(density); |
Cristy | c60d328 | 2020-07-26 09:55:35 -0400 | [diff] [blame] | 311 | *message='\0'; |
cristy | dfc19b6 | 2014-10-17 22:52:24 +0000 | [diff] [blame] | 312 | status=ExternalDelegateCommand(MagickFalse,read_info->verbose,command, |
| 313 | (char *) NULL,exception) != 0 ? MagickTrue : MagickFalse; |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 314 | (void) RelinquishUniqueFileResource(input_filename); |
Cristy | c60d328 | 2020-07-26 09:55:35 -0400 | [diff] [blame] | 315 | postscript_image=(Image *) NULL; |
| 316 | if (status == MagickFalse) |
| 317 | for (i=1; ; i++) |
| 318 | { |
| 319 | (void) InterpretImageFilename(image_info,image,filename,(int) i, |
| 320 | read_info->filename,exception); |
| 321 | if (IsGhostscriptRendered(read_info->filename) == MagickFalse) |
| 322 | break; |
| 323 | read_info->blob=NULL; |
| 324 | read_info->length=0; |
| 325 | next=ReadImage(read_info,exception); |
| 326 | (void) RelinquishUniqueFileResource(read_info->filename); |
| 327 | if (next == (Image *) NULL) |
| 328 | break; |
| 329 | AppendImageToList(&postscript_image,next); |
| 330 | } |
| 331 | else |
| 332 | for (i=1; ; i++) |
| 333 | { |
| 334 | (void) InterpretImageFilename(image_info,image,filename,(int) i, |
| 335 | read_info->filename,exception); |
| 336 | if (IsGhostscriptRendered(read_info->filename) == MagickFalse) |
| 337 | break; |
| 338 | read_info->blob=NULL; |
| 339 | read_info->length=0; |
| 340 | next=ReadImage(read_info,exception); |
| 341 | (void) RelinquishUniqueFileResource(read_info->filename); |
| 342 | if (next == (Image *) NULL) |
| 343 | break; |
| 344 | AppendImageToList(&postscript_image,next); |
| 345 | } |
| 346 | (void) RelinquishUniqueFileResource(filename); |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 347 | read_info=DestroyImageInfo(read_info); |
Cristy | c60d328 | 2020-07-26 09:55:35 -0400 | [diff] [blame] | 348 | if (postscript_image == (Image *) NULL) |
| 349 | { |
| 350 | if (*message != '\0') |
| 351 | (void) ThrowMagickException(exception,GetMagickModule(), |
| 352 | DelegateError,"PostscriptDelegateFailed","`%s'",message); |
| 353 | image=DestroyImageList(image); |
| 354 | return((Image *) NULL); |
| 355 | } |
| 356 | if (LocaleCompare(postscript_image->magick,"BMP") == 0) |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 357 | { |
| 358 | Image |
| 359 | *cmyk_image; |
| 360 | |
Cristy | c60d328 | 2020-07-26 09:55:35 -0400 | [diff] [blame] | 361 | cmyk_image=ConsolidateCMYKImages(postscript_image,exception); |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 362 | if (cmyk_image != (Image *) NULL) |
| 363 | { |
Cristy | c60d328 | 2020-07-26 09:55:35 -0400 | [diff] [blame] | 364 | postscript_image=DestroyImageList(postscript_image); |
| 365 | postscript_image=cmyk_image; |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 366 | } |
| 367 | } |
Cristy | c60d328 | 2020-07-26 09:55:35 -0400 | [diff] [blame] | 368 | if (image_info->number_scenes != 0) |
| 369 | { |
| 370 | Image |
| 371 | *clone_image; |
| 372 | |
| 373 | /* |
| 374 | Add place holder images to meet the subimage specification requirement. |
| 375 | */ |
| 376 | for (i=0; i < (ssize_t) image_info->scene; i++) |
| 377 | { |
| 378 | clone_image=CloneImage(postscript_image,1,1,MagickTrue,exception); |
| 379 | if (clone_image != (Image *) NULL) |
| 380 | PrependImageToList(&postscript_image,clone_image); |
| 381 | } |
| 382 | } |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 383 | do |
| 384 | { |
Cristy | c60d328 | 2020-07-26 09:55:35 -0400 | [diff] [blame] | 385 | (void) CopyMagickString(postscript_image->filename,filename, |
| 386 | MagickPathExtent); |
| 387 | (void) CopyMagickString(postscript_image->magick,image->magick, |
| 388 | MagickPathExtent); |
| 389 | postscript_image->page=page; |
Cristy | 49d662c | 2020-12-17 15:48:09 +0000 | [diff] [blame] | 390 | if (image_info->ping != MagickFalse) |
| 391 | { |
Cristy | 89c5c75 | 2020-12-18 13:04:39 +0000 | [diff] [blame] | 392 | postscript_image->magick_columns*=image->resolution.x/2.0; |
| 393 | postscript_image->magick_rows*=image->resolution.y/2.0; |
| 394 | postscript_image->columns*=image->resolution.x/2.0; |
| 395 | postscript_image->rows*=image->resolution.y/2.0; |
Cristy | 49d662c | 2020-12-17 15:48:09 +0000 | [diff] [blame] | 396 | } |
Cristy | c60d328 | 2020-07-26 09:55:35 -0400 | [diff] [blame] | 397 | (void) CloneImageProfiles(postscript_image,image); |
| 398 | (void) CloneImageProperties(postscript_image,image); |
| 399 | next=SyncNextImageInList(postscript_image); |
| 400 | if (next != (Image *) NULL) |
| 401 | postscript_image=next; |
| 402 | } while (next != (Image *) NULL); |
| 403 | image=DestroyImageList(image); |
| 404 | scene=0; |
| 405 | for (next=GetFirstImageInList(postscript_image); next != (Image *) NULL; ) |
| 406 | { |
| 407 | next->scene=scene++; |
| 408 | next=GetNextImageInList(next); |
| 409 | } |
| 410 | return(GetFirstImageInList(postscript_image)); |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 411 | } |
| 412 | |
| 413 | /* |
| 414 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 415 | % % |
| 416 | % % |
| 417 | % % |
| 418 | % R e g i s t e r X P S I m a g e % |
| 419 | % % |
| 420 | % % |
| 421 | % % |
| 422 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 423 | % |
Cristy | c60d328 | 2020-07-26 09:55:35 -0400 | [diff] [blame] | 424 | % RegisterXPSImage() adds properties for the PS image format to |
| 425 | % the list of supported formats. The properties include the image format |
| 426 | % tag, a method to read and/or write the format, whether the format |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 427 | % supports the saving of more than one frame to the same file or blob, |
| 428 | % whether the format supports native in-memory I/O, and a brief |
| 429 | % description of the format. |
| 430 | % |
| 431 | % The format of the RegisterXPSImage method is: |
| 432 | % |
cristy | bb50337 | 2010-05-27 20:51:26 +0000 | [diff] [blame] | 433 | % size_t RegisterXPSImage(void) |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 434 | % |
| 435 | */ |
cristy | bb50337 | 2010-05-27 20:51:26 +0000 | [diff] [blame] | 436 | ModuleExport size_t RegisterXPSImage(void) |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 437 | { |
| 438 | MagickInfo |
| 439 | *entry; |
| 440 | |
dirk | 06b627a | 2015-04-06 18:59:17 +0000 | [diff] [blame] | 441 | entry=AcquireMagickInfo("XPS","XPS","Microsoft XML Paper Specification"); |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 442 | entry->decoder=(DecodeImageHandler *) ReadXPSImage; |
Cristy | c60d328 | 2020-07-26 09:55:35 -0400 | [diff] [blame] | 443 | entry->flags|=CoderDecoderSeekableStreamFlag; |
dirk | 08e9a11 | 2015-02-22 01:51:41 +0000 | [diff] [blame] | 444 | entry->flags^=CoderAdjoinFlag; |
| 445 | entry->flags^=CoderBlobSupportFlag; |
Cristy | c60d328 | 2020-07-26 09:55:35 -0400 | [diff] [blame] | 446 | entry->mime_type=ConstantString("application/oxps"); |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 447 | (void) RegisterMagickInfo(entry); |
| 448 | return(MagickImageCoderSignature); |
| 449 | } |
| 450 | |
| 451 | /* |
| 452 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 453 | % % |
| 454 | % % |
| 455 | % % |
| 456 | % U n r e g i s t e r X P S I m a g e % |
| 457 | % % |
| 458 | % % |
| 459 | % % |
| 460 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 461 | % |
Cristy | c60d328 | 2020-07-26 09:55:35 -0400 | [diff] [blame] | 462 | % UnregisterXPSImage() removes format registrations made by the |
| 463 | % XPS module from the list of supported formats. |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 464 | % |
| 465 | % The format of the UnregisterXPSImage method is: |
| 466 | % |
| 467 | % UnregisterXPSImage(void) |
| 468 | % |
| 469 | */ |
| 470 | ModuleExport void UnregisterXPSImage(void) |
| 471 | { |
| 472 | (void) UnregisterMagickInfo("XPS"); |
| 473 | } |