PageRenderTime 138ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/plugins/ImageMagick-6.3.2/magick/utility.c

https://bitbucket.org/sisko/operation-caribou
C | 1558 lines | 1246 code | 30 blank | 282 comment | 108 complexity | 86d960ce840b421351b9fda5cc0e9f5a MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-2.1
  1. /*
  2. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3. % %
  4. % %
  5. % %
  6. % U U TTTTT IIIII L IIIII TTTTT Y Y %
  7. % U U T I L I T Y Y %
  8. % U U T I L I T Y %
  9. % U U T I L I T Y %
  10. % UUU T IIIII LLLLL IIIII T Y %
  11. % %
  12. % %
  13. % ImageMagick Utility Methods %
  14. % %
  15. % Software Design %
  16. % John Cristy %
  17. % January 1993 %
  18. % %
  19. % %
  20. % Copyright 1999-2006 ImageMagick Studio LLC, a non-profit organization %
  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. Include declarations.
  40. */
  41. #include "magick/studio.h"
  42. #include "magick/property.h"
  43. #include "magick/blob.h"
  44. #include "magick/color.h"
  45. #include "magick/exception.h"
  46. #include "magick/exception-private.h"
  47. #include "magick/geometry.h"
  48. #include "magick/list.h"
  49. #include "magick/log.h"
  50. #include "magick/memory_.h"
  51. #include "magick/option.h"
  52. #include "magick/resource_.h"
  53. #include "magick/semaphore.h"
  54. #include "magick/signature.h"
  55. #include "magick/statistic.h"
  56. #include "magick/string_.h"
  57. #include "magick/token.h"
  58. #include "magick/utility.h"
  59. /*
  60. Static declarations.
  61. */
  62. static const char
  63. Base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  64. /*
  65. Forward declaration.
  66. */
  67. static int
  68. IsDirectory(const char *);
  69. /*
  70. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  71. % %
  72. % %
  73. % %
  74. % A c q u i r e U n i q u e F i l e n a m e %
  75. % %
  76. % %
  77. % %
  78. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  79. %
  80. % AcquireUniqueFilename() replaces the contents of path by a unique path name.
  81. %
  82. % The format of the AcquireUniqueFilename method is:
  83. %
  84. % MagickBooleanType AcquireUniqueFilename(char *path)
  85. %
  86. % A description of each parameter follows.
  87. %
  88. % o path: Specifies a pointer to an array of characters. The unique path
  89. % name is returned in this array.
  90. %
  91. */
  92. MagickExport MagickBooleanType AcquireUniqueFilename(char *path)
  93. {
  94. int
  95. file;
  96. file=AcquireUniqueFileResource(path);
  97. if (file == -1)
  98. return(MagickFalse);
  99. file=close(file)-1;
  100. return(MagickTrue);
  101. }
  102. /*
  103. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  104. % %
  105. % %
  106. % %
  107. % A c q u i r e U n i q u e S ym b o l i c L i n k %
  108. % %
  109. % %
  110. % %
  111. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  112. %
  113. % AcquireUniqueSymbolicLink() creates a unique symbolic link to the specified
  114. % source path and returns MagickTrue on success otherwise MagickFalse. If the
  115. % symlink() method fails or is not available, a unique file name is generated
  116. % and the source file copied to it. When you are finished with the file, use
  117. % RelinquishUniqueFilename() to destroy it.
  118. %
  119. % The format of the AcquireUniqueSymbolicLink method is:
  120. %
  121. % MagickBooleanType AcquireUniqueSymbolicLink(const char *source,
  122. % char destination)
  123. %
  124. % A description of each parameter follows.
  125. %
  126. % o source: the source path.
  127. %
  128. % o destination: the destination path.
  129. %
  130. */
  131. MagickExport MagickBooleanType AcquireUniqueSymbolicLink(const char *source,
  132. char *destination)
  133. {
  134. int
  135. destination_file,
  136. source_file;
  137. size_t
  138. length,
  139. quantum;
  140. ssize_t
  141. count;
  142. struct stat
  143. file_info;
  144. unsigned char
  145. *buffer;
  146. assert(source != (const char *) NULL);
  147. assert(destination != (char *) NULL);
  148. #if defined(HAVE_SYMLINK)
  149. (void) AcquireUniqueFilename(destination);
  150. (void) RelinquishUniqueFileResource(destination);
  151. if (*source == *DirectorySeparator)
  152. {
  153. if (symlink(source,destination) == 0)
  154. return(MagickTrue);
  155. }
  156. else
  157. {
  158. char
  159. path[MaxTextExtent];
  160. *path='\0';
  161. if (getcwd(path,MaxTextExtent) == (char *) NULL)
  162. return(MagickFalse);
  163. (void) ConcatenateMagickString(path,DirectorySeparator,MaxTextExtent);
  164. (void) ConcatenateMagickString(path,source,MaxTextExtent);
  165. if (symlink(path,destination) == 0)
  166. return(MagickTrue);
  167. }
  168. #endif
  169. destination_file=AcquireUniqueFileResource(destination);
  170. if (destination_file == -1)
  171. return(MagickFalse);
  172. source_file=open(source,O_RDONLY | O_BINARY);
  173. if (source_file == -1)
  174. {
  175. (void) close(destination_file);
  176. (void) RelinquishUniqueFileResource(destination);
  177. return(MagickFalse);
  178. }
  179. quantum=(size_t) (fstat(source_file,&file_info) < 0 ? 0 :
  180. file_info.st_size);
  181. if ((quantum == 0) || (quantum > MagickMaxBufferSize))
  182. quantum=MagickMaxBufferSize;
  183. buffer=(unsigned char *) AcquireMagickMemory(quantum*sizeof(*buffer));
  184. if (buffer == (unsigned char *) NULL)
  185. {
  186. (void) close(source_file);
  187. (void) close(destination_file);
  188. (void) RelinquishUniqueFileResource(destination);
  189. return(MagickFalse);
  190. }
  191. for (length=0; ; )
  192. {
  193. count=read(source_file,buffer,quantum);
  194. if (count <= 0)
  195. break;
  196. length=(size_t) count;
  197. count=write(destination_file,buffer,length);
  198. if ((size_t) count != length)
  199. {
  200. (void) close(destination_file);
  201. (void) close(source_file);
  202. buffer=(unsigned char *) RelinquishMagickMemory(buffer);
  203. (void) RelinquishUniqueFileResource(destination);
  204. return(MagickFalse);
  205. }
  206. }
  207. (void) close(destination_file);
  208. (void) close(source_file);
  209. buffer=(unsigned char *) RelinquishMagickMemory(buffer);
  210. return(MagickTrue);
  211. }
  212. /*
  213. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  214. % %
  215. % %
  216. % %
  217. % A p p e n d I m a g e F o r m a t %
  218. % %
  219. % %
  220. % %
  221. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  222. %
  223. % AppendImageFormat() appends the image format type to the filename. If an
  224. % extension to the file already exists, it is first removed.
  225. %
  226. % The format of the AppendImageFormat method is:
  227. %
  228. % void AppendImageFormat(const char *format,char *filename)
  229. %
  230. % A description of each parameter follows.
  231. %
  232. % o format: Specifies a pointer to an array of characters. This is the
  233. % format of the image.
  234. %
  235. % o filename: Specifies a pointer to an array of characters. The unique
  236. % file name is returned in this array.
  237. %
  238. %
  239. */
  240. MagickExport void AppendImageFormat(const char *format,char *filename)
  241. {
  242. char
  243. root[MaxTextExtent];
  244. assert(format != (char *) NULL);
  245. assert(filename != (char *) NULL);
  246. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",filename);
  247. if ((*format == '\0') || (*filename == '\0'))
  248. return;
  249. if (LocaleCompare(filename,"-") == 0)
  250. {
  251. char
  252. message[MaxTextExtent];
  253. (void) FormatMagickString(message,MaxTextExtent,"%s:%s",format,filename);
  254. (void) CopyMagickString(filename,message,MaxTextExtent);
  255. return;
  256. }
  257. GetPathComponent(filename,RootPath,root);
  258. (void) FormatMagickString(filename,MaxTextExtent,"%s.%s",root,format);
  259. }
  260. /*
  261. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  262. % %
  263. % %
  264. % %
  265. % B a s e 6 4 D e c o d e %
  266. % %
  267. % %
  268. % %
  269. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  270. %
  271. % Base64Decode() decodes Base64-encoded text and returns its binary
  272. % equivalent. NULL is returned if the text is not valid Base64 data, or a
  273. % memory allocation failure occurs.
  274. %
  275. % Contributed by Bob Friesenhahn.
  276. %
  277. % The format of the Base64Decode method is:
  278. %
  279. % unsigned char *Base64Decode(const char *source,length_t *length)
  280. %
  281. % A description of each parameter follows:
  282. %
  283. % o source: A pointer to a Base64-encoded string.
  284. %
  285. % o length: The number of bytes decoded.
  286. %
  287. */
  288. MagickExport unsigned char *Base64Decode(const char *source,size_t *length)
  289. {
  290. int
  291. state;
  292. register const char
  293. *p,
  294. *q;
  295. register size_t
  296. i;
  297. size_t
  298. quantum;
  299. unsigned char
  300. *decode;
  301. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  302. assert(source != (char *) NULL);
  303. assert(length != (size_t *) NULL);
  304. *length=0;
  305. quantum=3*strlen(source)/4+1;
  306. decode=(unsigned char *) AcquireMagickMemory(quantum*sizeof(*decode));
  307. if (decode == (unsigned char *) NULL)
  308. return((unsigned char *) NULL);
  309. i=0;
  310. state=0;
  311. for (p=source; *p != '\0'; p++)
  312. {
  313. if (isspace((int) ((unsigned char) *p)) != 0)
  314. continue;
  315. if (*p == '=')
  316. break;
  317. q=strchr(Base64,*p);
  318. if (q == (char *) NULL)
  319. {
  320. decode=(unsigned char *) RelinquishMagickMemory(decode);
  321. return((unsigned char *) NULL); /* non-Base64 character */
  322. }
  323. switch (state)
  324. {
  325. case 0:
  326. {
  327. decode[i]=(q-Base64) << 2;
  328. state++;
  329. break;
  330. }
  331. case 1:
  332. {
  333. decode[i++]|=(q-Base64) >> 4;
  334. decode[i]=((q-Base64) & 0x0f) << 4;
  335. state++;
  336. break;
  337. }
  338. case 2:
  339. {
  340. decode[i++]|=(q-Base64) >> 2;
  341. decode[i]=((q-Base64) & 0x03) << 6;
  342. state++;
  343. break;
  344. }
  345. case 3:
  346. {
  347. decode[i++]|=(q-Base64);
  348. state=0;
  349. break;
  350. }
  351. }
  352. }
  353. /*
  354. Verify Base-64 string has proper terminal characters.
  355. */
  356. if (*p != '=')
  357. {
  358. if (state != 0)
  359. {
  360. decode=(unsigned char *) RelinquishMagickMemory(decode);
  361. return((unsigned char *) NULL);
  362. }
  363. }
  364. else
  365. {
  366. p++;
  367. switch (state)
  368. {
  369. case 0:
  370. case 1:
  371. {
  372. /*
  373. Unrecognized '=' character.
  374. */
  375. decode=(unsigned char *) RelinquishMagickMemory(decode);
  376. return((unsigned char *) NULL);
  377. }
  378. case 2:
  379. {
  380. for ( ; *p != '\0'; p++)
  381. if (isspace((int) ((unsigned char) *p)) == 0)
  382. break;
  383. if (*p != '=')
  384. {
  385. decode=(unsigned char *) RelinquishMagickMemory(decode);
  386. return((unsigned char *) NULL);
  387. }
  388. p++;
  389. }
  390. case 3:
  391. {
  392. for ( ; *p != '\0'; p++)
  393. if (isspace((int) ((unsigned char) *p)) == 0)
  394. {
  395. decode=(unsigned char *) RelinquishMagickMemory(decode);
  396. return((unsigned char *) NULL);
  397. }
  398. if ((int) decode[i] != 0)
  399. {
  400. decode=(unsigned char *) RelinquishMagickMemory(decode);
  401. return((unsigned char *) NULL);
  402. }
  403. }
  404. }
  405. }
  406. *length=i;
  407. assert(*length < quantum);
  408. return(decode);
  409. }
  410. /*
  411. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  412. % %
  413. % %
  414. % %
  415. % B a s e 6 4 E n c o d e %
  416. % %
  417. % %
  418. % %
  419. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  420. %
  421. % Base64Encode() encodes arbitrary binary data to Base64 encoded format as
  422. % described by the "Base64 Content-Transfer-Encoding" section of RFC 2045 and
  423. % returns the result as a null-terminated ASCII string. NULL is returned if
  424. % a memory allocation failure occurs.
  425. %
  426. % The format of the Base64Encode method is:
  427. %
  428. % char *Base64Encode(const unsigned char *blob,const size_t blob_length,
  429. % size_t *encode_length)
  430. %
  431. % A description of each parameter follows:
  432. %
  433. % o blob: A pointer to binary data to encode.
  434. %
  435. % o blob_length: The number of bytes to encode.
  436. %
  437. % o encode_length: The number of bytes encoded.
  438. %
  439. */
  440. MagickExport char *Base64Encode(const unsigned char *blob,
  441. const size_t blob_length,size_t *encode_length)
  442. {
  443. char
  444. *encode;
  445. register const unsigned char
  446. *p;
  447. register size_t
  448. i;
  449. size_t
  450. quantum,
  451. remainder;
  452. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  453. assert(blob != (const unsigned char *) NULL);
  454. assert(blob_length != 0);
  455. assert(encode_length != (size_t *) NULL);
  456. *encode_length=0;
  457. quantum=4*blob_length/3+4;
  458. encode=(char *) AcquireMagickMemory(quantum*sizeof(*encode));
  459. if (encode == (char *) NULL)
  460. return((char *) NULL);
  461. i=0;
  462. for (p=blob; p < (blob+blob_length-2); p+=3)
  463. {
  464. encode[i++]=Base64[(int) (*p >> 2)];
  465. encode[i++]=Base64[(int) (((*p & 0x03) << 4)+(*(p+1) >> 4))];
  466. encode[i++]=Base64[(int) (((*(p+1) & 0x0f) << 2)+(*(p+2) >> 6))];
  467. encode[i++]=Base64[(int) (*(p+2) & 0x3f)];
  468. }
  469. remainder=blob_length % 3;
  470. if (remainder != 0)
  471. {
  472. long
  473. j;
  474. unsigned char
  475. code[3];
  476. code[0]='\0';
  477. code[1]='\0';
  478. code[2]='\0';
  479. for (j=0; j < (long) remainder; j++)
  480. code[j]=(*p++);
  481. encode[i++]=Base64[(int) (code[0] >> 2)];
  482. encode[i++]=Base64[(int) (((code[0] & 0x03) << 4)+(code[1] >> 4))];
  483. if (remainder == 1)
  484. encode[i++]='=';
  485. else
  486. encode[i++]=Base64[(int) (((code[1] & 0x0f) << 2)+(code[2] >> 6))];
  487. encode[i++]='=';
  488. }
  489. *encode_length=i;
  490. encode[i++]='\0';
  491. assert(i <= quantum);
  492. return(encode);
  493. }
  494. /*
  495. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  496. % %
  497. % %
  498. % %
  499. % C h o p P a t h C o m p o n e n t s %
  500. % %
  501. % %
  502. % %
  503. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  504. %
  505. % ChopPathComponents() removes the number of specified file components from a
  506. % path.
  507. %
  508. % The format of the ChopPathComponents method is:
  509. %
  510. % ChopPathComponents(char *path,unsigned long components)
  511. %
  512. % A description of each parameter follows:
  513. %
  514. % o path: The path.
  515. %
  516. % o components: The number of components to chop.
  517. %
  518. */
  519. MagickExport void ChopPathComponents(char *path,const unsigned long components)
  520. {
  521. register long
  522. i;
  523. for (i=0; i < (long) components; i++)
  524. GetPathComponent(path,HeadPath,path);
  525. }
  526. /*
  527. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  528. % %
  529. % %
  530. % %
  531. % E x p a n d F i l e n a m e %
  532. % %
  533. % %
  534. % %
  535. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  536. %
  537. % ExpandFilename() expands '~' in a path.
  538. %
  539. % The format of the ExpandFilename function is:
  540. %
  541. % ExpandFilename(char *path)
  542. %
  543. % A description of each parameter follows:
  544. %
  545. % o path: Specifies a pointer to a character array that contains the
  546. % path.
  547. %
  548. %
  549. */
  550. MagickExport void ExpandFilename(char *path)
  551. {
  552. char
  553. expanded_path[MaxTextExtent];
  554. if (path == (char *) NULL)
  555. return;
  556. if (*path != '~')
  557. return;
  558. (void) CopyMagickString(expanded_path,path,MaxTextExtent);
  559. if ((*(path+1) == *DirectorySeparator) || (*(path+1) == '\0'))
  560. {
  561. char
  562. *home;
  563. /*
  564. Substitute ~ with $HOME.
  565. */
  566. (void) CopyMagickString(expanded_path,".",MaxTextExtent);
  567. (void) ConcatenateMagickString(expanded_path,path+1,MaxTextExtent);
  568. home=GetEnvironmentValue("HOME");
  569. if (home == (char *) NULL)
  570. home=GetEnvironmentValue("USERPROFILE");
  571. if (home != (char *) NULL)
  572. {
  573. (void) CopyMagickString(expanded_path,home,MaxTextExtent);
  574. (void) ConcatenateMagickString(expanded_path,path+1,MaxTextExtent);
  575. home=(char *) RelinquishMagickMemory(home);
  576. }
  577. }
  578. else
  579. {
  580. #if defined(POSIX)
  581. char
  582. username[MaxTextExtent];
  583. register char
  584. *p;
  585. struct passwd
  586. *entry;
  587. /*
  588. Substitute ~ with home directory from password file.
  589. */
  590. (void) CopyMagickString(username,path+1,MaxTextExtent);
  591. p=strchr(username,'/');
  592. if (p != (char *) NULL)
  593. *p='\0';
  594. entry=getpwnam(username);
  595. if (entry == (struct passwd *) NULL)
  596. return;
  597. (void) CopyMagickString(expanded_path,entry->pw_dir,MaxTextExtent);
  598. if (p != (char *) NULL)
  599. {
  600. (void) ConcatenateMagickString(expanded_path,"/",MaxTextExtent);
  601. (void) ConcatenateMagickString(expanded_path,p+1,MaxTextExtent);
  602. }
  603. #endif
  604. }
  605. (void) CopyMagickString(path,expanded_path,MaxTextExtent);
  606. }
  607. /*
  608. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  609. % %
  610. % %
  611. % %
  612. % E x p a n d F i l e n a m e s %
  613. % %
  614. % %
  615. % %
  616. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  617. %
  618. % ExpandFilenames() checks each argument of the command line vector and
  619. % expands it if they have a wildcard character. For example, *.jpg might
  620. % expand to: bird.jpg rose.jpg tiki.jpg.
  621. %
  622. % The format of the ExpandFilenames function is:
  623. %
  624. % status=ExpandFilenames(int *argc,char ***argv)
  625. %
  626. % A description of each parameter follows:
  627. %
  628. % o argc: Specifies a pointer to an integer describing the number of
  629. % elements in the argument vector.
  630. %
  631. % o argv: Specifies a pointer to a text array containing the command line
  632. % arguments.
  633. %
  634. */
  635. MagickExport MagickBooleanType ExpandFilenames(int *argc,char ***argv)
  636. {
  637. char
  638. **filelist,
  639. filename[MaxTextExtent],
  640. home_directory[MaxTextExtent],
  641. magick[MaxTextExtent],
  642. *option,
  643. path[MaxTextExtent],
  644. subimage[MaxTextExtent],
  645. **vector;
  646. long
  647. count,
  648. parameters;
  649. register long
  650. i,
  651. j;
  652. unsigned long
  653. number_files;
  654. /*
  655. Allocate argument vector.
  656. */
  657. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
  658. assert(argc != (int *) NULL);
  659. assert(argv != (char ***) NULL);
  660. for (i=1; i < (long) *argc; i++)
  661. if (strlen((*argv)[i]) > (MaxTextExtent/2-1))
  662. ThrowMagickFatalException(ResourceLimitFatalError,
  663. "TokenLengthExceedsLimit",(*argv)[i]);
  664. vector=(char **) AcquireMagickMemory((*argc+1)*sizeof(*vector));
  665. if (vector == (char **) NULL)
  666. return(MagickFalse);
  667. /*
  668. Expand any wildcard filenames.
  669. */
  670. if (getcwd(home_directory,MaxTextExtent) == (char *) NULL)
  671. return(MagickFalse);
  672. count=0;
  673. for (i=0; i < (long) *argc; i++)
  674. {
  675. option=(*argv)[i];
  676. vector[count++]=ConstantString(option);
  677. parameters=ParseMagickOption(MagickCommandOptions,MagickFalse,option);
  678. if (parameters > 0)
  679. {
  680. /*
  681. Do not expand command option parameters.
  682. */
  683. for (j=0; j < parameters; j++)
  684. {
  685. i++;
  686. if (i == (long) *argc)
  687. break;
  688. option=(*argv)[i];
  689. vector[count++]=ConstantString(option);
  690. }
  691. continue;
  692. }
  693. if ((*option == '"') || (*option == '\''))
  694. continue;
  695. GetPathComponent(option,TailPath,filename);
  696. if (IsGlob(filename) == MagickFalse)
  697. continue;
  698. GetPathComponent(option,MagickPath,magick);
  699. if ((LocaleCompare(magick,"CAPTION") == 0) ||
  700. (LocaleCompare(magick,"LABEL") == 0) ||
  701. (LocaleCompare(magick,"VID") == 0))
  702. continue;
  703. GetPathComponent(option,HeadPath,path);
  704. GetPathComponent(option,SubimagePath,subimage);
  705. ExpandFilename(path);
  706. filelist=ListFiles(*path == '\0' ? home_directory : path,filename,
  707. &number_files);
  708. if (filelist == (char **) NULL)
  709. continue;
  710. for (j=0; j < (long) number_files; j++)
  711. if (IsDirectory(filelist[j]) <= 0)
  712. break;
  713. if (j == (long) number_files)
  714. {
  715. for (j=0; j < (long) number_files; j++)
  716. filelist[j]=(char *) RelinquishMagickMemory(filelist[j]);
  717. filelist=(char **) RelinquishMagickMemory(filelist);
  718. continue;
  719. }
  720. /*
  721. Transfer file list to argument vector.
  722. */
  723. vector=(char **) ResizeMagickMemory(vector,(size_t) (*argc+count+
  724. number_files+1)*sizeof(*vector));
  725. if (vector == (char **) NULL)
  726. return(MagickFalse);
  727. count--;
  728. for (j=0; j < (long) number_files; j++)
  729. {
  730. (void) CopyMagickString(filename,path,MaxTextExtent);
  731. if (*path != '\0')
  732. (void) ConcatenateMagickString(filename,DirectorySeparator,
  733. MaxTextExtent);
  734. (void) ConcatenateMagickString(filename,filelist[j],MaxTextExtent);
  735. filelist[j]=(char *) RelinquishMagickMemory(filelist[j]);
  736. if (IsAccessible(filename) != MagickFalse)
  737. {
  738. char
  739. path[MaxTextExtent];
  740. *path='\0';
  741. if (*magick != '\0')
  742. {
  743. (void) ConcatenateMagickString(path,magick,MaxTextExtent);
  744. (void) ConcatenateMagickString(path,":",MaxTextExtent);
  745. }
  746. (void) ConcatenateMagickString(path,filename,MaxTextExtent);
  747. if (*subimage != '\0')
  748. {
  749. (void) ConcatenateMagickString(path,"[",MaxTextExtent);
  750. (void) ConcatenateMagickString(path,subimage,MaxTextExtent);
  751. (void) ConcatenateMagickString(path,"]",MaxTextExtent);
  752. }
  753. vector[count++]=ConstantString(path);
  754. }
  755. }
  756. filelist=(char **) RelinquishMagickMemory(filelist);
  757. }
  758. vector[count]=(char *) NULL;
  759. if (IsEventLogging() != MagickFalse)
  760. {
  761. char
  762. *command_line;
  763. command_line=AcquireString(vector[0]);
  764. for (i=1; i < count; i++)
  765. {
  766. (void) ConcatenateString(&command_line,"{");
  767. (void) ConcatenateString(&command_line,vector[i]);
  768. (void) ConcatenateString(&command_line,"}");
  769. }
  770. (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
  771. "Command line: %s",command_line);
  772. command_line=(char *) RelinquishMagickMemory(command_line);
  773. }
  774. *argc=(int) count;
  775. *argv=vector;
  776. return(MagickTrue);
  777. }
  778. /*
  779. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  780. % %
  781. % %
  782. % %
  783. % G e t E x e c u t i o n P a t h %
  784. % %
  785. % %
  786. % %
  787. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  788. %
  789. % GetExecutionPath() returns the pathname of the executable that started
  790. % the process. On success MagickTrue is returned, otherwise MagickFalse.
  791. %
  792. % The format of the GetExecutionPath method is:
  793. %
  794. % MagickBooleanType GetExecutionPath(char *path)
  795. %
  796. % A description of each parameter follows:
  797. %
  798. % o path: The pathname of the executable that started the process.
  799. %
  800. */
  801. MagickExport MagickBooleanType GetExecutionPath(char *path)
  802. {
  803. *path='\0';
  804. if (getcwd(path,MaxTextExtent) == (char *) NULL)
  805. return(MagickFalse);
  806. #if defined(__WINDOWS__)
  807. return(NTGetExecutionPath(path));
  808. #endif
  809. #if defined(HAVE_GETEXECNAME)
  810. {
  811. const char
  812. *execution_path;
  813. execution_path=(const char *) getexecname();
  814. if (execution_path != (const char *) NULL)
  815. {
  816. if (*execution_path != *DirectorySeparator)
  817. (void) ConcatenateMagickString(path,DirectorySeparator,MaxTextExtent);
  818. (void) ConcatenateMagickString(path,execution_path,MaxTextExtent);
  819. }
  820. }
  821. #endif
  822. return(MagickTrue);
  823. }
  824. /*
  825. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  826. % %
  827. % %
  828. % %
  829. % G e t P a t h C o m p o n e n t %
  830. % %
  831. % %
  832. % %
  833. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  834. %
  835. % GetPathComponent() returns the parent directory name, filename, basename, or
  836. % extension of a file path.
  837. %
  838. % The format of the GetPathComponent function is:
  839. %
  840. % GetPathComponent(const char *path,PathType type,char *component)
  841. %
  842. % A description of each parameter follows:
  843. %
  844. % o path: Specifies a pointer to a character array that contains the
  845. % file path.
  846. %
  847. % o type: Specififies which file path component to return.
  848. %
  849. % o component: The selected file path component is returned here.
  850. %
  851. */
  852. MagickExport void GetPathComponent(const char *path,PathType type,
  853. char *component)
  854. {
  855. char
  856. magick[MaxTextExtent],
  857. *q,
  858. subimage[MaxTextExtent];
  859. register char
  860. *p;
  861. assert(path != (const char *) NULL);
  862. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",path);
  863. assert(component != (char *) NULL);
  864. if (*path == '\0')
  865. {
  866. *component='\0';
  867. return;
  868. }
  869. (void) CopyMagickString(component,path,MaxTextExtent);
  870. *magick='\0';
  871. for (p=component; *p != '\0'; p++)
  872. if ((*p == ':') && (IsDirectory(path) < 0) &&
  873. (IsAccessible(path) == MagickFalse))
  874. {
  875. /*
  876. Look for image format specification (e.g. ps3:image).
  877. */
  878. (void) CopyMagickString(magick,component,(size_t) (p-component+1));
  879. if (IsMagickConflict(magick) != MagickFalse)
  880. *magick='\0';
  881. else
  882. for (q=component; *q != '\0'; q++)
  883. *q=(*++p);
  884. break;
  885. }
  886. *subimage='\0';
  887. p=component;
  888. if (*p != '\0')
  889. p=component+strlen(component)-1;
  890. if ((*p == ']') && (strchr(component,'[') != (char *) NULL))
  891. {
  892. /*
  893. Look for scene specification (e.g. img0001.pcd[4]).
  894. */
  895. for (q=p-1; q > component; q--)
  896. if (*q == '[')
  897. break;
  898. if (*q == '[')
  899. {
  900. (void) CopyMagickString(subimage,q+1,MaxTextExtent);
  901. subimage[p-q-1]='\0';
  902. if ((IsSceneGeometry(subimage,MagickFalse) == MagickFalse) &&
  903. (IsGeometry(subimage) == MagickFalse))
  904. *subimage='\0';
  905. else
  906. *q='\0';
  907. }
  908. }
  909. p=component;
  910. if (*p != '\0')
  911. for (p=component+strlen(component)-1; p > component; p--)
  912. if (IsBasenameSeparator(*p) != MagickFalse)
  913. break;
  914. switch (type)
  915. {
  916. case MagickPath:
  917. {
  918. (void) CopyMagickString(component,magick,MaxTextExtent);
  919. break;
  920. }
  921. case RootPath:
  922. {
  923. for (p=component+(strlen(component)-1); p > component; p--)
  924. {
  925. if (IsBasenameSeparator(*p) != MagickFalse)
  926. break;
  927. if (*p == '.')
  928. break;
  929. }
  930. if (*p == '.')
  931. *p='\0';
  932. break;
  933. }
  934. case HeadPath:
  935. {
  936. *p='\0';
  937. break;
  938. }
  939. case TailPath:
  940. {
  941. if (IsBasenameSeparator(*p) != MagickFalse)
  942. (void) CopyMagickMemory((unsigned char *) component,
  943. (const unsigned char *) (p+1),strlen(p+1)+1);
  944. break;
  945. }
  946. case BasePath:
  947. {
  948. if (IsBasenameSeparator(*p) != MagickFalse)
  949. (void) CopyMagickString(component,p+1,MaxTextExtent);
  950. for (p=component+(strlen(component)-1); p > component; p--)
  951. if (*p == '.')
  952. {
  953. *p='\0';
  954. break;
  955. }
  956. break;
  957. }
  958. case ExtensionPath:
  959. {
  960. if (IsBasenameSeparator(*p) != MagickFalse)
  961. (void) CopyMagickString(component,p+1,MaxTextExtent);
  962. p=component;
  963. if (*p != '\0')
  964. for (p=component+strlen(component)-1; p > component; p--)
  965. if (*p == '.')
  966. break;
  967. *component='\0';
  968. if (*p == '.')
  969. (void) CopyMagickString(component,p+1,MaxTextExtent);
  970. break;
  971. }
  972. case SubimagePath:
  973. {
  974. (void) CopyMagickString(component,subimage,MaxTextExtent);
  975. break;
  976. }
  977. case CanonicalPath:
  978. case UndefinedPath:
  979. break;
  980. }
  981. }
  982. /*
  983. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  984. % %
  985. % %
  986. % %
  987. % G e t P a t h C o m p o n e n t s %
  988. % %
  989. % %
  990. % %
  991. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  992. %
  993. % GetPathComponents() returns a list of path components.
  994. %
  995. % The format of the GetPathComponents method is:
  996. %
  997. % char **GetPathComponents(const char *path,
  998. % unsigned long *number_componenets)
  999. %
  1000. % A description of each parameter follows:
  1001. %
  1002. % o path: Specifies the string to segment into a list.
  1003. %
  1004. % o number_components: return the number of components in the list
  1005. %
  1006. */
  1007. MagickExport char **GetPathComponents(const char *path,
  1008. unsigned long *number_components)
  1009. {
  1010. char
  1011. **components;
  1012. register char
  1013. *q;
  1014. register const char
  1015. *p;
  1016. register long
  1017. i;
  1018. if (path == (char *) NULL)
  1019. return((char **) NULL);
  1020. *number_components=1;
  1021. for (p=path; *p != '\0'; p++)
  1022. if (IsBasenameSeparator(*p))
  1023. (*number_components)++;
  1024. components=(char **)
  1025. AcquireMagickMemory((size_t) (*number_components+1)*sizeof(*components));
  1026. if (components == (char **) NULL)
  1027. {
  1028. char
  1029. *message;
  1030. message=GetExceptionMessage(errno);
  1031. ThrowMagickFatalException(ResourceLimitFatalError,
  1032. "memory allocation failed `%s'",message);
  1033. message=(char *) RelinquishMagickMemory(message);
  1034. }
  1035. p=path;
  1036. for (i=0; i < (long) *number_components; i++)
  1037. {
  1038. for (q=(char *) p; *q != '\0'; q++)
  1039. if (IsBasenameSeparator(*q))
  1040. break;
  1041. components[i]=(char *) AcquireMagickMemory(((q-p)+MaxTextExtent)*
  1042. sizeof(*components));
  1043. if (components[i] == (char *) NULL)
  1044. {
  1045. char
  1046. *message;
  1047. message=GetExceptionMessage(errno);
  1048. ThrowMagickFatalException(ResourceLimitFatalError,
  1049. "MemoryAllocationFailed",message);
  1050. message=(char *) RelinquishMagickMemory(message);
  1051. }
  1052. (void) CopyMagickString(components[i],p,(size_t) (q-p+1));
  1053. p=q+1;
  1054. }
  1055. components[i]=(char *) NULL;
  1056. return(components);
  1057. }
  1058. /*
  1059. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1060. % %
  1061. % %
  1062. % %
  1063. % I s A c c e s s i b l e %
  1064. % %
  1065. % %
  1066. % %
  1067. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1068. %
  1069. % IsAccessible() returns MagickTrue if the file as defined by the path is
  1070. % accessible.
  1071. %
  1072. % The format of the IsAccessible method is:
  1073. %
  1074. % MagickBooleanType IsAccessible(const char *filename)
  1075. %
  1076. % A description of each parameter follows.
  1077. %
  1078. % o path: Specifies a path to a file.
  1079. %
  1080. %
  1081. */
  1082. MagickExport MagickBooleanType IsAccessible(const char *path)
  1083. {
  1084. int
  1085. status;
  1086. struct stat
  1087. file_info;
  1088. if ((path == (const char *) NULL) || (*path == '\0'))
  1089. return(MagickFalse);
  1090. status=stat(path,&file_info);
  1091. if (status != 0)
  1092. return(MagickFalse);
  1093. if (S_ISREG(file_info.st_mode) == 0)
  1094. return(MagickFalse);
  1095. if (access(path,F_OK) != 0)
  1096. return(MagickFalse);
  1097. return(MagickTrue);
  1098. }
  1099. /*
  1100. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1101. % %
  1102. % %
  1103. % %
  1104. + I s D i r e c t o r y %
  1105. % %
  1106. % %
  1107. % %
  1108. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1109. %
  1110. % IsDirectory() returns -1 if the directory does not exist, 1 is returned
  1111. % if the path represents a directory otherwise 0.
  1112. %
  1113. % The format of the IsAccessible method is:
  1114. %
  1115. % int IsDirectory(const char *path)
  1116. %
  1117. % A description of each parameter follows.
  1118. %
  1119. % o path: The directory path.
  1120. %
  1121. %
  1122. */
  1123. static int IsDirectory(const char *path)
  1124. {
  1125. #if !defined(X_OK)
  1126. #define X_OK 1
  1127. #endif
  1128. int
  1129. status;
  1130. struct stat
  1131. file_info;
  1132. if ((path == (const char *) NULL) || (*path == '\0'))
  1133. return(MagickFalse);
  1134. status=stat(path,&file_info);
  1135. if (status != 0)
  1136. return(-1);
  1137. if (S_ISDIR(file_info.st_mode) == 0)
  1138. return(0);
  1139. if (access(path,X_OK) != 0)
  1140. return(0);
  1141. return(1);
  1142. }
  1143. /*
  1144. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1145. % %
  1146. % %
  1147. % %
  1148. % I s M a g i c k T r u e %
  1149. % %
  1150. % %
  1151. % %
  1152. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1153. %
  1154. % IsMagickTrue() returns MagickTrue if the value is "true", "on", "yes" or
  1155. % "1".
  1156. %
  1157. % The format of the IsMagickTrue method is:
  1158. %
  1159. % MagickBooleanType IsMagickTrue(const char *value)
  1160. %
  1161. % A description of each parameter follows:
  1162. %
  1163. % o option: either MagickTrue or MagickFalse depending on the value
  1164. % parameter.
  1165. %
  1166. % o value: Specifies a pointer to a character array.
  1167. %
  1168. */
  1169. MagickExport MagickBooleanType IsMagickTrue(const char *value)
  1170. {
  1171. if (value == (char *) NULL)
  1172. return(MagickFalse);
  1173. if (LocaleCompare(value,"true") == 0)
  1174. return(MagickTrue);
  1175. if (LocaleCompare(value,"on") == 0)
  1176. return(MagickTrue);
  1177. if (LocaleCompare(value,"yes") == 0)
  1178. return(MagickTrue);
  1179. if (LocaleCompare(value,"1") == 0)
  1180. return(MagickTrue);
  1181. return(MagickFalse);
  1182. }
  1183. /*
  1184. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1185. % %
  1186. % %
  1187. % %
  1188. % L i s t F i l e s %
  1189. % %
  1190. % %
  1191. % %
  1192. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1193. %
  1194. % ListFiles() reads the directory specified and returns a list of filenames
  1195. % contained in the directory sorted in ascending alphabetic order.
  1196. %
  1197. % The format of the ListFiles function is:
  1198. %
  1199. % char **ListFiles(const char *directory,const char *pattern,
  1200. % long *number_entries)
  1201. %
  1202. % A description of each parameter follows:
  1203. %
  1204. % o filelist: Method ListFiles returns a list of filenames contained
  1205. % in the directory. If the directory specified cannot be read or it is
  1206. % a file a NULL list is returned.
  1207. %
  1208. % o directory: Specifies a pointer to a text string containing a directory
  1209. % name.
  1210. %
  1211. % o pattern: Specifies a pointer to a text string containing a pattern.
  1212. %
  1213. % o number_entries: This integer returns the number of filenames in the
  1214. % list.
  1215. %
  1216. %
  1217. */
  1218. #if defined(__cplusplus) || defined(c_plusplus)
  1219. extern "C" {
  1220. #endif
  1221. static int FileCompare(const void *x,const void *y)
  1222. {
  1223. register const char
  1224. **p,
  1225. **q;
  1226. p=(const char **) x;
  1227. q=(const char **) y;
  1228. return(LocaleCompare(*p,*q));
  1229. }
  1230. #if defined(__cplusplus) || defined(c_plusplus)
  1231. }
  1232. #endif
  1233. MagickExport char **ListFiles(const char *directory,const char *pattern,
  1234. unsigned long *number_entries)
  1235. {
  1236. char
  1237. **filelist;
  1238. DIR
  1239. *current_directory;
  1240. struct dirent
  1241. *entry;
  1242. unsigned long
  1243. max_entries;
  1244. /*
  1245. Open directory.
  1246. */
  1247. assert(directory != (const char *) NULL);
  1248. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",directory);
  1249. assert(pattern != (const char *) NULL);
  1250. assert(number_entries != (unsigned long *) NULL);
  1251. *number_entries=0;
  1252. current_directory=opendir(directory);
  1253. if (current_directory == (DIR *) NULL)
  1254. return((char **) NULL);
  1255. /*
  1256. Allocate filelist.
  1257. */
  1258. max_entries=2048;
  1259. filelist=(char **) AcquireMagickMemory((size_t)
  1260. max_entries*sizeof(*filelist));
  1261. if (filelist == (char **) NULL)
  1262. {
  1263. (void) closedir(current_directory);
  1264. return((char **) NULL);
  1265. }
  1266. /*
  1267. Save the current and change to the new directory.
  1268. */
  1269. entry=readdir(current_directory);
  1270. while (entry != (struct dirent *) NULL)
  1271. {
  1272. if (*entry->d_name == '.')
  1273. {
  1274. entry=readdir(current_directory);
  1275. continue;
  1276. }
  1277. if ((IsDirectory(entry->d_name) > 0) ||
  1278. (GlobExpression(entry->d_name,pattern) != MagickFalse))
  1279. {
  1280. if (*number_entries >= max_entries)
  1281. {
  1282. /*
  1283. Extend the file list.
  1284. */
  1285. max_entries<<=1;
  1286. filelist=(char **) ResizeMagickMemory(filelist,(size_t)
  1287. max_entries*sizeof(*filelist));
  1288. if (filelist == (char **) NULL)
  1289. {
  1290. (void) closedir(current_directory);
  1291. return((char **) NULL);
  1292. }
  1293. }
  1294. #if defined(vms)
  1295. {
  1296. register char
  1297. *p;
  1298. p=strchr(entry->d_name,';');
  1299. if (p)
  1300. *p='\0';
  1301. if (*number_entries > 0)
  1302. if (LocaleCompare(entry->d_name,filelist[*number_entries-1]) == 0)
  1303. {
  1304. entry=readdir(current_directory);
  1305. continue;
  1306. }
  1307. }
  1308. #endif
  1309. filelist[*number_entries]=(char *) AcquireString(entry->d_name);
  1310. if (IsDirectory(entry->d_name) > 0)
  1311. (void) ConcatenateMagickString(filelist[*number_entries],
  1312. DirectorySeparator,MaxTextExtent);
  1313. (*number_entries)++;
  1314. }
  1315. entry=readdir(current_directory);
  1316. }
  1317. (void) closedir(current_directory);
  1318. /*
  1319. Sort filelist in ascending order.
  1320. */
  1321. qsort((void *) filelist,(size_t) *number_entries,sizeof(*filelist),
  1322. FileCompare);
  1323. return(filelist);
  1324. }
  1325. /*
  1326. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1327. % %
  1328. % %
  1329. % %
  1330. % M a g i c k O p e n S t r e a m %
  1331. % %
  1332. % %
  1333. % %
  1334. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1335. %
  1336. % MagickOpenStream() opens the file whose name is the string pointed to by
  1337. % path and associates a stream with it.
  1338. %
  1339. % The path of the MagickOpenStream method is:
  1340. %
  1341. % FILE *MagickOpenStream(const char *path,const char *mode)
  1342. %
  1343. % A description of each parameter follows.
  1344. %
  1345. % o path: the file path.
  1346. %
  1347. % o mode: the file mode.
  1348. %
  1349. */
  1350. MagickExport FILE *MagickOpenStream(const char *path,const char *mode)
  1351. {
  1352. FILE
  1353. *file;
  1354. file=fopen(path,mode);
  1355. #if defined(__WINDOWS__)
  1356. if (file == (FILE *) NULL)
  1357. {
  1358. register long
  1359. i;
  1360. wchar_t
  1361. wide_mode[MaxTextExtent],
  1362. wide_path[MaxTextExtent];
  1363. /*
  1364. Perhaps this is a UTF-8 encoded filename.
  1365. */
  1366. for (i=0; i < strlen(path); i++)
  1367. wide_path[i]=path[i];
  1368. wide_path[i]=0;
  1369. for (i=0; i < strlen(mode); i++)
  1370. wide_mode[i]=mode[i];
  1371. wide_mode[i]=0;
  1372. file=_wfopen(wide_path,wide_mode);
  1373. }
  1374. #endif
  1375. return(file);
  1376. }
  1377. /*
  1378. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1379. % %
  1380. % %
  1381. % %
  1382. % M u l t i l i n e C e n s u s %
  1383. % %
  1384. % %
  1385. % %
  1386. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1387. %
  1388. % MultilineCensus() returns the number of lines within a label. A line is
  1389. % represented by a \n character.
  1390. %
  1391. % The format of the MultilineCenus method is:
  1392. %
  1393. % unsigned long MultilineCensus(const char *label)
  1394. %
  1395. % A description of each parameter follows.
  1396. %
  1397. % o label: This character string is the label.
  1398. %
  1399. %
  1400. */
  1401. MagickExport unsigned long MultilineCensus(const char *label)
  1402. {
  1403. unsigned long
  1404. number_lines;
  1405. /*
  1406. Determine the number of lines within this label.
  1407. */
  1408. if (label == (char *) NULL)
  1409. return(0);
  1410. for (number_lines=1; *label != '\0'; label++)
  1411. if (*label == '\n')
  1412. number_lines++;
  1413. return(number_lines);
  1414. }
  1415. /*
  1416. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1417. % %
  1418. % %
  1419. % %
  1420. % S y s t e m C o m m a n d %
  1421. % %
  1422. % %
  1423. % %
  1424. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  1425. %
  1426. % SystemCommand() executes the specified command and waits until it
  1427. % terminates. The returned value is the exit status of the command.
  1428. %
  1429. % The format of the SystemCommand method is:
  1430. %
  1431. % int SystemCommand(const MagickBooleanType verbose,const char *command)
  1432. %
  1433. % A description of each parameter follows:
  1434. %
  1435. % o verbose: An MagickBooleanType other than 0 prints the executed command
  1436. % before it is invoked.
  1437. %
  1438. % o command: This string is the command to execute.
  1439. %
  1440. %
  1441. */
  1442. MagickExport int SystemCommand(const MagickBooleanType verbose,
  1443. const char *command)
  1444. {
  1445. int
  1446. status;
  1447. if (verbose != MagickFalse)
  1448. (void) fprintf(stdout,"%s\n",command);
  1449. #if defined(POSIX)
  1450. status=system(command);
  1451. #elif defined(__WINDOWS__)
  1452. status=NTSystemCommand(command);
  1453. #elif defined(macintosh)
  1454. status=MACSystemCommand(command);
  1455. #elif defined(vms)
  1456. status=system(command);
  1457. #else
  1458. # error No suitable system() method.
  1459. #endif
  1460. if (status < 0)
  1461. {
  1462. char
  1463. *message;
  1464. ExceptionInfo
  1465. exception;
  1466. GetExceptionInfo(&exception);
  1467. message=GetExceptionMessage(errno);
  1468. (void) ThrowMagickException(&exception,GetMagickModule(),DelegateError,
  1469. "`%s': %s",command,message);
  1470. message=(char *) RelinquishMagickMemory(message);
  1471. CatchException(&exception);
  1472. (void) DestroyExceptionInfo(&exception);
  1473. }
  1474. return(status);
  1475. }