PageRenderTime 59ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 1ms

/plugins/ImageMagick-6.3.2/coders/pnm.c

https://bitbucket.org/sisko/operation-caribou
C | 1614 lines | 1295 code | 52 blank | 267 comment | 493 complexity | ae20bb2a47ebf2dc1f81cf135705b95a MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-2.1

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3. % %
  4. % %
  5. % %
  6. % PPPP N N M M %
  7. % P P NN N MM MM %
  8. % PPPP N N N M M M %
  9. % P N NN M M %
  10. % P N N M M %
  11. % %
  12. % %
  13. % Read/Write PBMPlus Portable Anymap Image Format. %
  14. % %
  15. % Software Design %
  16. % John Cristy %
  17. % July 1992 %
  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/blob.h"
  43. #include "magick/blob-private.h"
  44. #include "magick/color.h"
  45. #include "magick/color-private.h"
  46. #include "magick/colorspace.h"
  47. #include "magick/exception.h"
  48. #include "magick/exception-private.h"
  49. #include "magick/image.h"
  50. #include "magick/image-private.h"
  51. #include "magick/list.h"
  52. #include "magick/magick.h"
  53. #include "magick/memory_.h"
  54. #include "magick/monitor.h"
  55. #include "magick/property.h"
  56. #include "magick/quantum.h"
  57. #include "magick/static.h"
  58. #include "magick/statistic.h"
  59. #include "magick/string_.h"
  60. /*
  61. Forward declarations.
  62. */
  63. static MagickBooleanType
  64. WritePNMImage(const ImageInfo *,Image *);
  65. /*
  66. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  67. % %
  68. % %
  69. % %
  70. % I s P N M %
  71. % %
  72. % %
  73. % %
  74. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  75. %
  76. % IsPNM() returns MagickTrue if the image format type, identified by the
  77. % magick string, is PNM.
  78. %
  79. % The format of the IsPNM method is:
  80. %
  81. % MagickBooleanType IsPNM(const unsigned char *magick,const size_t length)
  82. %
  83. % A description of each parameter follows:
  84. %
  85. % o magick: This string is generally the first few bytes of an image file
  86. % or blob.
  87. %
  88. % o length: Specifies the length of the magick string.
  89. %
  90. %
  91. */
  92. static MagickBooleanType IsPNM(const unsigned char *magick,const size_t length)
  93. {
  94. if (length < 2)
  95. return(MagickFalse);
  96. if ((*magick == (unsigned char) 'P') &&
  97. (isdigit((int) magick[1]) != MagickFalse))
  98. return(MagickTrue);
  99. return(MagickFalse);
  100. }
  101. /*
  102. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  103. % %
  104. % %
  105. % %
  106. % R e a d P N M I m a g e %
  107. % %
  108. % %
  109. % %
  110. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  111. %
  112. % ReadPNMImage() reads a Portable Anymap image file and returns it.
  113. % It allocates the memory necessary for the new Image structure and returns
  114. % a pointer to the new image.
  115. %
  116. % The format of the ReadPNMImage method is:
  117. %
  118. % Image *ReadPNMImage(const ImageInfo *image_info,ExceptionInfo *exception)
  119. %
  120. % A description of each parameter follows:
  121. %
  122. % o image_info: The image info.
  123. %
  124. % o exception: return any errors or warnings in this structure.
  125. %
  126. %
  127. */
  128. static unsigned long PNMInteger(Image *image,const unsigned int base)
  129. {
  130. char
  131. *comment;
  132. int
  133. c;
  134. register char
  135. *p;
  136. size_t
  137. length;
  138. unsigned long
  139. value;
  140. /*
  141. Skip any leading whitespace.
  142. */
  143. length=MaxTextExtent;
  144. comment=(char *) NULL;
  145. p=comment;
  146. do
  147. {
  148. c=ReadBlobByte(image);
  149. if (c == EOF)
  150. return(0);
  151. if (c == (int) '#')
  152. {
  153. /*
  154. Read comment.
  155. */
  156. if (comment == (char *) NULL)
  157. comment=AcquireString((char *) NULL);
  158. p=comment+strlen(comment);
  159. for ( ; (c != EOF) && (c != (int) '\n'); p++)
  160. {
  161. if ((size_t) (p-comment+1) >= length)
  162. {
  163. length<<=1;
  164. comment=(char *) ResizeMagickMemory(comment,
  165. (length+MaxTextExtent)*sizeof(*comment));
  166. if (comment == (char *) NULL)
  167. break;
  168. p=comment+strlen(comment);
  169. }
  170. c=ReadBlobByte(image);
  171. *p=(char) c;
  172. *(p+1)='\0';
  173. }
  174. if (comment == (char *) NULL)
  175. return(0);
  176. continue;
  177. }
  178. } while (isdigit(c) == MagickFalse);
  179. if (comment != (char *) NULL)
  180. {
  181. (void) SetImageProperty(image,"Comment",comment);
  182. comment=(char *) RelinquishMagickMemory(comment);
  183. }
  184. if (base == 2)
  185. return((unsigned long) (c-(int) '0'));
  186. /*
  187. Evaluate number.
  188. */
  189. value=0;
  190. do
  191. {
  192. value*=10;
  193. value+=c-(int) '0';
  194. c=ReadBlobByte(image);
  195. if (c == EOF)
  196. return(value);
  197. }
  198. while (isdigit(c) != MagickFalse);
  199. return(value);
  200. }
  201. static Image *ReadPNMImage(const ImageInfo *image_info,ExceptionInfo *exception)
  202. {
  203. #define PushCharPixel(pixel,p) \
  204. { \
  205. pixel=(unsigned long) (*(p)); \
  206. (p)++; \
  207. }
  208. #define PushShortPixel(pixel,p) \
  209. { \
  210. pixel=(unsigned long) ((*(p) << 8) | *((p)+1)); \
  211. (p)+=2; \
  212. }
  213. char
  214. format;
  215. Image
  216. *image;
  217. long
  218. y;
  219. MagickBooleanType
  220. grayscale,
  221. status;
  222. Quantum
  223. *scale;
  224. register IndexPacket
  225. *indexes;
  226. register long
  227. x;
  228. register PixelPacket
  229. *q;
  230. register long
  231. i;
  232. register unsigned char
  233. *p;
  234. size_t
  235. length,
  236. packet_size;
  237. ssize_t
  238. count;
  239. unsigned char
  240. *pixels;
  241. unsigned long
  242. index,
  243. max_value;
  244. /*
  245. Open image file.
  246. */
  247. assert(image_info != (const ImageInfo *) NULL);
  248. assert(image_info->signature == MagickSignature);
  249. if (image_info->debug != MagickFalse)
  250. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
  251. image_info->filename);
  252. assert(exception != (ExceptionInfo *) NULL);
  253. assert(exception->signature == MagickSignature);
  254. image=AllocateImage(image_info);
  255. status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
  256. if (status == MagickFalse)
  257. {
  258. image=DestroyImageList(image);
  259. return((Image *) NULL);
  260. }
  261. /*
  262. Read PNM image.
  263. */
  264. count=ReadBlob(image,1,(unsigned char *) &format);
  265. do
  266. {
  267. /*
  268. Initialize image structure.
  269. */
  270. if ((count != 1) || (format != 'P'))
  271. ThrowReaderException(CorruptImageError,"ImproperImageHeader");
  272. max_value=1;
  273. grayscale=MagickFalse;
  274. format=(char) ReadBlobByte(image);
  275. if (format != '7')
  276. {
  277. /*
  278. PBM, PGM, PPM, and PNM.
  279. */
  280. image->columns=PNMInteger(image,10);
  281. image->rows=PNMInteger(image,10);
  282. if ((format == '1') || (format == '4'))
  283. max_value=1; /* bitmap */
  284. else
  285. max_value=PNMInteger(image,10);
  286. if ((format != '3') && (format != '6'))
  287. {
  288. image->storage_class=PseudoClass;
  289. image->colors=(unsigned long) (max_value >= MaxColormapSize ?
  290. MaxColormapSize : max_value+1);
  291. }
  292. }
  293. else
  294. {
  295. char
  296. keyword[MaxTextExtent],
  297. value[MaxTextExtent];
  298. int
  299. c;
  300. register char
  301. *p;
  302. /*
  303. PAM.
  304. */
  305. for (c=ReadBlobByte(image); c != EOF; c=ReadBlobByte(image))
  306. {
  307. while (isspace((int) ((unsigned char) c)) != 0)
  308. c=ReadBlobByte(image);
  309. p=keyword;
  310. do
  311. {
  312. if ((size_t) (p-keyword) < (MaxTextExtent/2))
  313. *p++=c;
  314. c=ReadBlobByte(image);
  315. } while (isalnum(c));
  316. *p='\0';
  317. if (LocaleCompare(keyword,"endhdr") == 0)
  318. break;
  319. while (isspace((int) ((unsigned char) c)) != 0)
  320. c=ReadBlobByte(image);
  321. p=value;
  322. while (isalnum(c) || (c == '_'))
  323. {
  324. if ((size_t) (p-value) < (MaxTextExtent/2))
  325. *p++=c;
  326. c=ReadBlobByte(image);
  327. }
  328. *p='\0';
  329. /*
  330. Assign a value to the specified keyword.
  331. */
  332. if (LocaleCompare(keyword,"depth") == 0)
  333. packet_size=(unsigned long) atol(value);
  334. if (LocaleCompare(keyword,"height") == 0)
  335. image->rows=(unsigned long) atol(value);
  336. if (LocaleCompare(keyword,"maxval") == 0)
  337. max_value=(unsigned long) atol(value);
  338. if (LocaleCompare(keyword,"TUPLTYPE") == 0)
  339. {
  340. if (LocaleCompare(value,"BLACKANDWHITE") == 0)
  341. grayscale=MagickTrue;
  342. if (LocaleCompare(value,"BLACKANDWHITE_ALPHA") == 0)
  343. {
  344. grayscale=MagickTrue;
  345. image->matte=MagickTrue;
  346. }
  347. if (LocaleCompare(value,"GRAYSCALE") == 0)
  348. grayscale=MagickTrue;
  349. if (LocaleCompare(value,"GRAYSCALE_ALPHA") == 0)
  350. {
  351. grayscale=MagickTrue;
  352. image->matte=MagickTrue;
  353. }
  354. if (LocaleCompare(value,"RGB_ALPHA") == 0)
  355. image->matte=MagickTrue;
  356. if (LocaleCompare(value,"CMYK") == 0)
  357. image->colorspace=CMYKColorspace;
  358. if (LocaleCompare(value,"CMYK_ALPHA") == 0)
  359. image->matte=MagickTrue;
  360. }
  361. if (LocaleCompare(keyword,"width") == 0)
  362. image->columns=(unsigned long) atol(value);
  363. }
  364. }
  365. if ((image->columns == 0) || (image->rows == 0))
  366. ThrowReaderException(CorruptImageError,"NegativeOrZeroImageSize");
  367. if (max_value >= 65536)
  368. ThrowReaderException(CorruptImageError,"ImproperImageHeader");
  369. for (image->depth=1; (1UL << image->depth) < max_value; image->depth++);
  370. scale=(Quantum *) NULL;
  371. if (image->storage_class == PseudoClass)
  372. if (AllocateImageColormap(image,image->colors) == MagickFalse)
  373. ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
  374. if ((image->storage_class != PseudoClass) || (max_value > QuantumRange))
  375. {
  376. /*
  377. Compute pixel scaling table.
  378. */
  379. scale=(Quantum *) AcquireMagickMemory((size_t) (max_value+1)*
  380. sizeof(*scale));
  381. if (scale == (Quantum *) NULL)
  382. ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
  383. for (i=0; i <= (long) max_value; i++)
  384. scale[i]=ScaleAnyToQuantum((unsigned long) i,max_value);
  385. }
  386. if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0))
  387. if (image->scene >= (image_info->scene+image_info->number_scenes-1))
  388. break;
  389. /*
  390. Convert PNM pixels to runlength-encoded MIFF packets.
  391. */
  392. switch (format)
  393. {
  394. case '1':
  395. {
  396. /*
  397. Convert PBM image to pixel packets.
  398. */
  399. for (y=0; y < (long) image->rows; y++)
  400. {
  401. q=SetImagePixels(image,0,y,image->columns,1);
  402. if (q == (PixelPacket *) NULL)
  403. break;
  404. indexes=GetIndexes(image);
  405. for (x=0; x < (long) image->columns; x++)
  406. {
  407. index=(IndexPacket) (PNMInteger(image,2) == 0);
  408. if ((unsigned long) index >= image->colors)
  409. {
  410. (void) ThrowMagickException(&image->exception,GetMagickModule(),
  411. CorruptImageError,"InvalidColormapIndex","`%s'",
  412. image->filename);
  413. index=0;
  414. }
  415. indexes[x]=(IndexPacket) index;
  416. *q++=image->colormap[index];
  417. }
  418. if (SyncImagePixels(image) == MagickFalse)
  419. break;
  420. if (image->previous == (Image *) NULL)
  421. if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
  422. (QuantumTick(y,image->rows) != MagickFalse))
  423. {
  424. status=image->progress_monitor(LoadImageTag,y,image->rows,
  425. image->client_data);
  426. if (status == MagickFalse)
  427. break;
  428. }
  429. }
  430. break;
  431. }
  432. case '2':
  433. {
  434. unsigned long
  435. intensity;
  436. /*
  437. Convert PGM image to pixel packets.
  438. */
  439. for (y=0; y < (long) image->rows; y++)
  440. {
  441. q=SetImagePixels(image,0,y,image->columns,1);
  442. if (q == (PixelPacket *) NULL)
  443. break;
  444. indexes=GetIndexes(image);
  445. for (x=0; x < (long) image->columns; x++)
  446. {
  447. intensity=PNMInteger(image,10);
  448. if (scale != (Quantum *) NULL)
  449. intensity=scale[intensity];
  450. index=(IndexPacket) intensity;
  451. if ((unsigned long) index >= image->colors)
  452. {
  453. (void) ThrowMagickException(&image->exception,GetMagickModule(),
  454. CorruptImageError,"InvalidColormapIndex","`%s'",
  455. image->filename);
  456. index=0;
  457. }
  458. indexes[x]=(IndexPacket) index;
  459. *q++=image->colormap[index];
  460. }
  461. if (SyncImagePixels(image) == MagickFalse)
  462. break;
  463. if (image->previous == (Image *) NULL)
  464. if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
  465. (QuantumTick(y,image->rows) != MagickFalse))
  466. {
  467. status=image->progress_monitor(LoadImageTag,y,image->rows,
  468. image->client_data);
  469. if (status == MagickFalse)
  470. break;
  471. }
  472. }
  473. break;
  474. }
  475. case '3':
  476. {
  477. LongPixelPacket
  478. pixel;
  479. /*
  480. Convert PNM image to pixel packets.
  481. */
  482. for (y=0; y < (long) image->rows; y++)
  483. {
  484. q=SetImagePixels(image,0,y,image->columns,1);
  485. if (q == (PixelPacket *) NULL)
  486. break;
  487. for (x=0; x < (long) image->columns; x++)
  488. {
  489. pixel.red=PNMInteger(image,10);
  490. pixel.green=PNMInteger(image,10);
  491. pixel.blue=PNMInteger(image,10);
  492. if (scale != (Quantum *) NULL)
  493. {
  494. pixel.red=scale[pixel.red];
  495. pixel.green=scale[pixel.green];
  496. pixel.blue=scale[pixel.blue];
  497. }
  498. q->red=(Quantum) pixel.red;
  499. q->green=(Quantum) pixel.green;
  500. q->blue=(Quantum) pixel.blue;
  501. q++;
  502. }
  503. if (SyncImagePixels(image) == MagickFalse)
  504. break;
  505. if (image->previous == (Image *) NULL)
  506. if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
  507. (QuantumTick(y,image->rows) != MagickFalse))
  508. {
  509. status=image->progress_monitor(LoadImageTag,y,image->rows,
  510. image->client_data);
  511. if (status == MagickFalse)
  512. break;
  513. }
  514. }
  515. break;
  516. }
  517. case '4':
  518. {
  519. unsigned long
  520. bit,
  521. byte;
  522. /*
  523. Convert PBM raw image to pixel packets.
  524. */
  525. for (y=0; y < (long) image->rows; y++)
  526. {
  527. q=SetImagePixels(image,0,y,image->columns,1);
  528. if (q == (PixelPacket *) NULL)
  529. break;
  530. indexes=GetIndexes(image);
  531. bit=0;
  532. byte=0;
  533. for (x=0; x < (long) image->columns; x++)
  534. {
  535. if (bit == 0)
  536. byte=(unsigned long) ReadBlobByte(image);
  537. index=(IndexPacket) ((byte & 0x80) != 0 ? 0x00 : 0x01);
  538. indexes[x]=(IndexPacket) index;
  539. *q++=image->colormap[index];
  540. bit++;
  541. if (bit == 8)
  542. bit=0;
  543. byte<<=1;
  544. }
  545. if (SyncImagePixels(image) == MagickFalse)
  546. break;
  547. if (image->previous == (Image *) NULL)
  548. if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
  549. (QuantumTick(y,image->rows) != MagickFalse))
  550. {
  551. status=image->progress_monitor(LoadImageTag,y,image->rows,
  552. image->client_data);
  553. if (status == MagickFalse)
  554. break;
  555. }
  556. }
  557. if (EOFBlob(image) != MagickFalse)
  558. ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
  559. image->filename);
  560. break;
  561. }
  562. case '5':
  563. {
  564. /*
  565. Convert PGM raw image to pixel packets.
  566. */
  567. packet_size=(size_t) (image->depth <= 8 ? 1 : 2);
  568. length=packet_size*image->columns;
  569. pixels=(unsigned char *) AcquireMagickMemory(length*sizeof(*pixels));
  570. if (pixels == (unsigned char *) NULL)
  571. ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
  572. for (y=0; y < (long) image->rows; y++)
  573. {
  574. count=ReadBlob(image,length,pixels);
  575. if (count != (ssize_t) length)
  576. ThrowReaderException(CorruptImageError,"UnableToReadImageData");
  577. p=pixels;
  578. q=SetImagePixels(image,0,y,image->columns,1);
  579. if (q == (PixelPacket *) NULL)
  580. break;
  581. indexes=GetIndexes(image);
  582. if (image->depth <= 8)
  583. for (x=0; x < (long) image->columns; x++)
  584. {
  585. index=(IndexPacket) (*p++);
  586. if ((unsigned long) index >= image->colors)
  587. {
  588. (void) ThrowMagickException(&image->exception,
  589. GetMagickModule(),CorruptImageError,"InvalidColormapIndex",
  590. "`%s'",image->filename);
  591. index=0;
  592. }
  593. indexes[x]=(IndexPacket) index;
  594. *q++=image->colormap[index];
  595. }
  596. else
  597. for (x=0; x < (long) image->columns; x++)
  598. {
  599. PushShortPixel(index,p);
  600. if (index >= image->colors)
  601. {
  602. (void) ThrowMagickException(&image->exception,
  603. GetMagickModule(),CorruptImageError,"InvalidColormapIndex",
  604. "`%s'",image->filename);
  605. index=0;
  606. }
  607. indexes[x]=(IndexPacket) index;
  608. *q++=image->colormap[index];
  609. }
  610. if (SyncImagePixels(image) == MagickFalse)
  611. break;
  612. if (image->previous == (Image *) NULL)
  613. if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
  614. (QuantumTick(y,image->rows) != MagickFalse))
  615. {
  616. status=image->progress_monitor(LoadImageTag,y,image->rows,
  617. image->client_data);
  618. if (status == MagickFalse)
  619. break;
  620. }
  621. }
  622. pixels=(unsigned char *) RelinquishMagickMemory(pixels);
  623. if (EOFBlob(image) != MagickFalse)
  624. (void) ThrowMagickException(exception,GetMagickModule(),
  625. CorruptImageError,"UnexpectedEndOfFile","`%s'",image->filename);
  626. break;
  627. }
  628. case '6':
  629. {
  630. LongPixelPacket
  631. pixel;
  632. /*
  633. Convert PNM raster image to pixel packets.
  634. */
  635. packet_size=(size_t) (image->depth <= 8 ? 3 : 6);
  636. if (image->colorspace == CMYKColorspace)
  637. packet_size+=(size_t) (image->depth <= 8 ? 1 : 2);
  638. pixels=(unsigned char *) AcquireMagickMemory(packet_size*
  639. image->columns*sizeof(*pixels));
  640. if (pixels == (unsigned char *) NULL)
  641. ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
  642. (void) ResetMagickMemory(&pixel,0,sizeof(LongPixelPacket));
  643. for (y=0; y < (long) image->rows; y++)
  644. {
  645. count=ReadBlob(image,packet_size*image->columns,pixels);
  646. if (count != (ssize_t) (packet_size*image->columns))
  647. ThrowReaderException(CorruptImageError,"UnableToReadImageData");
  648. p=pixels;
  649. q=SetImagePixels(image,0,y,image->columns,1);
  650. if (q == (PixelPacket *) NULL)
  651. break;
  652. if (image->depth <= 8)
  653. for (x=0; x < (long) image->columns; x++)
  654. {
  655. PushCharPixel(pixel.red,p);
  656. PushCharPixel(pixel.green,p);
  657. PushCharPixel(pixel.blue,p);
  658. if (scale != (Quantum *) NULL)
  659. {
  660. pixel.red=scale[pixel.red];
  661. pixel.green=scale[pixel.green];
  662. pixel.blue=scale[pixel.blue];
  663. }
  664. q->red=(Quantum) pixel.red;
  665. q->green=(Quantum) pixel.green;
  666. q->blue=(Quantum) pixel.blue;
  667. q++;
  668. }
  669. else
  670. for (x=0; x < (long) image->columns; x++)
  671. {
  672. PushShortPixel(pixel.red,p);
  673. PushShortPixel(pixel.green,p);
  674. PushShortPixel(pixel.blue,p);
  675. if (scale != (Quantum *) NULL)
  676. {
  677. pixel.red=scale[pixel.red];
  678. pixel.green=scale[pixel.green];
  679. pixel.blue=scale[pixel.blue];
  680. }
  681. q->red=(Quantum) pixel.red;
  682. q->green=(Quantum) pixel.green;
  683. q->blue=(Quantum) pixel.blue;
  684. q++;
  685. }
  686. if (SyncImagePixels(image) == MagickFalse)
  687. break;
  688. if (image->previous == (Image *) NULL)
  689. if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
  690. (QuantumTick(y,image->rows) != MagickFalse))
  691. {
  692. status=image->progress_monitor(LoadImageTag,y,image->rows,
  693. image->client_data);
  694. if (status == MagickFalse)
  695. break;
  696. }
  697. }
  698. pixels=(unsigned char *) RelinquishMagickMemory(pixels);
  699. if (EOFBlob(image) != MagickFalse)
  700. (void) ThrowMagickException(exception,GetMagickModule(),
  701. CorruptImageError,"UnexpectedEndOfFile","`%s'",image->filename);
  702. break;
  703. }
  704. case '7':
  705. {
  706. IndexPacket
  707. *indexes;
  708. unsigned long
  709. pixel;
  710. /*
  711. Convert PNM raster image to pixel packets.
  712. */
  713. packet_size=3;
  714. if (grayscale != MagickFalse)
  715. packet_size=1;
  716. if (image->matte != MagickFalse)
  717. packet_size++;
  718. if (image->colorspace == CMYKColorspace)
  719. packet_size++;
  720. if (image->depth > 8)
  721. packet_size*=2;
  722. length=packet_size*image->columns*sizeof(*pixels);
  723. pixels=(unsigned char *) AcquireMagickMemory(length);
  724. if (pixels == (unsigned char *) NULL)
  725. ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
  726. for (y=0; y < (long) image->rows; y++)
  727. {
  728. count=ReadBlob(image,packet_size*image->columns,pixels);
  729. if (count != (ssize_t) (packet_size*image->columns))
  730. ThrowReaderException(CorruptImageError,"UnableToReadImageData");
  731. p=pixels;
  732. q=SetImagePixels(image,0,y,image->columns,1);
  733. if (q == (PixelPacket *) NULL)
  734. break;
  735. indexes=GetIndexes(image);
  736. if (grayscale != MagickFalse)
  737. {
  738. if (image->depth <= 8)
  739. for (x=0; x < (long) image->columns; x++)
  740. {
  741. PushCharPixel(pixel,p);
  742. q->red=ScaleAnyToQuantum(pixel,(1UL << image->depth)-1);
  743. q->green=q->red;
  744. q->blue=q->red;
  745. if (image->colorspace == CMYKColorspace)
  746. {
  747. PushCharPixel(pixel,p);
  748. indexes[x]=(IndexPacket) ScaleAnyToQuantum(pixel,
  749. (1UL << image->depth)-1);
  750. }
  751. if (image->matte != MagickFalse)
  752. {
  753. PushCharPixel(pixel,p);
  754. q->opacity=QuantumRange-ScaleAnyToQuantum(pixel,
  755. (1UL << image->depth)-1);
  756. }
  757. q++;
  758. }
  759. else
  760. for (x=0; x < (long) image->columns; x++)
  761. {
  762. PushShortPixel(pixel,p);
  763. q->red=ScaleAnyToQuantum(pixel,(1UL << image->depth)-1);
  764. q->green=q->red;
  765. q->blue=q->red;
  766. if (image->colorspace == CMYKColorspace)
  767. {
  768. PushShortPixel(pixel,p);
  769. indexes[x]=(IndexPacket) ScaleAnyToQuantum(pixel,
  770. (1UL << image->depth)-1);
  771. }
  772. if (image->matte != MagickFalse)
  773. {
  774. PushShortPixel(pixel,p);
  775. q->opacity=QuantumRange-ScaleAnyToQuantum(pixel,
  776. (1UL << image->depth)-1);
  777. }
  778. q++;
  779. }
  780. }
  781. else
  782. if (image->depth <= 8)
  783. for (x=0; x < (long) image->columns; x++)
  784. {
  785. PushCharPixel(pixel,p);
  786. q->red=ScaleAnyToQuantum(pixel,(1UL << image->depth)-1);
  787. PushCharPixel(pixel,p);
  788. q->green=ScaleAnyToQuantum(pixel,(1UL << image->depth)-1);
  789. PushCharPixel(pixel,p);
  790. q->blue=ScaleAnyToQuantum(pixel,(1UL << image->depth)-1);
  791. if (image->colorspace == CMYKColorspace)
  792. {
  793. PushCharPixel(pixel,p);
  794. indexes[x]=(IndexPacket) ScaleAnyToQuantum(pixel,
  795. (1UL << image->depth)-1);
  796. }
  797. if (image->matte != MagickFalse)
  798. {
  799. PushCharPixel(pixel,p);
  800. q->opacity=QuantumRange-ScaleAnyToQuantum(pixel,
  801. (1UL << image->depth)-1);
  802. }
  803. q++;
  804. }
  805. else
  806. for (x=0; x < (long) image->columns; x++)
  807. {
  808. PushShortPixel(pixel,p);
  809. q->red=ScaleAnyToQuantum(pixel,(1UL << image->depth)-1);
  810. PushShortPixel(pixel,p);
  811. q->green=ScaleAnyToQuantum(pixel,(1UL << image->depth)-1);
  812. PushShortPixel(pixel,p);
  813. q->blue=ScaleAnyToQuantum(pixel,(1UL << image->depth)-1);
  814. if (image->colorspace == CMYKColorspace)
  815. {
  816. PushShortPixel(pixel,p);
  817. indexes[x]=(IndexPacket) ScaleAnyToQuantum(pixel,
  818. (1UL << image->depth)-1);
  819. }
  820. if (image->matte != MagickFalse)
  821. {
  822. PushShortPixel(pixel,p);
  823. q->opacity=QuantumRange-ScaleAnyToQuantum(pixel,
  824. (1UL << image->depth)-1);
  825. }
  826. q++;
  827. }
  828. if (SyncImagePixels(image) == MagickFalse)
  829. break;
  830. if (image->previous == (Image *) NULL)
  831. if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
  832. (QuantumTick(y,image->rows) != MagickFalse))
  833. {
  834. status=image->progress_monitor(LoadImageTag,y,image->rows,
  835. image->client_data);
  836. if (status == MagickFalse)
  837. break;
  838. }
  839. }
  840. pixels=(unsigned char *) RelinquishMagickMemory(pixels);
  841. if (EOFBlob(image) != MagickFalse)
  842. (void) ThrowMagickException(exception,GetMagickModule(),
  843. CorruptImageError,"UnexpectedEndOfFile","`%s'",image->filename);
  844. break;
  845. }
  846. default:
  847. ThrowReaderException(CorruptImageError,"ImproperImageHeader");
  848. }
  849. if (scale != (Quantum *) NULL)
  850. scale=(Quantum *) RelinquishMagickMemory(scale);
  851. /*
  852. Proceed to next image.
  853. */
  854. if (image_info->number_scenes != 0)
  855. if (image->scene >= (image_info->scene+image_info->number_scenes-1))
  856. break;
  857. if ((format == '1') || (format == '2') || (format == '3'))
  858. do
  859. {
  860. /*
  861. Skip to end of line.
  862. */
  863. count=ReadBlob(image,1,(unsigned char *) &format);
  864. if (count == 0)
  865. break;
  866. if ((count != 0) && (format == 'P'))
  867. break;
  868. } while (format != '\n');
  869. count=ReadBlob(image,1,(unsigned char *) &format);
  870. if ((count == 1) && (format == 'P'))
  871. {
  872. /*
  873. Allocate next image structure.
  874. */
  875. AllocateNextImage(image_info,image);
  876. if (GetNextImageInList(image) == (Image *) NULL)
  877. {
  878. image=DestroyImageList(image);
  879. return((Image *) NULL);
  880. }
  881. image=SyncNextImageInList(image);
  882. if (image->progress_monitor != (MagickProgressMonitor) NULL)
  883. {
  884. status=image->progress_monitor(LoadImagesTag,TellBlob(image),
  885. GetBlobSize(image),image->client_data);
  886. if (status == MagickFalse)
  887. break;
  888. }
  889. }
  890. } while ((count == 1) && (format == 'P'));
  891. CloseBlob(image);
  892. return(GetFirstImageInList(image));
  893. }
  894. /*
  895. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  896. % %
  897. % %
  898. % %
  899. % R e g i s t e r P N M I m a g e %
  900. % %
  901. % %
  902. % %
  903. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  904. %
  905. % RegisterPNMImage() adds properties for the PNM image format to
  906. % the list of supported formats. The properties include the image format
  907. % tag, a method to read and/or write the format, whether the format
  908. % supports the saving of more than one frame to the same file or blob,
  909. % whether the format supports native in-memory I/O, and a brief
  910. % description of the format.
  911. %
  912. % The format of the RegisterPNMImage method is:
  913. %
  914. % RegisterPNMImage(void)
  915. %
  916. */
  917. ModuleExport void RegisterPNMImage(void)
  918. {
  919. MagickInfo
  920. *entry;
  921. entry=SetMagickInfo("PAM");
  922. entry->decoder=(DecoderHandler *) ReadPNMImage;
  923. entry->encoder=(EncoderHandler *) WritePNMImage;
  924. entry->description=ConstantString("Common 2-dimensional bitmap format");
  925. entry->module=ConstantString("PNM");
  926. (void) RegisterMagickInfo(entry);
  927. entry=SetMagickInfo("PBM");
  928. entry->decoder=(DecoderHandler *) ReadPNMImage;
  929. entry->encoder=(EncoderHandler *) WritePNMImage;
  930. entry->description=ConstantString("Portable bitmap format (black and white)");
  931. entry->module=ConstantString("PNM");
  932. (void) RegisterMagickInfo(entry);
  933. entry=SetMagickInfo("PGM");
  934. entry->decoder=(DecoderHandler *) ReadPNMImage;
  935. entry->encoder=(EncoderHandler *) WritePNMImage;
  936. entry->description=ConstantString("Portable graymap format (gray scale)");
  937. entry->module=ConstantString("PNM");
  938. (void) RegisterMagickInfo(entry);
  939. entry=SetMagickInfo("PNM");
  940. entry->decoder=(DecoderHandler *) ReadPNMImage;
  941. entry->encoder=(EncoderHandler *) WritePNMImage;
  942. entry->magick=(MagickHandler *) IsPNM;
  943. entry->description=ConstantString("Portable anymap");
  944. entry->module=ConstantString("PNM");
  945. (void) RegisterMagickInfo(entry);
  946. entry=SetMagickInfo("PPM");
  947. entry->decoder=(DecoderHandler *) ReadPNMImage;
  948. entry->encoder=(EncoderHandler *) WritePNMImage;
  949. entry->description=ConstantString("Portable pixmap format (color)");
  950. entry->module=ConstantString("PNM");
  951. (void) RegisterMagickInfo(entry);
  952. }
  953. /*
  954. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  955. % %
  956. % %
  957. % %
  958. % U n r e g i s t e r P N M I m a g e %
  959. % %
  960. % %
  961. % %
  962. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  963. %
  964. % UnregisterPNMImage() removes format registrations made by the
  965. % PNM module from the list of supported formats.
  966. %
  967. % The format of the UnregisterPNMImage method is:
  968. %
  969. % UnregisterPNMImage(void)
  970. %
  971. */
  972. ModuleExport void UnregisterPNMImage(void)
  973. {
  974. (void) UnregisterMagickInfo("PAM");
  975. (void) UnregisterMagickInfo("PBM");
  976. (void) UnregisterMagickInfo("PGM");
  977. (void) UnregisterMagickInfo("PNM");
  978. (void) UnregisterMagickInfo("PPM");
  979. }
  980. /*
  981. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  982. % %
  983. % %
  984. % %
  985. % W r i t e P N M I m a g e %
  986. % %
  987. % %
  988. % %
  989. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  990. %
  991. % Procedure WritePNMImage() writes an image to a file in the PNM rasterfile
  992. % format.
  993. %
  994. % The format of the WritePNMImage method is:
  995. %
  996. % MagickBooleanType WritePNMImage(const ImageInfo *image_info,Image *image)
  997. %
  998. % A description of each parameter follows.
  999. %
  1000. % o image_info: The image info.
  1001. %
  1002. % o image: The image.
  1003. %
  1004. %
  1005. */
  1006. static MagickBooleanType WritePNMImage(const ImageInfo *image_info,Image *image)
  1007. {
  1008. #define PopCharPixel(pixel,p) \
  1009. { \
  1010. *(q)=(unsigned char) pixel; \
  1011. (q)++; \
  1012. }
  1013. #define PopShortPixel(pixel,p) \
  1014. { \
  1015. *(q)=(unsigned char) (pixel >> 8); \
  1016. (q)++; \
  1017. *(q)=(unsigned char) pixel; \
  1018. (q)++; \
  1019. }
  1020. char
  1021. buffer[MaxTextExtent];
  1022. const char
  1023. *value;
  1024. IndexPacket
  1025. index;
  1026. int
  1027. format;
  1028. long
  1029. y;
  1030. MagickBooleanType
  1031. grayscale,
  1032. status;
  1033. MagickOffsetType
  1034. scene;
  1035. register const PixelPacket
  1036. *p;
  1037. register IndexPacket
  1038. *indexes;
  1039. register long
  1040. i,
  1041. x;
  1042. register unsigned char
  1043. *q;
  1044. size_t
  1045. length,
  1046. packet_size;
  1047. unsigned char
  1048. *pixels;
  1049. unsigned long
  1050. depth;
  1051. /*
  1052. Open output image file.
  1053. */
  1054. assert(image_info != (const ImageInfo *) NULL);
  1055. assert(image_info->signature == MagickSignature);
  1056. assert(image != (Image *) NULL);
  1057. assert(image->signature == MagickSignature);
  1058. if (image->debug != MagickFalse)
  1059. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
  1060. status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
  1061. if (status == MagickFalse)
  1062. return(status);
  1063. scene=0;
  1064. do
  1065. {
  1066. /*
  1067. Write PNM file header.
  1068. */
  1069. if (image_info->colorspace == UndefinedColorspace)
  1070. (void) SetImageColorspace(image,RGBColorspace);
  1071. grayscale=IsGrayImage(image,&image->exception);
  1072. depth=image->depth;
  1073. format=6;
  1074. if (LocaleCompare(image_info->magick,"PAM") == 0)
  1075. format=7;
  1076. else
  1077. if (LocaleCompare(image_info->magick,"PGM") == 0)
  1078. format=5;
  1079. else
  1080. if (LocaleCompare(image_info->magick,"PBM") == 0)
  1081. format=4;
  1082. else
  1083. if ((LocaleCompare(image_info->magick,"PNM") == 0) &&
  1084. (image_info->type != TrueColorType) && (grayscale != MagickFalse))
  1085. {
  1086. format=5;
  1087. if (IsMonochromeImage(image,&image->exception) != MagickFalse)
  1088. format=4;
  1089. }
  1090. if ((image->compression == NoCompression) && (format != 7))
  1091. format-=3;
  1092. (void) FormatMagickString(buffer,MaxTextExtent,"P%d\n",format);
  1093. (void) WriteBlobString(image,buffer);
  1094. value=GetImageProperty(image,"Comment");
  1095. if (value != (const char *) NULL)
  1096. {
  1097. register const char
  1098. *p;
  1099. /*
  1100. Write comments to file.
  1101. */
  1102. (void) WriteBlobByte(image,'#');
  1103. for (p=value; *p != '\0'; p++)
  1104. {
  1105. (void) WriteBlobByte(image,(unsigned char) *p);
  1106. if ((*p == '\r') && (*(p+1) != '\0'))
  1107. (void) WriteBlobByte(image,'#');
  1108. if ((*p == '\n') && (*(p+1) != '\0'))
  1109. (void) WriteBlobByte(image,'#');
  1110. }
  1111. (void) WriteBlobByte(image,'\n');
  1112. }
  1113. if (format != 7)
  1114. {
  1115. (void) FormatMagickString(buffer,MaxTextExtent,"%lu %lu\n",
  1116. image->columns,image->rows);
  1117. (void) WriteBlobString(image,buffer);
  1118. }
  1119. else
  1120. {
  1121. char
  1122. type[MaxTextExtent];
  1123. unsigned long
  1124. extent;
  1125. /*
  1126. PAM header.
  1127. */
  1128. (void) FormatMagickString(buffer,MaxTextExtent,
  1129. "WIDTH %lu\nHEIGHT %lu\n",image->columns,image->rows);
  1130. (void) WriteBlobString(image,buffer);
  1131. packet_size=3;
  1132. (void) CopyMagickString(type,"RGB",MaxTextExtent);
  1133. if (grayscale != MagickFalse)
  1134. {
  1135. packet_size=1;
  1136. (void) CopyMagickString(type,"GRAYSCALE",MaxTextExtent);
  1137. if (IsMonochromeImage(image,&image->exception))
  1138. (void) CopyMagickString(type,"BLACKANDWHITE",MaxTextExtent);
  1139. }
  1140. if (image->matte != MagickFalse)
  1141. {
  1142. packet_size++;
  1143. (void) ConcatenateMagickString(type,"_ALPHA",MaxTextExtent);
  1144. }
  1145. if (depth > 16)
  1146. depth=16;
  1147. extent=(1UL << depth)-1;
  1148. (void) FormatMagickString(buffer,MaxTextExtent,
  1149. "DEPTH %lu\nMAXVAL %lu\n",(unsigned long) packet_size,extent);
  1150. (void) WriteBlobString(image,buffer);
  1151. (void) FormatMagickString(buffer,MaxTextExtent,"TUPLTYPE %s\nENDHDR\n",
  1152. type);
  1153. (void) WriteBlobString(image,buffer);
  1154. }
  1155. /*
  1156. Convert runlength encoded to PNM raster pixels.
  1157. */
  1158. switch (format)
  1159. {
  1160. case 1:
  1161. {
  1162. /*
  1163. Convert image to a PBM image.
  1164. */
  1165. (void) SetImageType(image,BilevelType);
  1166. i=0;
  1167. for (y=0; y < (long) image->rows; y++)
  1168. {
  1169. p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
  1170. if (p == (const PixelPacket *) NULL)
  1171. break;
  1172. indexes=GetIndexes(image);
  1173. for (x=0; x < (long) image->columns; x++)
  1174. {
  1175. (void) FormatMagickString(buffer,MaxTextExtent,"%u ",
  1176. PixelIntensity(p) < (QuantumRange/2.0) ? 0x01 : 0x00);
  1177. (void) WriteBlobString(image,buffer);
  1178. i++;
  1179. if (i == 36)
  1180. {
  1181. (void) WriteBlobByte(image,'\n');
  1182. i=0;
  1183. }
  1184. p++;
  1185. }
  1186. if (image->previous == (Image *) NULL)
  1187. if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
  1188. (QuantumTick(y,image->rows) != MagickFalse))
  1189. {
  1190. status=image->progress_monitor(SaveImageTag,y,image->rows,
  1191. image->client_data);
  1192. if (status == MagickFalse)
  1193. break;
  1194. }
  1195. }
  1196. if (i != 0)
  1197. (void) WriteBlobByte(image,'\n');
  1198. break;
  1199. }
  1200. case 2:
  1201. {
  1202. /*
  1203. Convert image to a PGM image.
  1204. */
  1205. if (image->depth <= 8)
  1206. (void) WriteBlobString(image,"255\n");
  1207. else
  1208. (void) WriteBlobString(image,"65535\n");
  1209. i=0;
  1210. for (y=0; y < (long) image->rows; y++)
  1211. {
  1212. p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
  1213. if (p == (const PixelPacket *) NULL)
  1214. break;
  1215. for (x=0; x < (long) image->columns; x++)
  1216. {
  1217. index=PixelIntensityToQuantum(p);
  1218. if (image->depth <= 8)
  1219. (void) FormatMagickString(buffer,MaxTextExtent," %u",
  1220. ScaleQuantumToChar(index));
  1221. else
  1222. (void) FormatMagickString(buffer,MaxTextExtent," %u",
  1223. ScaleQuantumToShort(index));
  1224. (void) WriteBlobString(image,buffer);
  1225. i++;
  1226. if (i == 12)
  1227. {
  1228. (void) WriteBlobByte(image,'\n');
  1229. i=0;
  1230. }
  1231. p++;
  1232. }
  1233. if (image->previous == (Image *) NULL)
  1234. if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
  1235. (QuantumTick(y,image->rows) != MagickFalse))
  1236. {
  1237. status=image->progress_monitor(SaveImageTag,y,image->rows,
  1238. image->client_data);
  1239. if (status == MagickFalse)
  1240. break;
  1241. }
  1242. }
  1243. if (i != 0)
  1244. (void) WriteBlobByte(image,'\n');
  1245. break;
  1246. }
  1247. case 3:
  1248. {
  1249. /*
  1250. Convert image to a PNM image.
  1251. */
  1252. if (image->depth <= 8)
  1253. (void) WriteBlobString(image,"255\n");
  1254. else
  1255. (void) WriteBlobString(image,"65535\n");
  1256. i=0;
  1257. for (y=0; y < (long) image->rows; y++)
  1258. {
  1259. p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
  1260. if (p == (const PixelPacket *) NULL)
  1261. break;
  1262. for (x=0; x < (long) image->columns; x++)
  1263. {
  1264. if (image->depth <= 8)
  1265. (void) FormatMagickString(buffer,MaxTextExtent,"%u %u %u ",
  1266. ScaleQuantumToChar(p->red),ScaleQuantumToChar(p->green),
  1267. ScaleQuantumToChar(p->blue));
  1268. else
  1269. (void) FormatMagickString(buffer,MaxTextExtent,"%u %u %u ",
  1270. ScaleQuantumToShort(p->red),ScaleQuantumToShort(p->green),
  1271. ScaleQuantumToShort(p->blue));
  1272. (void) WriteBlobString(image,buffer);
  1273. i++;
  1274. if (i == 4)
  1275. {
  1276. (void) WriteBlobByte(image,'\n');
  1277. i=0;
  1278. }
  1279. p++;
  1280. }
  1281. if (image->previous == (Image *) NULL)
  1282. if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
  1283. (QuantumTick(y,image->rows) != MagickFalse))
  1284. {
  1285. status=image->progress_monitor(SaveImageTag,y,image->rows,
  1286. image->client_data);
  1287. if (status == MagickFalse)
  1288. break;
  1289. }
  1290. }
  1291. if (i != 0)
  1292. (void) WriteBlobByte(image,'\n');
  1293. break;
  1294. }
  1295. case 4:
  1296. {
  1297. unsigned long
  1298. bit,
  1299. byte;
  1300. /*
  1301. Convert image to a PBM image.
  1302. */
  1303. (void) SetImageType(image,BilevelType);
  1304. for (y=0; y < (long) image->rows; y++)
  1305. {
  1306. p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
  1307. if (p == (const PixelPacket *) NULL)
  1308. break;
  1309. indexes=GetIndexes(image);
  1310. bit=0;
  1311. byte=0;
  1312. for (x=0; x < (long) image->columns; x++)
  1313. {
  1314. byte<<=1;
  1315. if (PixelIntensity(p) < (QuantumRange/2.0))
  1316. byte|=0x01;
  1317. bit++;
  1318. if (bit == 8)
  1319. {
  1320. (void) WriteBlobByte(image,(unsigned char) byte);
  1321. bit=0;
  1322. byte=0;
  1323. }
  1324. p++;
  1325. }
  1326. if (bit != 0)
  1327. (void) WriteBlobByte(image,(unsigned char) (byte << (8-bit)));
  1328. if (image->previous == (Image *) NULL)
  1329. if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
  1330. (QuantumTick(y,image->rows) != MagickFalse))
  1331. {
  1332. status=image->progress_monitor(SaveImageTag,y,image->rows,
  1333. image->client_data);
  1334. if (status == MagickFalse)
  1335. break;
  1336. }
  1337. }
  1338. break;
  1339. }
  1340. case 5:
  1341. {
  1342. /*
  1343. Convert image to a PGM image.
  1344. */
  1345. if (image->depth <= 8)
  1346. (void) WriteBlobString(image,"255\n");
  1347. else
  1348. (void) WriteBlobString(image,"65535\n");
  1349. for (y=0; y < (long) image->rows; y++)
  1350. {
  1351. p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
  1352. if (p == (const PixelPacket *) NULL)
  1353. break;
  1354. if (image->depth <= 8)
  1355. for (x=0; x < (long) image->columns; x++)
  1356. {
  1357. (void) WriteBlobByte(image,
  1358. ScaleQuantumToChar(PixelIntensityToQuantum(p)));
  1359. p++;
  1360. }
  1361. else
  1362. for (x=0; x < (long) image->columns; x++)
  1363. {
  1364. (void) WriteBlobMSBShort(image,
  1365. ScaleQuantumToShort(PixelIntensityToQuantum(p)));
  1366. p++;
  1367. }
  1368. if (image->previous == (Image *) NULL)
  1369. if ((image->progress_monitor != (MagickProgressMonitor) NULL) &&
  1370. (QuantumTick(y,image->rows) != MagickFalse))
  1371. {
  1372. status=image->progress_monitor(SaveImageTag,y,image->rows,
  1373. image->client_data);
  1374. if (status == MagickFalse)
  1375. break;
  1376. }
  1377. }
  1378. break;
  1379. }
  1380. case 6:
  1381. {
  1382. /*
  1383. Allocate memory for pixels.
  1384. */
  1385. packet_size=(size_t) (image->depth <= 8 ? 3 : 6);
  1386. length=packet_size*image->columns*sizeof(*pixels);
  1387. pixels=(unsigned char *) AcquireMagickMemory(length);
  1388. if (pixels == (unsigned char *) NULL)
  1389. ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
  1390. /*
  1391. Convert image to a PNM image.
  1392. */
  1393. if (image->depth <= 8)
  1394. (void) WriteBlobString(image,"255\n");
  1395. else
  1396. (void) WriteBlobString(image,"65535\n");
  1397. for (y=0; y < (long) image->rows; y++)
  1398. {
  1399. p=AcquireImagePixels(image,0,y,image->columns,1,&image->exception);
  1400. if (p == (const PixelPacket *) NULL)
  1401. break;
  1402. q=pixels;
  1403. if (image->depth <= 8)
  1404. for (x=0; x < (long) image->columns; x++)
  1405. {
  1406. *q++=ScaleQuantumToChar(p->red);
  1407. *q++=ScaleQuantumToChar(p->green);
  1408. *q++=ScaleQuantumToChar(p->blue);
  1409. p++;
  1410. }
  1411. else
  1412. for (x=0; x < (long) image->columns; x++)
  1413. {
  1414. *q++=(unsigned char) (ScaleQuantumToShort(p->red) >> 8);
  1415. *q++=(unsigned char) ScaleQuantumToShort(p->red);
  1416. *q++=(unsigned char) (ScaleQuantumToShort(p->green) >> 8);
  1417. *q++=(unsigned char) ScaleQuantumToShort(p->green);
  1418. *q++=(unsigned char) (ScaleQuantumToShort(p->blue) >> 8);
  1419. *q++=(unsigned char) ScaleQuantumToShort(p->blue);
  1420. p++;
  1421. }
  1422. (void) WriteBlob(image,(size_t) (q-pixels),pixels);

Large files files are truncated, but you can click here to view the full file