cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 1 | /* |
| 2 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 3 | % % |
| 4 | % % |
| 5 | % % |
| 6 | % DDDD PPPP SSSSS % |
| 7 | % D D P P SS % |
| 8 | % D D PPPP SSS % |
| 9 | % D D P SS % |
| 10 | % DDDD P SSSSS % |
| 11 | % % |
| 12 | % % |
| 13 | % Read Postscript Using the Display Postscript System. % |
| 14 | % % |
| 15 | % Software Design % |
| 16 | % John Cristy % |
| 17 | % July 1992 % |
| 18 | % % |
| 19 | % % |
cristy | 1454be7 | 2011-12-19 01:52:48 +0000 | [diff] [blame] | 20 | % Copyright 1999-2012 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 | % % |
| 26 | % http://www.imagemagick.org/script/license.php % |
| 27 | % % |
| 28 | % Unless required by applicable law or agreed to in writing, software % |
| 29 | % distributed under the License is distributed on an "AS IS" BASIS, % |
| 30 | % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % |
| 31 | % See the License for the specific language governing permissions and % |
| 32 | % limitations under the License. % |
| 33 | % % |
| 34 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 35 | % |
| 36 | % |
| 37 | */ |
| 38 | |
| 39 | /* |
| 40 | Include declarations. |
| 41 | */ |
cristy | 4c08aed | 2011-07-01 19:47:50 +0000 | [diff] [blame] | 42 | #include "MagickCore/studio.h" |
| 43 | #include "MagickCore/blob.h" |
| 44 | #include "MagickCore/blob-private.h" |
| 45 | #include "MagickCore/client.h" |
| 46 | #include "MagickCore/colormap.h" |
| 47 | #include "MagickCore/exception.h" |
| 48 | #include "MagickCore/exception-private.h" |
| 49 | #include "MagickCore/image.h" |
| 50 | #include "MagickCore/image-private.h" |
| 51 | #include "MagickCore/list.h" |
| 52 | #include "MagickCore/magick.h" |
| 53 | #include "MagickCore/memory_.h" |
| 54 | #include "MagickCore/monitor.h" |
| 55 | #include "MagickCore/monitor-private.h" |
cristy | 878ebf5 | 2011-07-02 00:45:32 +0000 | [diff] [blame] | 56 | #include "MagickCore/pixel-accessor.h" |
cristy | 4c08aed | 2011-07-01 19:47:50 +0000 | [diff] [blame] | 57 | #include "MagickCore/quantum-private.h" |
| 58 | #include "MagickCore/static.h" |
| 59 | #include "MagickCore/string_.h" |
| 60 | #include "MagickCore/module.h" |
| 61 | #include "MagickCore/utility.h" |
| 62 | #include "MagickCore/xwindow-private.h" |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 63 | #if defined(MAGICKCORE_DPS_DELEGATE) |
| 64 | #include <DPS/dpsXclient.h> |
| 65 | #include <DPS/dpsXpreview.h> |
| 66 | #endif |
| 67 | |
| 68 | #if defined(MAGICKCORE_DPS_DELEGATE) |
| 69 | /* |
| 70 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 71 | % % |
| 72 | % % |
| 73 | % % |
| 74 | % R e a d D P S I m a g e % |
| 75 | % % |
| 76 | % % |
| 77 | % % |
| 78 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 79 | % |
| 80 | % ReadDPSImage() reads a Adobe Postscript image file and returns it. It |
| 81 | % allocates the memory necessary for the new Image structure and returns a |
| 82 | % pointer to the new image. |
| 83 | % |
| 84 | % The format of the ReadDPSImage method is: |
| 85 | % |
| 86 | % Image *ReadDPSImage(const ImageInfo *image_info,ExceptionInfo *exception) |
| 87 | % |
| 88 | % A description of each parameter follows: |
| 89 | % |
| 90 | % o image_info: the image info. |
| 91 | % |
| 92 | % o exception: return any errors or warnings in this structure. |
| 93 | % |
| 94 | */ |
| 95 | |
| 96 | static inline double MagickMin(const double x,const double y) |
| 97 | { |
| 98 | if (x < y) |
| 99 | return(x); |
| 100 | return(y); |
| 101 | } |
| 102 | |
| 103 | static Image *ReadDPSImage(const ImageInfo *image_info,ExceptionInfo *exception) |
| 104 | { |
cristy | 104cea8 | 2009-10-25 02:26:51 +0000 | [diff] [blame] | 105 | const char |
| 106 | *client_name; |
| 107 | |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 108 | Display |
| 109 | *display; |
| 110 | |
| 111 | float |
| 112 | pixels_per_point; |
| 113 | |
| 114 | Image |
| 115 | *image; |
| 116 | |
| 117 | int |
| 118 | sans, |
| 119 | status; |
| 120 | |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 121 | Pixmap |
| 122 | pixmap; |
| 123 | |
cristy | bb50337 | 2010-05-27 20:51:26 +0000 | [diff] [blame] | 124 | register ssize_t |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 125 | i; |
| 126 | |
cristy | 4c08aed | 2011-07-01 19:47:50 +0000 | [diff] [blame] | 127 | register Quantum |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 128 | *q; |
| 129 | |
cristy | bb50337 | 2010-05-27 20:51:26 +0000 | [diff] [blame] | 130 | register size_t |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 131 | pixel; |
| 132 | |
| 133 | Screen |
| 134 | *screen; |
| 135 | |
cristy | ddbc41b | 2011-04-24 14:27:48 +0000 | [diff] [blame] | 136 | ssize_t |
| 137 | x, |
| 138 | y; |
| 139 | |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 140 | XColor |
| 141 | *colors; |
| 142 | |
| 143 | XImage |
| 144 | *dps_image; |
| 145 | |
| 146 | XRectangle |
| 147 | page, |
| 148 | bits_per_pixel; |
| 149 | |
| 150 | XResourceInfo |
| 151 | resource_info; |
| 152 | |
| 153 | XrmDatabase |
| 154 | resource_database; |
| 155 | |
| 156 | XStandardColormap |
| 157 | *map_info; |
| 158 | |
| 159 | XVisualInfo |
| 160 | *visual_info; |
| 161 | |
| 162 | /* |
| 163 | Open X server connection. |
| 164 | */ |
| 165 | assert(image_info != (const ImageInfo *) NULL); |
| 166 | assert(image_info->signature == MagickSignature); |
| 167 | if (image_info->debug != MagickFalse) |
| 168 | (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", |
| 169 | image_info->filename); |
| 170 | assert(exception != (ExceptionInfo *) NULL); |
| 171 | assert(exception->signature == MagickSignature); |
| 172 | display=XOpenDisplay(image_info->server_name); |
| 173 | if (display == (Display *) NULL) |
| 174 | return((Image *) NULL); |
| 175 | /* |
| 176 | Set our forgiving exception handler. |
| 177 | */ |
| 178 | (void) XSetErrorHandler(XError); |
| 179 | /* |
| 180 | Open image file. |
| 181 | */ |
cristy | 9950d57 | 2011-10-01 18:22:35 +0000 | [diff] [blame] | 182 | image=AcquireImage(image_info,exception); |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 183 | status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); |
| 184 | if (status == MagickFalse) |
| 185 | return((Image *) NULL); |
| 186 | /* |
| 187 | Get user defaults from X resource database. |
| 188 | */ |
cristy | 104cea8 | 2009-10-25 02:26:51 +0000 | [diff] [blame] | 189 | client_name=GetClientName(); |
| 190 | resource_database=XGetResourceDatabase(display,client_name); |
| 191 | XGetResourceInfo(image_info,resource_database,client_name,&resource_info); |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 192 | /* |
| 193 | Allocate standard colormap. |
| 194 | */ |
| 195 | map_info=XAllocStandardColormap(); |
| 196 | visual_info=(XVisualInfo *) NULL; |
| 197 | if (map_info == (XStandardColormap *) NULL) |
| 198 | ThrowReaderException(ResourceLimitError,"UnableToCreateStandardColormap") |
| 199 | else |
| 200 | { |
| 201 | /* |
| 202 | Initialize visual info. |
| 203 | */ |
| 204 | (void) CloneString(&resource_info.visual_type,"default"); |
| 205 | visual_info=XBestVisualInfo(display,map_info,&resource_info); |
| 206 | map_info->colormap=(Colormap) NULL; |
| 207 | } |
| 208 | if ((map_info == (XStandardColormap *) NULL) || |
| 209 | (visual_info == (XVisualInfo *) NULL)) |
| 210 | { |
| 211 | image=DestroyImage(image); |
| 212 | XFreeResources(display,visual_info,map_info,(XPixelInfo *) NULL, |
| 213 | (XFontStruct *) NULL,&resource_info,(XWindowInfo *) NULL); |
| 214 | return((Image *) NULL); |
| 215 | } |
| 216 | /* |
| 217 | Create a pixmap the appropriate size for the image. |
| 218 | */ |
| 219 | screen=ScreenOfDisplay(display,visual_info->screen); |
| 220 | pixels_per_point=XDPSPixelsPerPoint(screen); |
cristy | 2a11bef | 2011-10-28 18:33:11 +0000 | [diff] [blame] | 221 | if ((image->resolution.x != 0.0) && (image->resolution.y != 0.0)) |
| 222 | pixels_per_point=MagickMin(image->resolution.x,image->resolution.y)/ |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 223 | DefaultResolution; |
| 224 | status=XDPSCreatePixmapForEPSF((DPSContext) NULL,screen, |
| 225 | GetBlobFileHandle(image),visual_info->depth,pixels_per_point,&pixmap, |
| 226 | &bits_per_pixel,&page); |
| 227 | if ((status == dps_status_failure) || (status == dps_status_no_extension)) |
| 228 | { |
| 229 | image=DestroyImage(image); |
| 230 | XFreeResources(display,visual_info,map_info,(XPixelInfo *) NULL, |
| 231 | (XFontStruct *) NULL,&resource_info,(XWindowInfo *) NULL); |
| 232 | return((Image *) NULL); |
| 233 | } |
| 234 | /* |
| 235 | Rasterize the file into the pixmap. |
| 236 | */ |
| 237 | status=XDPSImageFileIntoDrawable((DPSContext) NULL,screen,pixmap, |
| 238 | GetBlobFileHandle(image),(int) bits_per_pixel.height,visual_info->depth, |
| 239 | &page,-page.x,-page.y,pixels_per_point,MagickTrue,MagickFalse,MagickTrue, |
| 240 | &sans); |
| 241 | if (status != dps_status_success) |
| 242 | { |
| 243 | image=DestroyImage(image); |
| 244 | XFreeResources(display,visual_info,map_info,(XPixelInfo *) NULL, |
| 245 | (XFontStruct *) NULL,&resource_info,(XWindowInfo *) NULL); |
| 246 | return((Image *) NULL); |
| 247 | } |
| 248 | /* |
| 249 | Initialize DPS X image. |
| 250 | */ |
| 251 | dps_image=XGetImage(display,pixmap,0,0,bits_per_pixel.width, |
| 252 | bits_per_pixel.height,AllPlanes,ZPixmap); |
| 253 | (void) XFreePixmap(display,pixmap); |
| 254 | if (dps_image == (XImage *) NULL) |
| 255 | { |
| 256 | image=DestroyImage(image); |
| 257 | XFreeResources(display,visual_info,map_info,(XPixelInfo *) NULL, |
| 258 | (XFontStruct *) NULL,&resource_info,(XWindowInfo *) NULL); |
| 259 | return((Image *) NULL); |
| 260 | } |
| 261 | /* |
| 262 | Get the colormap colors. |
| 263 | */ |
| 264 | colors=(XColor *) AcquireQuantumMemory(visual_info->colormap_size, |
| 265 | sizeof(*colors)); |
| 266 | if (colors == (XColor *) NULL) |
| 267 | { |
| 268 | image=DestroyImage(image); |
| 269 | XDestroyImage(dps_image); |
| 270 | XFreeResources(display,visual_info,map_info,(XPixelInfo *) NULL, |
| 271 | (XFontStruct *) NULL,&resource_info,(XWindowInfo *) NULL); |
| 272 | return((Image *) NULL); |
| 273 | } |
| 274 | if ((visual_info->klass != DirectColor) && (visual_info->klass != TrueColor)) |
| 275 | for (i=0; i < visual_info->colormap_size; i++) |
| 276 | { |
cristy | bb50337 | 2010-05-27 20:51:26 +0000 | [diff] [blame] | 277 | colors[i].pixel=(size_t) i; |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 278 | colors[i].pad=0; |
| 279 | } |
| 280 | else |
| 281 | { |
cristy | bb50337 | 2010-05-27 20:51:26 +0000 | [diff] [blame] | 282 | size_t |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 283 | blue, |
| 284 | blue_bit, |
| 285 | green, |
| 286 | green_bit, |
| 287 | red, |
| 288 | red_bit; |
| 289 | |
| 290 | /* |
| 291 | DirectColor or TrueColor visual. |
| 292 | */ |
| 293 | red=0; |
| 294 | green=0; |
| 295 | blue=0; |
| 296 | red_bit=visual_info->red_mask & (~(visual_info->red_mask)+1); |
| 297 | green_bit=visual_info->green_mask & (~(visual_info->green_mask)+1); |
| 298 | blue_bit=visual_info->blue_mask & (~(visual_info->blue_mask)+1); |
| 299 | for (i=0; i < visual_info->colormap_size; i++) |
| 300 | { |
| 301 | colors[i].pixel=red | green | blue; |
| 302 | colors[i].pad=0; |
| 303 | red+=red_bit; |
| 304 | if (red > visual_info->red_mask) |
| 305 | red=0; |
| 306 | green+=green_bit; |
| 307 | if (green > visual_info->green_mask) |
| 308 | green=0; |
| 309 | blue+=blue_bit; |
| 310 | if (blue > visual_info->blue_mask) |
| 311 | blue=0; |
| 312 | } |
| 313 | } |
| 314 | (void) XQueryColors(display,XDefaultColormap(display,visual_info->screen), |
| 315 | colors,visual_info->colormap_size); |
| 316 | /* |
| 317 | Convert X image to MIFF format. |
| 318 | */ |
| 319 | if ((visual_info->klass != TrueColor) && (visual_info->klass != DirectColor)) |
| 320 | image->storage_class=PseudoClass; |
cristy | bb50337 | 2010-05-27 20:51:26 +0000 | [diff] [blame] | 321 | image->columns=(size_t) dps_image->width; |
| 322 | image->rows=(size_t) dps_image->height; |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 323 | if (image_info->ping != MagickFalse) |
| 324 | { |
| 325 | (void) CloseBlob(image); |
| 326 | return(GetFirstImageInList(image)); |
| 327 | } |
| 328 | switch (image->storage_class) |
| 329 | { |
| 330 | case DirectClass: |
| 331 | default: |
| 332 | { |
cristy | bb50337 | 2010-05-27 20:51:26 +0000 | [diff] [blame] | 333 | register size_t |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 334 | color, |
| 335 | index; |
| 336 | |
cristy | bb50337 | 2010-05-27 20:51:26 +0000 | [diff] [blame] | 337 | size_t |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 338 | blue_mask, |
| 339 | blue_shift, |
| 340 | green_mask, |
| 341 | green_shift, |
| 342 | red_mask, |
| 343 | red_shift; |
| 344 | |
| 345 | /* |
| 346 | Determine shift and mask for red, green, and blue. |
| 347 | */ |
| 348 | red_mask=visual_info->red_mask; |
| 349 | red_shift=0; |
| 350 | while ((red_mask != 0) && ((red_mask & 0x01) == 0)) |
| 351 | { |
| 352 | red_mask>>=1; |
| 353 | red_shift++; |
| 354 | } |
| 355 | green_mask=visual_info->green_mask; |
| 356 | green_shift=0; |
| 357 | while ((green_mask != 0) && ((green_mask & 0x01) == 0)) |
| 358 | { |
| 359 | green_mask>>=1; |
| 360 | green_shift++; |
| 361 | } |
| 362 | blue_mask=visual_info->blue_mask; |
| 363 | blue_shift=0; |
| 364 | while ((blue_mask != 0) && ((blue_mask & 0x01) == 0)) |
| 365 | { |
| 366 | blue_mask>>=1; |
| 367 | blue_shift++; |
| 368 | } |
| 369 | /* |
| 370 | Convert X image to DirectClass packets. |
| 371 | */ |
| 372 | if ((visual_info->colormap_size > 0) && |
| 373 | (visual_info->klass == DirectColor)) |
cristy | bb50337 | 2010-05-27 20:51:26 +0000 | [diff] [blame] | 374 | for (y=0; y < (ssize_t) image->rows; y++) |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 375 | { |
| 376 | q=QueueAuthenticPixels(image,0,y,image->columns,1,exception); |
cristy | acd2ed2 | 2011-08-30 01:44:23 +0000 | [diff] [blame] | 377 | if (q == (Quantum *) NULL) |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 378 | break; |
cristy | bb50337 | 2010-05-27 20:51:26 +0000 | [diff] [blame] | 379 | for (x=0; x < (ssize_t) image->columns; x++) |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 380 | { |
| 381 | pixel=XGetPixel(dps_image,x,y); |
| 382 | index=(pixel >> red_shift) & red_mask; |
cristy | 4c08aed | 2011-07-01 19:47:50 +0000 | [diff] [blame] | 383 | SetPixelRed(image,ScaleShortToQuantum(colors[index].red),q); |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 384 | index=(pixel >> green_shift) & green_mask; |
cristy | 4c08aed | 2011-07-01 19:47:50 +0000 | [diff] [blame] | 385 | SetPixelGreen(image,ScaleShortToQuantum(colors[index].green),q); |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 386 | index=(pixel >> blue_shift) & blue_mask; |
cristy | 4c08aed | 2011-07-01 19:47:50 +0000 | [diff] [blame] | 387 | SetPixelBlue(image,ScaleShortToQuantum(colors[index].blue),q); |
cristy | ed23157 | 2011-07-14 02:18:59 +0000 | [diff] [blame] | 388 | q+=GetPixelChannels(image); |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 389 | } |
| 390 | if (SyncAuthenticPixels(image,exception) == MagickFalse) |
| 391 | break; |
| 392 | if (SetImageProgress(image,LoadImageTag,y,image->rows) == MagickFalse) |
| 393 | break; |
| 394 | } |
| 395 | else |
cristy | bb50337 | 2010-05-27 20:51:26 +0000 | [diff] [blame] | 396 | for (y=0; y < (ssize_t) image->rows; y++) |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 397 | { |
| 398 | q=QueueAuthenticPixels(image,0,y,image->columns,1,exception); |
cristy | acd2ed2 | 2011-08-30 01:44:23 +0000 | [diff] [blame] | 399 | if (q == (Quantum *) NULL) |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 400 | break; |
cristy | bb50337 | 2010-05-27 20:51:26 +0000 | [diff] [blame] | 401 | for (x=0; x < (ssize_t) image->columns; x++) |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 402 | { |
| 403 | pixel=XGetPixel(dps_image,x,y); |
| 404 | color=(pixel >> red_shift) & red_mask; |
| 405 | color=(color*65535L)/red_mask; |
cristy | 4c08aed | 2011-07-01 19:47:50 +0000 | [diff] [blame] | 406 | SetPixelRed(image,ScaleShortToQuantum((unsigned short) color),q); |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 407 | color=(pixel >> green_shift) & green_mask; |
| 408 | color=(color*65535L)/green_mask; |
cristy | 4c08aed | 2011-07-01 19:47:50 +0000 | [diff] [blame] | 409 | SetPixelGreen(image,ScaleShortToQuantum((unsigned short) color),q); |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 410 | color=(pixel >> blue_shift) & blue_mask; |
| 411 | color=(color*65535L)/blue_mask; |
cristy | 4c08aed | 2011-07-01 19:47:50 +0000 | [diff] [blame] | 412 | SetPixelBlue(image,ScaleShortToQuantum((unsigned short) color),q); |
cristy | ed23157 | 2011-07-14 02:18:59 +0000 | [diff] [blame] | 413 | q+=GetPixelChannels(image); |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 414 | } |
| 415 | if (SyncAuthenticPixels(image,exception) == MagickFalse) |
| 416 | break; |
| 417 | if (SetImageProgress(image,LoadImageTag,y,image->rows) == MagickFalse) |
| 418 | break; |
| 419 | } |
| 420 | break; |
| 421 | } |
| 422 | case PseudoClass: |
| 423 | { |
| 424 | /* |
| 425 | Create colormap. |
| 426 | */ |
cristy | aea7103 | 2011-09-19 13:22:58 +0000 | [diff] [blame] | 427 | if (AcquireImageColormap(image,(size_t) visual_info->colormap_size,exception) == MagickFalse) |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 428 | { |
| 429 | image=DestroyImage(image); |
| 430 | colors=(XColor *) RelinquishMagickMemory(colors); |
| 431 | XDestroyImage(dps_image); |
| 432 | XFreeResources(display,visual_info,map_info,(XPixelInfo *) NULL, |
| 433 | (XFontStruct *) NULL,&resource_info,(XWindowInfo *) NULL); |
| 434 | return((Image *) NULL); |
| 435 | } |
cristy | bb50337 | 2010-05-27 20:51:26 +0000 | [diff] [blame] | 436 | for (i=0; i < (ssize_t) image->colors; i++) |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 437 | { |
| 438 | image->colormap[colors[i].pixel].red=ScaleShortToQuantum(colors[i].red); |
| 439 | image->colormap[colors[i].pixel].green= |
| 440 | ScaleShortToQuantum(colors[i].green); |
| 441 | image->colormap[colors[i].pixel].blue= |
| 442 | ScaleShortToQuantum(colors[i].blue); |
| 443 | } |
| 444 | /* |
| 445 | Convert X image to PseudoClass packets. |
| 446 | */ |
cristy | bb50337 | 2010-05-27 20:51:26 +0000 | [diff] [blame] | 447 | for (y=0; y < (ssize_t) image->rows; y++) |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 448 | { |
| 449 | q=QueueAuthenticPixels(image,0,y,image->columns,1,exception); |
cristy | acd2ed2 | 2011-08-30 01:44:23 +0000 | [diff] [blame] | 450 | if (q == (Quantum *) NULL) |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 451 | break; |
cristy | bb50337 | 2010-05-27 20:51:26 +0000 | [diff] [blame] | 452 | for (x=0; x < (ssize_t) image->columns; x++) |
cristy | 4c08aed | 2011-07-01 19:47:50 +0000 | [diff] [blame] | 453 | { |
| 454 | SetPixelIndex(image,(unsigned short) XGetPixel(dps_image,x,y),q); |
cristy | ed23157 | 2011-07-14 02:18:59 +0000 | [diff] [blame] | 455 | q+=GetPixelChannels(image); |
cristy | 4c08aed | 2011-07-01 19:47:50 +0000 | [diff] [blame] | 456 | } |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 457 | if (SyncAuthenticPixels(image,exception) == MagickFalse) |
| 458 | break; |
| 459 | if (SetImageProgress(image,LoadImageTag,y,image->rows) == MagickFalse) |
| 460 | break; |
| 461 | } |
| 462 | break; |
| 463 | } |
| 464 | } |
| 465 | colors=(XColor *) RelinquishMagickMemory(colors); |
| 466 | XDestroyImage(dps_image); |
| 467 | if (image->storage_class == PseudoClass) |
cristy | ea1a8aa | 2011-10-20 13:24:06 +0000 | [diff] [blame] | 468 | (void) SyncImage(image,exception); |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 469 | /* |
| 470 | Rasterize matte image. |
| 471 | */ |
| 472 | status=XDPSCreatePixmapForEPSF((DPSContext) NULL,screen, |
| 473 | GetBlobFileHandle(image),1,pixels_per_point,&pixmap,&bits_per_pixel,&page); |
| 474 | if ((status != dps_status_failure) && (status != dps_status_no_extension)) |
| 475 | { |
| 476 | status=XDPSImageFileIntoDrawable((DPSContext) NULL,screen,pixmap, |
| 477 | GetBlobFileHandle(image),(int) bits_per_pixel.height,1,&page,-page.x, |
| 478 | -page.y,pixels_per_point,MagickTrue,MagickTrue,MagickTrue,&sans); |
| 479 | if (status == dps_status_success) |
| 480 | { |
| 481 | XImage |
| 482 | *matte_image; |
| 483 | |
| 484 | /* |
| 485 | Initialize image matte. |
| 486 | */ |
| 487 | matte_image=XGetImage(display,pixmap,0,0,bits_per_pixel.width, |
| 488 | bits_per_pixel.height,AllPlanes,ZPixmap); |
| 489 | (void) XFreePixmap(display,pixmap); |
| 490 | if (matte_image != (XImage *) NULL) |
| 491 | { |
| 492 | image->storage_class=DirectClass; |
| 493 | image->matte=MagickTrue; |
cristy | bb50337 | 2010-05-27 20:51:26 +0000 | [diff] [blame] | 494 | for (y=0; y < (ssize_t) image->rows; y++) |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 495 | { |
| 496 | q=QueueAuthenticPixels(image,0,y,image->columns,1,exception); |
cristy | acd2ed2 | 2011-08-30 01:44:23 +0000 | [diff] [blame] | 497 | if (q == (Quantum *) NULL) |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 498 | break; |
cristy | bb50337 | 2010-05-27 20:51:26 +0000 | [diff] [blame] | 499 | for (x=0; x < (ssize_t) image->columns; x++) |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 500 | { |
cristy | 4c08aed | 2011-07-01 19:47:50 +0000 | [diff] [blame] | 501 | SetPixelAlpha(image,OpaqueAlpha,q); |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 502 | if (XGetPixel(matte_image,x,y) == 0) |
cristy | 4c08aed | 2011-07-01 19:47:50 +0000 | [diff] [blame] | 503 | SetPixelAlpha(image,TransparentAlpha,q); |
cristy | ed23157 | 2011-07-14 02:18:59 +0000 | [diff] [blame] | 504 | q+=GetPixelChannels(image); |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 505 | } |
| 506 | if (SyncAuthenticPixels(image,exception) == MagickFalse) |
| 507 | break; |
| 508 | } |
| 509 | XDestroyImage(matte_image); |
| 510 | } |
| 511 | } |
| 512 | } |
| 513 | /* |
| 514 | Relinquish resources. |
| 515 | */ |
| 516 | XFreeResources(display,visual_info,map_info,(XPixelInfo *) NULL, |
| 517 | (XFontStruct *) NULL,&resource_info,(XWindowInfo *) NULL); |
| 518 | (void) CloseBlob(image); |
| 519 | return(GetFirstImageInList(image)); |
| 520 | } |
| 521 | #endif |
| 522 | |
| 523 | /* |
| 524 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 525 | % % |
| 526 | % % |
| 527 | % % |
| 528 | % R e g i s t e r D P S I m a g e % |
| 529 | % % |
| 530 | % % |
| 531 | % % |
| 532 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 533 | % |
| 534 | % RegisterDPSImage() adds attributes for the Display Postscript image |
| 535 | % format to the list of supported formats. The attributes include the image |
| 536 | % format tag, a method to read and/or write the format, whether the format |
| 537 | % supports the saving of more than one frame to the same file or blob, |
| 538 | % whether the format supports native in-memory I/O, and a brief |
| 539 | % description of the format. |
| 540 | % |
| 541 | % The format of the RegisterDPSImage method is: |
| 542 | % |
cristy | bb50337 | 2010-05-27 20:51:26 +0000 | [diff] [blame] | 543 | % size_t RegisterDPSImage(void) |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 544 | % |
| 545 | */ |
cristy | bb50337 | 2010-05-27 20:51:26 +0000 | [diff] [blame] | 546 | ModuleExport size_t RegisterDPSImage(void) |
cristy | 3ed852e | 2009-09-05 21:47:34 +0000 | [diff] [blame] | 547 | { |
| 548 | MagickInfo |
| 549 | *entry; |
| 550 | |
| 551 | entry=SetMagickInfo("DPS"); |
| 552 | #if defined(MAGICKCORE_DPS_DELEGATE) |
| 553 | entry->decoder=(DecodeImageHandler *) ReadDPSImage; |
| 554 | #endif |
| 555 | entry->blob_support=MagickFalse; |
| 556 | entry->description=ConstantString("Display Postscript Interpreter"); |
| 557 | entry->module=ConstantString("DPS"); |
| 558 | (void) RegisterMagickInfo(entry); |
| 559 | return(MagickImageCoderSignature); |
| 560 | } |
| 561 | |
| 562 | /* |
| 563 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 564 | % % |
| 565 | % % |
| 566 | % % |
| 567 | % U n r e g i s t e r D P S I m a g e % |
| 568 | % % |
| 569 | % % |
| 570 | % % |
| 571 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
| 572 | % |
| 573 | % UnregisterDPSImage() removes format registrations made by the |
| 574 | % DPS module from the list of supported formats. |
| 575 | % |
| 576 | % The format of the UnregisterDPSImage method is: |
| 577 | % |
| 578 | % UnregisterDPSImage(void) |
| 579 | % |
| 580 | */ |
| 581 | ModuleExport void UnregisterDPSImage(void) |
| 582 | { |
| 583 | (void) UnregisterMagickInfo("DPS"); |
| 584 | } |