PageRenderTime 78ms CodeModel.GetById 50ms RepoModel.GetById 0ms app.codeStats 0ms

/trunk/coders/mono.c

https://github.com/trevor/ImageMagick
C | 359 lines | 193 code | 12 blank | 154 comment | 62 complexity | f9baba184483c02bced5e79de7fe4736 MD5 | raw file
  1. /*
  2. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3. % %
  4. % %
  5. % %
  6. % M M OOO N N OOO %
  7. % MM MM O O NN N O O %
  8. % M M M O O N N N O O %
  9. % M M O O N NN O O %
  10. % M M OOO N N OOO %
  11. % %
  12. % %
  13. % Read/Write Raw Bi-Level Bitmap Format %
  14. % %
  15. % Software Design %
  16. % Cristy %
  17. % July 1992 %
  18. % %
  19. % %
  20. % Copyright 1999-2014 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 "MagickCore/studio.h"
  42. #include "MagickCore/attribute.h"
  43. #include "MagickCore/blob.h"
  44. #include "MagickCore/blob-private.h"
  45. #include "MagickCore/cache.h"
  46. #include "MagickCore/color-private.h"
  47. #include "MagickCore/colormap.h"
  48. #include "MagickCore/colorspace.h"
  49. #include "MagickCore/colorspace-private.h"
  50. #include "MagickCore/exception.h"
  51. #include "MagickCore/exception-private.h"
  52. #include "MagickCore/image.h"
  53. #include "MagickCore/image-private.h"
  54. #include "MagickCore/list.h"
  55. #include "MagickCore/magick.h"
  56. #include "MagickCore/memory_.h"
  57. #include "MagickCore/monitor.h"
  58. #include "MagickCore/monitor-private.h"
  59. #include "MagickCore/pixel-accessor.h"
  60. #include "MagickCore/quantum-private.h"
  61. #include "MagickCore/static.h"
  62. #include "MagickCore/string_.h"
  63. #include "MagickCore/module.h"
  64. /*
  65. Forward declarations.
  66. */
  67. static MagickBooleanType
  68. WriteMONOImage(const ImageInfo *,Image *,ExceptionInfo *);
  69. /*
  70. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  71. % %
  72. % %
  73. % %
  74. % R e a d M O N O I m a g e %
  75. % %
  76. % %
  77. % %
  78. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  79. %
  80. % ReadMONOImage() reads an image of raw bites in LSB order and returns
  81. % it. It allocates the memory necessary for the new Image structure and
  82. % returns a pointer to the new image.
  83. %
  84. % The format of the ReadMONOImage method is:
  85. %
  86. % Image *ReadMONOImage(const ImageInfo *image_info,
  87. % ExceptionInfo *exception)
  88. %
  89. % A description of each parameter follows:
  90. %
  91. % o image_info: the image info.
  92. %
  93. % o exception: return any errors or warnings in this structure.
  94. %
  95. */
  96. static Image *ReadMONOImage(const ImageInfo *image_info,
  97. ExceptionInfo *exception)
  98. {
  99. Image
  100. *image;
  101. MagickBooleanType
  102. status;
  103. register Quantum
  104. *q;
  105. register ssize_t
  106. x;
  107. size_t
  108. bit,
  109. byte;
  110. ssize_t
  111. y;
  112. /*
  113. Open image file.
  114. */
  115. assert(image_info != (const ImageInfo *) NULL);
  116. assert(image_info->signature == MagickSignature);
  117. if (image_info->debug != MagickFalse)
  118. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
  119. image_info->filename);
  120. assert(exception != (ExceptionInfo *) NULL);
  121. assert(exception->signature == MagickSignature);
  122. image=AcquireImage(image_info,exception);
  123. if ((image->columns == 0) || (image->rows == 0))
  124. ThrowReaderException(OptionError,"MustSpecifyImageSize");
  125. status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
  126. if (status == MagickFalse)
  127. {
  128. image=DestroyImageList(image);
  129. return((Image *) NULL);
  130. }
  131. if (DiscardBlobBytes(image,image->offset) == MagickFalse)
  132. ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
  133. image->filename);
  134. /*
  135. Initialize image colormap.
  136. */
  137. image->depth=1;
  138. if (AcquireImageColormap(image,2,exception) == MagickFalse)
  139. ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
  140. if (image_info->ping != MagickFalse)
  141. {
  142. (void) CloseBlob(image);
  143. return(GetFirstImageInList(image));
  144. }
  145. /*
  146. Convert bi-level image to pixel packets.
  147. */
  148. for (y=0; y < (ssize_t) image->rows; y++)
  149. {
  150. q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
  151. if (q == (Quantum *) NULL)
  152. break;
  153. bit=0;
  154. byte=0;
  155. for (x=0; x < (ssize_t) image->columns; x++)
  156. {
  157. if (bit == 0)
  158. byte=(size_t) ReadBlobByte(image);
  159. if (image_info->endian == LSBEndian)
  160. SetPixelIndex(image,((byte & 0x01) != 0) ? 0x00 : 0x01,q);
  161. else
  162. SetPixelIndex(image,((byte & 0x01) != 0) ? 0x01 : 0x00,q);
  163. bit++;
  164. if (bit == 8)
  165. bit=0;
  166. byte>>=1;
  167. q+=GetPixelChannels(image);
  168. }
  169. if (SyncAuthenticPixels(image,exception) == MagickFalse)
  170. break;
  171. status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
  172. image->rows);
  173. if (status == MagickFalse)
  174. break;
  175. }
  176. (void) SyncImage(image,exception);
  177. if (EOFBlob(image) != MagickFalse)
  178. ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
  179. image->filename);
  180. (void) CloseBlob(image);
  181. return(GetFirstImageInList(image));
  182. }
  183. /*
  184. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  185. % %
  186. % %
  187. % %
  188. % R e g i s t e r M O N O I m a g e %
  189. % %
  190. % %
  191. % %
  192. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  193. %
  194. % RegisterMONOImage() adds attributes for the MONO image format to
  195. % the list of supported formats. The attributes include the image format
  196. % tag, a method to read and/or write the format, whether the format
  197. % supports the saving of more than one frame to the same file or blob,
  198. % whether the format supports native in-memory I/O, and a brief
  199. % description of the format.
  200. %
  201. % The format of the RegisterMONOImage method is:
  202. %
  203. % size_t RegisterMONOImage(void)
  204. %
  205. */
  206. ModuleExport size_t RegisterMONOImage(void)
  207. {
  208. MagickInfo
  209. *entry;
  210. entry=SetMagickInfo("MONO");
  211. entry->decoder=(DecodeImageHandler *) ReadMONOImage;
  212. entry->encoder=(EncodeImageHandler *) WriteMONOImage;
  213. entry->raw=MagickTrue;
  214. entry->endian_support=MagickTrue;
  215. entry->adjoin=MagickFalse;
  216. entry->description=ConstantString("Raw bi-level bitmap");
  217. entry->module=ConstantString("MONO");
  218. (void) RegisterMagickInfo(entry);
  219. return(MagickImageCoderSignature);
  220. }
  221. /*
  222. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  223. % %
  224. % %
  225. % %
  226. % U n r e g i s t e r M O N O I m a g e %
  227. % %
  228. % %
  229. % %
  230. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  231. %
  232. % UnregisterMONOImage() removes format registrations made by the
  233. % MONO module from the list of supported formats.
  234. %
  235. % The format of the UnregisterMONOImage method is:
  236. %
  237. % UnregisterMONOImage(void)
  238. %
  239. */
  240. ModuleExport void UnregisterMONOImage(void)
  241. {
  242. (void) UnregisterMagickInfo("MONO");
  243. }
  244. /*
  245. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  246. % %
  247. % %
  248. % %
  249. % W r i t e M O N O I m a g e %
  250. % %
  251. % %
  252. % %
  253. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  254. %
  255. % WriteMONOImage() writes an image of raw bits in LSB order to a file.
  256. %
  257. % The format of the WriteMONOImage method is:
  258. %
  259. % MagickBooleanType WriteMONOImage(const ImageInfo *image_info,
  260. % Image *image,ExceptionInfo *exception)
  261. %
  262. % A description of each parameter follows.
  263. %
  264. % o image_info: the image info.
  265. %
  266. % o image: The image.
  267. %
  268. % o exception: return any errors or warnings in this structure.
  269. %
  270. */
  271. static MagickBooleanType WriteMONOImage(const ImageInfo *image_info,
  272. Image *image,ExceptionInfo *exception)
  273. {
  274. MagickBooleanType
  275. status;
  276. register const Quantum
  277. *p;
  278. register ssize_t
  279. x;
  280. size_t
  281. bit,
  282. byte;
  283. ssize_t
  284. y;
  285. /*
  286. Open output image file.
  287. */
  288. assert(image_info != (const ImageInfo *) NULL);
  289. assert(image_info->signature == MagickSignature);
  290. assert(image != (Image *) NULL);
  291. assert(image->signature == MagickSignature);
  292. if (image->debug != MagickFalse)
  293. (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
  294. assert(exception != (ExceptionInfo *) NULL);
  295. assert(exception->signature == MagickSignature);
  296. status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
  297. if (status == MagickFalse)
  298. return(status);
  299. if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
  300. (void) TransformImageColorspace(image,sRGBColorspace,exception);
  301. /*
  302. Convert image to a bi-level image.
  303. */
  304. (void) SetImageType(image,BilevelType,exception);
  305. for (y=0; y < (ssize_t) image->rows; y++)
  306. {
  307. p=GetVirtualPixels(image,0,y,image->columns,1,exception);
  308. if (p == (const Quantum *) NULL)
  309. break;
  310. bit=0;
  311. byte=0;
  312. for (x=0; x < (ssize_t) image->columns; x++)
  313. {
  314. byte>>=1;
  315. if (image->endian == LSBEndian)
  316. {
  317. if (GetPixelLuma(image,p) < (QuantumRange/2.0))
  318. byte|=0x80;
  319. }
  320. else
  321. if (GetPixelLuma(image,p) >= (QuantumRange/2.0))
  322. byte|=0x80;
  323. bit++;
  324. if (bit == 8)
  325. {
  326. (void) WriteBlobByte(image,(unsigned char) byte);
  327. bit=0;
  328. byte=0;
  329. }
  330. p+=GetPixelChannels(image);
  331. }
  332. if (bit != 0)
  333. (void) WriteBlobByte(image,(unsigned char) (byte >> (8-bit)));
  334. status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
  335. image->rows);
  336. if (status == MagickFalse)
  337. break;
  338. }
  339. (void) CloseBlob(image);
  340. return(MagickTrue);
  341. }