/src/graphicsmagick/coders/ept.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | % Copyright (C) 2003-2022 GraphicsMagick Group |
3 | | % Copyright (C) 2002 ImageMagick Studio |
4 | | % Copyright 1991-1999 E. I. du Pont de Nemours and Company |
5 | | % |
6 | | % This program is covered by multiple licenses, which are described in |
7 | | % Copyright.txt. You should have received a copy of Copyright.txt with this |
8 | | % package; otherwise see http://www.graphicsmagick.org/www/Copyright.html. |
9 | | % |
10 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
11 | | % % |
12 | | % % |
13 | | % % |
14 | | % EEEEE PPPP TTTTT % |
15 | | % E P P T % |
16 | | % EEE PPPP T % |
17 | | % E P T % |
18 | | % EEEEE P T % |
19 | | % % |
20 | | % % |
21 | | % Read/Write Encapsulated Postscript Format (with preview). % |
22 | | % % |
23 | | % % |
24 | | % Software Design % |
25 | | % John Cristy % |
26 | | % July 1992 % |
27 | | % % |
28 | | % % |
29 | | % % |
30 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
31 | | % |
32 | | % |
33 | | */ |
34 | | |
35 | | /* |
36 | | Include declarations. |
37 | | */ |
38 | | #include "magick/studio.h" |
39 | | #include "magick/blob.h" |
40 | | #include "magick/constitute.h" |
41 | | #include "magick/delegate.h" |
42 | | #include "magick/log.h" |
43 | | #include "magick/magick.h" |
44 | | #include "magick/monitor.h" |
45 | | #include "magick/render.h" |
46 | | #include "magick/tempfile.h" |
47 | | #include "magick/utility.h" |
48 | | |
49 | | /* |
50 | | Forward declarations. |
51 | | */ |
52 | | static unsigned int |
53 | | WriteEPTImage(const ImageInfo *,Image *); |
54 | | |
55 | | /* |
56 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
57 | | % % |
58 | | % % |
59 | | % % |
60 | | % I s E P T % |
61 | | % % |
62 | | % % |
63 | | % % |
64 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
65 | | % |
66 | | % Method IsEPT returns True if the image format type, identified by the |
67 | | % magick string, is EPT. |
68 | | % |
69 | | % The format of the IsEPT method is: |
70 | | % |
71 | | % unsigned int IsEPT(const unsigned char *magick,const size_t length) |
72 | | % |
73 | | % A description of each parameter follows: |
74 | | % |
75 | | % o status: Method IsEPT returns True if the image format type is EPT. |
76 | | % |
77 | | % o magick: This string is generally the first few bytes of an image file |
78 | | % or blob. |
79 | | % |
80 | | % o length: Specifies the length of the magick string. |
81 | | % |
82 | | % |
83 | | */ |
84 | | static unsigned int IsEPT(const unsigned char *magick,const size_t length) |
85 | 0 | { |
86 | 0 | if (length < 4) |
87 | 0 | return(False); |
88 | 0 | if (memcmp(magick,"\305\320\323\306",4) == 0) |
89 | 0 | return(True); |
90 | 0 | return(False); |
91 | 0 | } |
92 | | |
93 | | /* |
94 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
95 | | % % |
96 | | % % |
97 | | % % |
98 | | % R e a d E P T I m a g e % |
99 | | % % |
100 | | % % |
101 | | % % |
102 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
103 | | % |
104 | | % Method ReadEPTImage reads a binary Adobe Postscript image file and returns |
105 | | % it. It allocates the memory necessary for the new Image structure and |
106 | | % returns a pointer to the new image. |
107 | | % |
108 | | % The format of the ReadEPTImage method is: |
109 | | % |
110 | | % Image *ReadEPTImage(const ImageInfo *image_info, |
111 | | % ExceptionInfo *exception) |
112 | | % |
113 | | % A description of each parameter follows: |
114 | | % |
115 | | % o image: Method ReadEPTImage returns a pointer to the image after |
116 | | % reading. A null image is returned if there is a memory shortage or |
117 | | % if the image cannot be read. |
118 | | % |
119 | | % o image_info: Specifies a pointer to a ImageInfo structure. |
120 | | % |
121 | | % o exception: return any errors or warnings in this structure. |
122 | | % |
123 | | % |
124 | | */ |
125 | | #if defined(HasGS) |
126 | | static Image *ReadEPTImage(const ImageInfo *image_info, |
127 | | ExceptionInfo *exception) |
128 | 257 | { |
129 | 257 | #define BoundingBox "%%BoundingBox:" |
130 | 257 | #define DocumentMedia "%%DocumentMedia:" |
131 | 257 | #define PageBoundingBox "%%PageBoundingBox:" |
132 | 257 | #define PostscriptLevel "%!PS-" |
133 | 257 | #define RenderPostscriptText "[%s] Rendering postscript..." |
134 | | |
135 | 257 | char |
136 | 257 | density[MaxTextExtent], |
137 | 257 | command[MaxTextExtent], |
138 | 257 | filename[MaxTextExtent], |
139 | 257 | geometry[MaxTextExtent], |
140 | 257 | postscript_filename[MaxTextExtent], |
141 | 257 | translate_geometry[MaxTextExtent]; |
142 | | |
143 | 257 | const DelegateInfo |
144 | 257 | *delegate_info; |
145 | | |
146 | 257 | double |
147 | 257 | dx_resolution, |
148 | 257 | dy_resolution; |
149 | | |
150 | 257 | FILE |
151 | 257 | *file; |
152 | | |
153 | 257 | Image |
154 | 257 | *image, |
155 | 257 | *next_image; |
156 | | |
157 | 257 | int |
158 | 257 | c, |
159 | 257 | status; |
160 | | |
161 | 257 | unsigned int |
162 | 257 | antialias=4; |
163 | | |
164 | 257 | magick_uint32_t |
165 | 257 | filesize; |
166 | | |
167 | 257 | RectangleInfo |
168 | 257 | box, |
169 | 257 | page; |
170 | | |
171 | 257 | register char |
172 | 257 | *p; |
173 | | |
174 | 257 | register size_t |
175 | 257 | i; |
176 | | |
177 | 257 | SegmentInfo |
178 | 257 | bounds; |
179 | | |
180 | 257 | magick_uint32_t |
181 | 257 | count; |
182 | | |
183 | 257 | unsigned long |
184 | 257 | height, |
185 | 257 | width; |
186 | | |
187 | 257 | assert(image_info != (const ImageInfo *) NULL); |
188 | 257 | assert(image_info->signature == MagickSignature); |
189 | 257 | assert(exception != (ExceptionInfo *) NULL); |
190 | 257 | assert(exception->signature == MagickSignature); |
191 | | |
192 | | /* |
193 | | Select Postscript delegate driver |
194 | | */ |
195 | 257 | delegate_info=GetPostscriptDelegateInfo(image_info,&antialias,exception); |
196 | 257 | if (delegate_info == (const DelegateInfo *) NULL) |
197 | 257 | return((Image *) NULL); |
198 | | /* |
199 | | Open image file. |
200 | | */ |
201 | 0 | image=AllocateImage(image_info); |
202 | 0 | status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); |
203 | 0 | if (status == False) |
204 | 0 | ThrowReaderException(FileOpenError,UnableToOpenFile,image); |
205 | | /* |
206 | | Set the page geometry. |
207 | | */ |
208 | 0 | dx_resolution=72.0; |
209 | 0 | dy_resolution=72.0; |
210 | 0 | if ((image->x_resolution == 0.0) || (image->y_resolution == 0.0)) |
211 | 0 | { |
212 | 0 | (void) strlcpy(density,PSDensityGeometry,sizeof(density)); |
213 | 0 | count=GetMagickDimension(density,&image->x_resolution, |
214 | 0 | &image->y_resolution,NULL,NULL); |
215 | 0 | if (count != 2) |
216 | 0 | image->y_resolution=image->x_resolution; |
217 | 0 | } |
218 | 0 | FormatString(density,"%gx%g",image->x_resolution,image->y_resolution); |
219 | 0 | if (image->logging) |
220 | 0 | (void) LogMagickEvent(CoderEvent,GetMagickModule(), |
221 | 0 | "Density: %s", density); |
222 | 0 | SetGeometry(image,&page); |
223 | 0 | page.width=612; |
224 | 0 | page.height=792; |
225 | 0 | (void) GetGeometry(PSPageGeometry,&page.x,&page.y,&page.width,&page.height); |
226 | | /* |
227 | | Determine page geometry from the Postscript bounding box. |
228 | | */ |
229 | 0 | (void) ReadBlobLSBLong(image); |
230 | 0 | count=ReadBlobLSBLong(image); |
231 | 0 | filesize=ReadBlobLSBLong(image); |
232 | 0 | if (EOFBlob(image)) |
233 | 0 | ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); |
234 | 0 | if (image->logging) |
235 | 0 | (void) LogMagickEvent(CoderEvent,GetMagickModule(), |
236 | 0 | "File Size: %u, Offset: %u", |
237 | 0 | (unsigned int) filesize, (unsigned int) count); |
238 | 0 | if ((count <= 12) || (filesize == 0)) |
239 | 0 | ThrowReaderException(CorruptImageError,ImproperImageHeader,image); |
240 | 0 | for (i=0; i < (count-12); i++) |
241 | 0 | if (ReadBlobByte(image) == EOF) |
242 | 0 | ThrowReaderException(CorruptImageError,UnexpectedEndOfFile,image); |
243 | | /* |
244 | | Open temporary output file. |
245 | | */ |
246 | 0 | file=AcquireTemporaryFileStream(postscript_filename,BinaryFileIOMode); |
247 | 0 | if (file == (FILE *) NULL) |
248 | 0 | ThrowReaderTemporaryFileException(postscript_filename); |
249 | 0 | FormatString(translate_geometry,"%g %g translate\n ",0.0,0.0); |
250 | 0 | (void) fputs(translate_geometry,file); |
251 | | /* |
252 | | Copy Postscript to temporary file. |
253 | | */ |
254 | 0 | box.width=0; |
255 | 0 | box.height=0; |
256 | 0 | p=command; |
257 | 0 | if (image->logging) |
258 | 0 | (void) LogMagickEvent(CoderEvent,GetMagickModule(), |
259 | 0 | "Copying Postscript to temporary file \"%s\" ...", |
260 | 0 | postscript_filename); |
261 | 0 | bounds.x1=0.0; |
262 | 0 | bounds.y1=0.0; |
263 | 0 | bounds.x2=0.0; |
264 | 0 | bounds.y2=0.0; |
265 | 0 | for (i=0; i < filesize; i++) |
266 | 0 | { |
267 | 0 | if ((c=ReadBlobByte(image)) == EOF) |
268 | 0 | break; |
269 | 0 | (void) fputc(c,file); |
270 | 0 | *p++=c; |
271 | 0 | if ((c != '\n') && (c != '\r') && ((p-command) < (MaxTextExtent-1))) |
272 | 0 | continue; |
273 | 0 | *p='\0'; |
274 | 0 | p=command; |
275 | | /* |
276 | | Parse a bounding box statement. |
277 | | */ |
278 | 0 | count=0; |
279 | 0 | if (LocaleNCompare(BoundingBox,command,strlen(BoundingBox)) == 0) |
280 | 0 | count=sscanf(command,"%%%%BoundingBox: %lf %lf %lf %lf",&bounds.x1, |
281 | 0 | &bounds.y1,&bounds.x2,&bounds.y2); |
282 | 0 | if (LocaleNCompare(DocumentMedia,command,strlen(DocumentMedia)) == 0) |
283 | 0 | count=sscanf(command,"%%%%DocumentMedia: %*s %lf %lf",&bounds.x2, |
284 | 0 | &bounds.y2)+2; |
285 | 0 | if (LocaleNCompare(PageBoundingBox,command,strlen(PageBoundingBox)) == 0) |
286 | 0 | count=sscanf(command,"%%%%PageBoundingBox: %lf %lf %lf %lf", |
287 | 0 | &bounds.x1,&bounds.y1,&bounds.x2,&bounds.y2); |
288 | 0 | if (count != 4) |
289 | 0 | continue; |
290 | 0 | if ((bounds.x1 > bounds.x2) || |
291 | 0 | (bounds.y1 > bounds.y2)) |
292 | 0 | continue; |
293 | | /* |
294 | | Set Postscript render geometry. |
295 | | */ |
296 | 0 | FormatString(translate_geometry,"%g %g translate\n",-bounds.x1,-bounds.y1); |
297 | 0 | width=(unsigned long) (bounds.x2-bounds.x1+0.5); |
298 | 0 | height=(unsigned long) (bounds.y2-bounds.y1+0.5); |
299 | 0 | if ((width <= box.width) && (height <= box.height)) |
300 | 0 | continue; |
301 | 0 | page.width=width; |
302 | 0 | page.height=height; |
303 | 0 | box=page; |
304 | 0 | } |
305 | 0 | if (image->logging) |
306 | 0 | (void) LogMagickEvent(CoderEvent,GetMagickModule(), |
307 | 0 | "Done copying."); |
308 | 0 | if (image_info->page != (char *) NULL) |
309 | 0 | (void) GetGeometry(image_info->page,&page.x,&page.y,&page.width, |
310 | 0 | &page.height); |
311 | 0 | FormatString(geometry,"%lux%lu", |
312 | 0 | (unsigned long) ceil(page.width*image->x_resolution/dx_resolution-0.5), |
313 | 0 | (unsigned long) ceil(page.height*image->y_resolution/dy_resolution-0.5)); |
314 | 0 | if (image->logging) |
315 | 0 | (void) LogMagickEvent(CoderEvent,GetMagickModule(), |
316 | 0 | "Page geometry: %s",geometry); |
317 | 0 | if (ferror(file)) |
318 | 0 | { |
319 | 0 | (void) fclose(file); |
320 | 0 | (void) LiberateTemporaryFile(postscript_filename); |
321 | 0 | ThrowReaderException(CorruptImageError,AnErrorHasOccurredWritingToFile, |
322 | 0 | image) |
323 | 0 | } |
324 | 0 | (void) rewind(file); |
325 | 0 | (void) fputs(translate_geometry,file); |
326 | 0 | (void) fclose(file); |
327 | 0 | CloseBlob(image); |
328 | 0 | filesize=GetBlobSize(image); |
329 | 0 | DestroyImage(image); |
330 | 0 | image=(Image *) NULL; |
331 | | /* |
332 | | Use Ghostscript to convert Postscript image. |
333 | | */ |
334 | 0 | { |
335 | 0 | char |
336 | 0 | options[MaxTextExtent]; |
337 | |
|
338 | 0 | options[0]='\0'; |
339 | | /* |
340 | | Append subrange. |
341 | | */ |
342 | 0 | if (image_info->subrange != 0) |
343 | 0 | FormatString(options,"-dFirstPage=%lu -dLastPage=%lu", |
344 | 0 | image_info->subimage+1,image_info->subimage+image_info->subrange); |
345 | | /* |
346 | | Append bounding box. |
347 | | */ |
348 | 0 | FormatString(options+strlen(options)," -g%s",geometry); |
349 | 0 | (void) strlcpy(filename,image_info->filename,MaxTextExtent); |
350 | 0 | if (image_info->temporary) |
351 | 0 | (void) LiberateTemporaryFile((char *) image_info->filename); |
352 | 0 | if(!AcquireTemporaryFileName((char *)image_info->filename)) |
353 | 0 | { |
354 | 0 | (void) LiberateTemporaryFile(postscript_filename); |
355 | 0 | ThrowReaderTemporaryFileException(image_info->filename); |
356 | 0 | } |
357 | 0 | FormatString(command,delegate_info->commands,antialias, |
358 | 0 | antialias,density,options,image_info->filename, |
359 | 0 | postscript_filename); |
360 | 0 | } |
361 | 0 | (void) MagickMonitorFormatted(0,8,exception,RenderPostscriptText, |
362 | 0 | image_info->filename); |
363 | 0 | status=InvokePostscriptDelegate(image_info->verbose,command,exception); |
364 | 0 | if (!IsAccessibleAndNotEmpty(image_info->filename)) |
365 | 0 | { |
366 | | /* |
367 | | Ghostscript requires a showpage operator. |
368 | | */ |
369 | 0 | file=fopen(postscript_filename,"ab"); |
370 | 0 | if (file == (FILE *) NULL) |
371 | 0 | { |
372 | 0 | (void) LiberateTemporaryFile((char *) image_info->filename); |
373 | 0 | ThrowReaderException(FileOpenError,UnableToWriteFile,image); |
374 | 0 | } |
375 | 0 | (void) fputs("showpage\n",file); |
376 | 0 | (void) fclose(file); |
377 | 0 | status=InvokePostscriptDelegate(image_info->verbose,command,exception); |
378 | 0 | } |
379 | 0 | (void) LiberateTemporaryFile(postscript_filename); |
380 | 0 | (void) MagickMonitorFormatted(7,8,exception,RenderPostscriptText, |
381 | 0 | image_info->filename); |
382 | 0 | if (IsAccessibleAndNotEmpty(image_info->filename)) |
383 | 0 | { |
384 | | /* |
385 | | Read Ghostscript output. |
386 | | */ |
387 | 0 | ImageInfo |
388 | 0 | *clone_info; |
389 | |
|
390 | 0 | clone_info=CloneImageInfo(image_info); |
391 | 0 | clone_info->blob=(void *) NULL; |
392 | 0 | clone_info->length=0; |
393 | 0 | clone_info->magick[0]='\0'; |
394 | 0 | image=ReadImage(clone_info,exception); |
395 | 0 | DestroyImageInfo(clone_info); |
396 | 0 | } |
397 | 0 | (void) LiberateTemporaryFile((char *) image_info->filename); |
398 | 0 | if (image == (Image *) NULL) |
399 | 0 | if (UndefinedException == exception->severity) |
400 | 0 | ThrowException(exception,DelegateError,PostscriptDelegateFailed,filename); |
401 | 0 | if (image != (Image *) NULL) |
402 | 0 | { |
403 | 0 | do |
404 | 0 | { |
405 | 0 | (void) strlcpy(image->magick,"PS",sizeof(image->magick)); |
406 | 0 | (void) strlcpy(image->filename,filename,sizeof(image->filename)); |
407 | 0 | next_image=SyncNextImageInList(image); |
408 | 0 | if (next_image != (Image *) NULL) |
409 | 0 | image=next_image; |
410 | 0 | } while (next_image != (Image *) NULL); |
411 | 0 | while (image->previous != (Image *) NULL) |
412 | 0 | image=image->previous; |
413 | 0 | } |
414 | 0 | return(image); |
415 | 0 | } |
416 | | #endif /* if defined(HasGS) */ |
417 | | |
418 | | /* |
419 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
420 | | % % |
421 | | % % |
422 | | % % |
423 | | % R e g i s t e r E P T I m a g e % |
424 | | % % |
425 | | % % |
426 | | % % |
427 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
428 | | % |
429 | | % Method RegisterEPTImage adds attributes for the EPT image format to |
430 | | % the list of supported formats. The attributes include the image format |
431 | | % tag, a method to read and/or write the format, whether the format |
432 | | % supports the saving of more than one frame to the same file or blob, |
433 | | % whether the format supports native in-memory I/O, and a brief |
434 | | % description of the format. |
435 | | % |
436 | | % The format of the RegisterEPTImage method is: |
437 | | % |
438 | | % RegisterEPTImage(void) |
439 | | % |
440 | | */ |
441 | | ModuleExport void RegisterEPTImage(void) |
442 | 3 | { |
443 | 3 | MagickInfo |
444 | 3 | *entry; |
445 | | |
446 | 3 | entry=SetMagickInfo("EPT"); |
447 | 3 | #if defined(HasGS) |
448 | 3 | entry->decoder=(DecoderHandler) ReadEPTImage; |
449 | 3 | #endif /* if defined(HasGS) */ |
450 | 3 | entry->encoder=(EncoderHandler) WriteEPTImage; |
451 | 3 | entry->magick=(MagickHandler) IsEPT; |
452 | 3 | entry->adjoin=False; |
453 | 3 | entry->blob_support=MagickFalse; |
454 | 3 | entry->description="Adobe Encapsulated PostScript with MS-DOS TIFF preview"; |
455 | 3 | entry->module="EPT"; |
456 | 3 | entry->coder_class=PrimaryCoderClass; |
457 | 3 | (void) RegisterMagickInfo(entry); |
458 | | |
459 | 3 | entry=SetMagickInfo("EPT2"); |
460 | 3 | #if defined(HasGS) |
461 | 3 | entry->decoder=(DecoderHandler) ReadEPTImage; |
462 | 3 | #endif /* if defined(HasGS) */ |
463 | 3 | entry->encoder=(EncoderHandler) WriteEPTImage; |
464 | 3 | entry->magick=(MagickHandler) IsEPT; |
465 | 3 | entry->adjoin=False; |
466 | 3 | entry->blob_support=MagickFalse; |
467 | 3 | entry->description="Adobe Level II Encapsulated PostScript with MS-DOS TIFF preview"; |
468 | 3 | entry->module="EPT"; |
469 | 3 | entry->coder_class=PrimaryCoderClass; |
470 | 3 | (void) RegisterMagickInfo(entry); |
471 | | |
472 | 3 | entry=SetMagickInfo("EPT3"); |
473 | 3 | #if defined(HasGS) |
474 | 3 | entry->decoder=(DecoderHandler) ReadEPTImage; |
475 | 3 | #endif /* if defined(HasGS) */ |
476 | 3 | entry->encoder=(EncoderHandler) WriteEPTImage; |
477 | 3 | entry->magick=(MagickHandler) IsEPT; |
478 | 3 | entry->adjoin=False; |
479 | 3 | entry->blob_support=MagickFalse; |
480 | 3 | entry->description="Adobe Level III Encapsulated PostScript with MS-DOS TIFF preview"; |
481 | 3 | entry->module="EPT"; |
482 | 3 | entry->coder_class=PrimaryCoderClass; |
483 | 3 | (void) RegisterMagickInfo(entry); |
484 | 3 | } |
485 | | |
486 | | /* |
487 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
488 | | % % |
489 | | % % |
490 | | % % |
491 | | % U n r e g i s t e r E P T I m a g e % |
492 | | % % |
493 | | % % |
494 | | % % |
495 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
496 | | % |
497 | | % Method UnregisterEPTImage removes format registrations made by the |
498 | | % EPT module from the list of supported formats. |
499 | | % |
500 | | % The format of the UnregisterEPTImage method is: |
501 | | % |
502 | | % UnregisterEPTImage(void) |
503 | | % |
504 | | */ |
505 | | ModuleExport void UnregisterEPTImage(void) |
506 | 0 | { |
507 | 0 | (void) UnregisterMagickInfo("EPT"); |
508 | 0 | (void) UnregisterMagickInfo("EPT2"); |
509 | 0 | (void) UnregisterMagickInfo("EPT3"); |
510 | 0 | } |
511 | | |
512 | | /* |
513 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
514 | | % % |
515 | | % % |
516 | | % % |
517 | | % W r i t e E P T I m a g e % |
518 | | % % |
519 | | % % |
520 | | % % |
521 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
522 | | % |
523 | | % Method WriteEPTImage writes an image in the Adobe Encapsulated Postscript |
524 | | % format with a TIFF preview. |
525 | | % |
526 | | % The format of the WriteEPTImage method is: |
527 | | % |
528 | | % unsigned int WriteEPTImage(const ImageInfo *image_info,Image *image) |
529 | | % |
530 | | % A description of each parameter follows. |
531 | | % |
532 | | % o status: Method WriteEPTImage return True if the image is written. |
533 | | % False is returned is there is a memory shortage or if the image file |
534 | | % fails to write. |
535 | | % |
536 | | % o image_info: Specifies a pointer to a ImageInfo structure. |
537 | | % |
538 | | % o image: A pointer to an Image structure. |
539 | | % |
540 | | % |
541 | | */ |
542 | | static unsigned int WriteEPTImage(const ImageInfo *image_info,Image *image) |
543 | 0 | { |
544 | 0 | char |
545 | 0 | filename[MaxTextExtent], |
546 | 0 | ps_filename[MaxTextExtent], |
547 | 0 | tiff_filename[MaxTextExtent]; |
548 | |
|
549 | 0 | FILE |
550 | 0 | *ps_file, |
551 | 0 | *tiff_file; |
552 | |
|
553 | 0 | unsigned int |
554 | 0 | logging, |
555 | 0 | status; |
556 | |
|
557 | 0 | assert(image_info != (const ImageInfo *) NULL); |
558 | 0 | assert(image_info->signature == MagickSignature); |
559 | 0 | assert(image != (Image *) NULL); |
560 | 0 | assert(image->signature == MagickSignature); |
561 | | |
562 | 0 | logging=IsEventLogged(CoderEvent); |
563 | |
|
564 | 0 | (void) strlcpy(filename,image->filename,MaxTextExtent); |
565 | 0 | (void) strlcpy(ps_filename,image->magick_filename,MaxTextExtent); |
566 | 0 | if (LocaleCompare(image_info->magick,"EPS") != 0) |
567 | 0 | { |
568 | | /* |
569 | | Write image as Encapsulated Postscript to a temporary file. |
570 | | */ |
571 | 0 | char |
572 | 0 | subformat[MaxTextExtent]; |
573 | |
|
574 | 0 | if(!AcquireTemporaryFileName(ps_filename)) |
575 | 0 | ThrowWriterTemporaryFileException(ps_filename); |
576 | | |
577 | | /* Select desired EPS level */ |
578 | 0 | (void) strlcpy(subformat,"eps",sizeof(subformat)); |
579 | 0 | if (LocaleCompare(image_info->magick,"EPT2") == 0) |
580 | 0 | (void) strlcpy(subformat,"eps2",sizeof(subformat)); |
581 | 0 | else if (LocaleCompare(image_info->magick,"EPT3") == 0) |
582 | 0 | (void) strlcpy(subformat,"eps3",sizeof(subformat)); |
583 | | |
584 | | /* JPEG compression requires at least EPS2 */ |
585 | 0 | if ((image->compression == JPEGCompression) && |
586 | 0 | (LocaleCompare(subformat,"EPS") == 0)) |
587 | 0 | (void) strlcpy(subformat,"eps2",sizeof(subformat)); |
588 | |
|
589 | 0 | FormatString(image->filename,"%s:%.1024s",subformat,ps_filename); |
590 | 0 | if (logging) |
591 | 0 | (void) LogMagickEvent(CoderEvent,GetMagickModule(), |
592 | 0 | "Writing temporary EPS file \"%s\"",ps_filename); |
593 | 0 | (void) WriteImage(image_info,image); |
594 | 0 | } |
595 | | /* |
596 | | Write image as TIFF to a temporary file. |
597 | | */ |
598 | 0 | if(!AcquireTemporaryFileName(tiff_filename)) |
599 | 0 | { |
600 | 0 | (void) LiberateTemporaryFile(ps_filename); |
601 | 0 | ThrowWriterTemporaryFileException(tiff_filename); |
602 | 0 | } |
603 | | |
604 | 0 | FormatString(image->filename,"tiff:%.1024s",tiff_filename); |
605 | 0 | image->compression=RLECompression; |
606 | 0 | if (logging) |
607 | 0 | (void) LogMagickEvent(CoderEvent,GetMagickModule(), |
608 | 0 | "Writing temporary TIFF preview file \"%s\"",tiff_filename); |
609 | 0 | (void) WriteImage(image_info,image); |
610 | | /* |
611 | | Write EPT image. |
612 | | */ |
613 | 0 | (void) strlcpy(image->filename,filename,MaxTextExtent); |
614 | 0 | status=MagickFail; |
615 | 0 | if (OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception) != MagickFail) |
616 | 0 | { |
617 | 0 | if ((ps_file=fopen(ps_filename,"rb")) != (FILE *) NULL) |
618 | 0 | { |
619 | 0 | if ((tiff_file=fopen(tiff_filename,"rb")) != (FILE *) NULL) |
620 | 0 | { |
621 | 0 | int |
622 | 0 | c; |
623 | |
|
624 | 0 | struct stat |
625 | 0 | attributes; |
626 | | |
627 | | /* |
628 | | Write EPT image. |
629 | | */ |
630 | | |
631 | | /* MS-DOS EPS binary file magic signature */ |
632 | 0 | (void) WriteBlobLSBLong(image,0xc6d3d0c5ul); |
633 | | /* Byte position in file for start of Postscript language code |
634 | | section */ |
635 | 0 | (void) WriteBlobLSBLong(image,30); |
636 | 0 | if (logging) |
637 | 0 | (void) LogMagickEvent(CoderEvent,GetMagickModule(), |
638 | 0 | "EPS section offset is %lu bytes",(unsigned long) 30); |
639 | | /* Byte length of PostScript language section. */ |
640 | 0 | attributes.st_size=0; |
641 | 0 | (void) fstat(fileno(ps_file),&attributes); |
642 | 0 | if (logging) |
643 | 0 | (void) LogMagickEvent(CoderEvent,GetMagickModule(), |
644 | 0 | "EPS section is %lu bytes long", |
645 | 0 | (unsigned long)attributes.st_size); |
646 | 0 | (void) WriteBlobLSBLong(image,(unsigned long) attributes.st_size); |
647 | | /* Byte position in file for start of Metafile screen |
648 | | representation (none provided). */ |
649 | 0 | (void) WriteBlobLSBLong(image,0); |
650 | | /* Byte length of Metafile section (PSize). (none provided) */ |
651 | 0 | (void) WriteBlobLSBLong(image,0); |
652 | | /* Byte position of TIFF representation. */ |
653 | 0 | (void) WriteBlobLSBLong(image,(unsigned long) attributes.st_size+30); |
654 | 0 | if (logging) |
655 | 0 | (void) LogMagickEvent(CoderEvent,GetMagickModule(), |
656 | 0 | "TIFF section offset is %lu bytes", |
657 | 0 | (unsigned long) attributes.st_size+30); |
658 | | /* Byte length of TIFF section. */ |
659 | 0 | (void) fstat(fileno(tiff_file),&attributes); |
660 | 0 | if (logging) |
661 | 0 | (void) LogMagickEvent(CoderEvent,GetMagickModule(), |
662 | 0 | "TIFF section is %lu bytes long", |
663 | 0 | (unsigned long) attributes.st_size); |
664 | 0 | (void) WriteBlobLSBLong(image,(long) attributes.st_size); |
665 | | /* Checksum of header (XOR of bytes 0-27). If Checksum is FFFF |
666 | | then ignore it. This is lazy code. */ |
667 | 0 | (void) WriteBlobLSBShort(image,0xffff); |
668 | | /* EPS section */ |
669 | 0 | if (logging) |
670 | 0 | (void) LogMagickEvent(CoderEvent,GetMagickModule(), |
671 | 0 | "Writing EPS section at offset %ld", |
672 | 0 | (long) TellBlob(image)); |
673 | 0 | for (c=fgetc(ps_file); c != EOF; c=fgetc(ps_file)) |
674 | 0 | (void) WriteBlobByte(image,c); |
675 | | /* TIFF section */ |
676 | 0 | if (logging) |
677 | 0 | (void) LogMagickEvent(CoderEvent,GetMagickModule(), |
678 | 0 | "Writing TIFF section at offset %ld", |
679 | 0 | (long) TellBlob(image)); |
680 | 0 | for (c=fgetc(tiff_file); c != EOF; c=fgetc(tiff_file)) |
681 | 0 | (void) WriteBlobByte(image,c); |
682 | 0 | (void) fclose(tiff_file); |
683 | 0 | status=MagickPass; |
684 | 0 | } |
685 | 0 | else |
686 | 0 | { |
687 | 0 | (void) LogMagickEvent(CoderEvent,GetMagickModule(), |
688 | 0 | "Failed to open \"%s\" for read", |
689 | 0 | tiff_filename); |
690 | 0 | } |
691 | 0 | (void) fclose(ps_file); |
692 | 0 | } |
693 | 0 | else |
694 | 0 | { |
695 | 0 | (void) LogMagickEvent(CoderEvent,GetMagickModule(), |
696 | 0 | "Failed to open \"%s\" for read",ps_filename); |
697 | 0 | } |
698 | |
|
699 | 0 | status &= CloseBlob(image); |
700 | 0 | } |
701 | 0 | else |
702 | 0 | { |
703 | 0 | (void) LogMagickEvent(CoderEvent,GetMagickModule(), |
704 | 0 | "Failed to open \"%s\" for write", |
705 | 0 | image->filename); |
706 | 0 | } |
707 | 0 | if (LocaleCompare(image_info->magick,"EPS") != 0) |
708 | 0 | (void) LiberateTemporaryFile(ps_filename); |
709 | 0 | (void) LiberateTemporaryFile(tiff_filename); |
710 | 0 | if (status == MagickFail) |
711 | 0 | ThrowWriterException(FileOpenError,UnableToOpenFile,image); |
712 | 0 | return(status); |
713 | 0 | } |