13ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
23ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
33ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
43ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
53ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
63ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                            X   X  BBBB   M   M                              %
73ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                             X X   B   B  MM MM                              %
83ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                              X    BBBB   M M M                              %
93ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                             X X   B   B  M   M                              %
103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                            X   X  BBBB   M   M                              %
113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                  Read/Write X Windows System Bitmap Format                  %
143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                              Software Design                                %
16de984cdc3631106b1cbbb8d3972b76a0fc27e8e8cristy%                                   Cristy                                    %
173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                 July 1992                                   %
183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
207ce65e7125a4e1df1a274ce373c537a9df9c16cdCristy%  Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization      %
213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  dedicated to making software imaging solutions freely available.           %
223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  You may not use this file except in compliance with the License.  You may  %
243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  obtain a copy of the License at                                            %
253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    http://www.imagemagick.org/script/license.php                            %
273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  Unless required by applicable law or agreed to in writing, software        %
293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  distributed under the License is distributed on an "AS IS" BASIS,          %
303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  See the License for the specific language governing permissions and        %
323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  limitations under the License.                                             %
333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Include declarations.
413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
424c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/studio.h"
43d9ecd04e9c567113b4b605cf76681cbb37c093cdcristy#include "MagickCore/attribute.h"
444c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/blob.h"
454c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/blob-private.h"
464c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/cache.h"
474c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/color-private.h"
484c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/colormap.h"
494c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/colorspace.h"
50510d06a3f7063e91993e13d546d5685048248074cristy#include "MagickCore/colorspace-private.h"
514c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/exception.h"
524c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/exception-private.h"
534c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/image.h"
544c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/image-private.h"
554c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/list.h"
564c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/magick.h"
574c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/memory_.h"
584c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/monitor.h"
594c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/monitor-private.h"
604c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/pixel-accessor.h"
614c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/quantum-private.h"
624c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/static.h"
634c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/string_.h"
644c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/module.h"
654c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/utility.h"
663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Forward declarations.
693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
703ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
713a37efd7ece979e9c63dc8f2f2d3816bab8b1156cristy  WriteXBMImage(const ImageInfo *,Image *,ExceptionInfo *);
723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s X B M                                                                 %
793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsXBM() returns MagickTrue if the image format type, identified by the
853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is XBM.
863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the IsXBM method is:
883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsXBM(const unsigned char *magick,const size_t length)
903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
983ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsXBM(const unsigned char *magick,const size_t length)
993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 7)
1013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
1023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick,"#define",7) == 0)
1033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
1043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
1053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d X B M I m a g e                                                   %
1133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadXBMImage() reads an X11 bitmap image file and returns it.  It
1193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  allocates the memory necessary for the new Image structure and returns a
1203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pointer to the new image.
1213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadXBMImage method is:
1233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadXBMImage(const ImageInfo *image_info,ExceptionInfo *exception)
1253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
1273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
1293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
1313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
134920046a438db0d028d27fe7e63c40c3b8560eb42cristystatic unsigned int XBMInteger(Image *image,short int *hex_digits)
135920046a438db0d028d27fe7e63c40c3b8560eb42cristy{
1363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
137920046a438db0d028d27fe7e63c40c3b8560eb42cristy    c;
138920046a438db0d028d27fe7e63c40c3b8560eb42cristy
139920046a438db0d028d27fe7e63c40c3b8560eb42cristy  unsigned int
1403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    value;
141920046a438db0d028d27fe7e63c40c3b8560eb42cristy
142920046a438db0d028d27fe7e63c40c3b8560eb42cristy  /*
143920046a438db0d028d27fe7e63c40c3b8560eb42cristy    Skip any leading whitespace.
144920046a438db0d028d27fe7e63c40c3b8560eb42cristy  */
145920046a438db0d028d27fe7e63c40c3b8560eb42cristy  do
146920046a438db0d028d27fe7e63c40c3b8560eb42cristy  {
1473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    c=ReadBlobByte(image);
1483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (c == EOF)
149920046a438db0d028d27fe7e63c40c3b8560eb42cristy      return(0);
150d178f436636e594e4e6ab009ba398b04de04557ecristy  } while ((c == ' ') || (c == '\t') || (c == '\n') || (c == '\r'));
151920046a438db0d028d27fe7e63c40c3b8560eb42cristy  /*
152920046a438db0d028d27fe7e63c40c3b8560eb42cristy    Evaluate number.
153920046a438db0d028d27fe7e63c40c3b8560eb42cristy  */
154920046a438db0d028d27fe7e63c40c3b8560eb42cristy  value=0;
155920046a438db0d028d27fe7e63c40c3b8560eb42cristy  do
156920046a438db0d028d27fe7e63c40c3b8560eb42cristy  {
157920046a438db0d028d27fe7e63c40c3b8560eb42cristy    if (value > (unsigned int) (INT_MAX/10))
158920046a438db0d028d27fe7e63c40c3b8560eb42cristy      break;
159920046a438db0d028d27fe7e63c40c3b8560eb42cristy    value*=16;
1603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    c&=0xff;
16140a5c455ade0046871a4e93e41585465ff6c575acristy    if (value > (unsigned int) (INT_MAX-hex_digits[c]))
1623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
163920046a438db0d028d27fe7e63c40c3b8560eb42cristy    value+=hex_digits[c];
164920046a438db0d028d27fe7e63c40c3b8560eb42cristy    c=ReadBlobByte(image);
165d178f436636e594e4e6ab009ba398b04de04557ecristy    if (c == EOF)
166d178f436636e594e4e6ab009ba398b04de04557ecristy      return(0);
167920046a438db0d028d27fe7e63c40c3b8560eb42cristy  } while (hex_digits[c] >= 0);
1683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(value);
1693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
1703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1713ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadXBMImage(const ImageInfo *image_info,ExceptionInfo *exception)
1723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
174151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy    buffer[MagickPathExtent],
175151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy    name[MagickPathExtent];
1763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
1783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
1793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
1813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
1823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
183bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
1843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    i,
1853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
1863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1874c08aed51c5899665ade97263692328eea4af106cristy  register Quantum
1883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
1893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
1913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
1923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  short int
1943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    hex_digits[256];
1953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
196c6da28e61bb609d2b2cfdcc7752106c973415edbcristy  ssize_t
197c6da28e61bb609d2b2cfdcc7752106c973415edbcristy    y;
198c6da28e61bb609d2b2cfdcc7752106c973415edbcristy
199c6da28e61bb609d2b2cfdcc7752106c973415edbcristy  unsigned char
200c6da28e61bb609d2b2cfdcc7752106c973415edbcristy    *data;
201c6da28e61bb609d2b2cfdcc7752106c973415edbcristy
202920046a438db0d028d27fe7e63c40c3b8560eb42cristy  unsigned int
203920046a438db0d028d27fe7e63c40c3b8560eb42cristy    bit,
204920046a438db0d028d27fe7e63c40c3b8560eb42cristy    byte,
205920046a438db0d028d27fe7e63c40c3b8560eb42cristy    bytes_per_line,
206f1d91246f9ab47d524abc076c6ead91e5cc27d03cristy    height,
207920046a438db0d028d27fe7e63c40c3b8560eb42cristy    length,
208920046a438db0d028d27fe7e63c40c3b8560eb42cristy    padding,
209920046a438db0d028d27fe7e63c40c3b8560eb42cristy    value,
210920046a438db0d028d27fe7e63c40c3b8560eb42cristy    version,
211f1d91246f9ab47d524abc076c6ead91e5cc27d03cristy    width;
212f1d91246f9ab47d524abc076c6ead91e5cc27d03cristy
2133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
2143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
2153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
2163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
217e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image_info->signature == MagickCoreSignature);
2183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->debug != MagickFalse)
2193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
2203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_info->filename);
2213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
222e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(exception->signature == MagickCoreSignature);
2239950d57e1124b73f684fb5946e206994cefda628cristy  image=AcquireImage(image_info,exception);
2243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
2253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
2263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=DestroyImageList(image);
2283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
2293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
2303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
2313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read X bitmap header.
2323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
233f1d91246f9ab47d524abc076c6ead91e5cc27d03cristy  width=0;
234f1d91246f9ab47d524abc076c6ead91e5cc27d03cristy  height=0;
2353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (ReadBlobString(image,buffer) != (char *) NULL)
23634aabc459bfb1948eae9242e57d7cf8e23b3302aCristy    if (sscanf(buffer,"#define %32s %u",name,&width) == 2)
2373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((strlen(name) >= 6) &&
2383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (LocaleCompare(name+strlen(name)-6,"_width") == 0))
239f1d91246f9ab47d524abc076c6ead91e5cc27d03cristy        break;
2403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (ReadBlobString(image,buffer) != (char *) NULL)
24134aabc459bfb1948eae9242e57d7cf8e23b3302aCristy    if (sscanf(buffer,"#define %32s %u",name,&height) == 2)
2423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((strlen(name) >= 7) &&
2433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (LocaleCompare(name+strlen(name)-7,"_height") == 0))
244f1d91246f9ab47d524abc076c6ead91e5cc27d03cristy        break;
245f1d91246f9ab47d524abc076c6ead91e5cc27d03cristy  image->columns=width;
2469768b939d2165dca5751438be9de7322ff7d6f1ccristy  image->rows=height;
2473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->depth=8;
2483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->storage_class=PseudoClass;
2493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->colors=2;
2503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
2513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Scan until hex digits.
2523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
2533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  version=11;
2543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (ReadBlobString(image,buffer) != (char *) NULL)
2553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
25634aabc459bfb1948eae9242e57d7cf8e23b3302aCristy    if (sscanf(buffer,"static short %32s = {",name) == 1)
2573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      version=10;
2583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
25934aabc459bfb1948eae9242e57d7cf8e23b3302aCristy      if (sscanf(buffer,"static unsigned char %32s = {",name) == 1)
2603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        version=11;
2613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else
26234aabc459bfb1948eae9242e57d7cf8e23b3302aCristy        if (sscanf(buffer,"static char %32s = {",name) == 1)
2633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          version=11;
2643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        else
2653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          continue;
2663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    p=(unsigned char *) strrchr(name,'_');
2673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (p == (unsigned char *) NULL)
2683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      p=(unsigned char *) name;
2693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
2703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      p++;
2713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (LocaleCompare("bits[]",(char *) p) == 0)
2723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
2733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
2743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((image->columns == 0) || (image->rows == 0) ||
2753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (EOFBlob(image) != MagickFalse))
2763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
2773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
2783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image structure.
2793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
280018f07f7333b25743d0afff892450cebdb905c1acristy  if (AcquireImageColormap(image,image->colors,exception) == MagickFalse)
2813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
2823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
2833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize colormap.
2843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
2856e963d8cbd0aebba1073d7f4b61e3d17177d6fedcristy  image->colormap[0].red=QuantumRange;
2866e963d8cbd0aebba1073d7f4b61e3d17177d6fedcristy  image->colormap[0].green=QuantumRange;
2876e963d8cbd0aebba1073d7f4b61e3d17177d6fedcristy  image->colormap[0].blue=QuantumRange;
2883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->colormap[1].red=(Quantum) 0;
2893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->colormap[1].green=(Quantum) 0;
2903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->colormap[1].blue=(Quantum) 0;
2913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->ping != MagickFalse)
2923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
2933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) CloseBlob(image);
2943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(GetFirstImageInList(image));
2953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
296acabb847a592ca5e430c1c0949d03acfc0b78bb9cristy  status=SetImageExtent(image,image->columns,image->rows,exception);
297acabb847a592ca5e430c1c0949d03acfc0b78bb9cristy  if (status == MagickFalse)
298acabb847a592ca5e430c1c0949d03acfc0b78bb9cristy    return(DestroyImageList(image));
2993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
3003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize hex values.
3013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
3023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  hex_digits[(int) '0']=0;
3033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  hex_digits[(int) '1']=1;
3043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  hex_digits[(int) '2']=2;
3053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  hex_digits[(int) '3']=3;
3063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  hex_digits[(int) '4']=4;
3073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  hex_digits[(int) '5']=5;
3083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  hex_digits[(int) '6']=6;
3093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  hex_digits[(int) '7']=7;
3103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  hex_digits[(int) '8']=8;
3113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  hex_digits[(int) '9']=9;
3123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  hex_digits[(int) 'A']=10;
3133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  hex_digits[(int) 'B']=11;
3143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  hex_digits[(int) 'C']=12;
3153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  hex_digits[(int) 'D']=13;
3163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  hex_digits[(int) 'E']=14;
3173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  hex_digits[(int) 'F']=15;
3183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  hex_digits[(int) 'a']=10;
3193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  hex_digits[(int) 'b']=11;
3203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  hex_digits[(int) 'c']=12;
3213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  hex_digits[(int) 'd']=13;
3223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  hex_digits[(int) 'e']=14;
3233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  hex_digits[(int) 'f']=15;
3243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  hex_digits[(int) 'x']=0;
3253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  hex_digits[(int) ' ']=(-1);
3263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  hex_digits[(int) ',']=(-1);
3273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  hex_digits[(int) '}']=(-1);
3283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  hex_digits[(int) '\n']=(-1);
3293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  hex_digits[(int) '\t']=(-1);
3303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
3313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read hex image data.
3323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
3333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  padding=0;
334c4fc8e7a3e5e349c7c0f11ba537791f02240d39fcristy  if (((image->columns % 16) != 0) && ((image->columns % 16) < 9) &&
335c4fc8e7a3e5e349c7c0f11ba537791f02240d39fcristy      (version == 10))
3363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    padding=1;
33739c51ebe84c67764311d5d4c223ef69a664b571cdirk  bytes_per_line=(unsigned int) (image->columns+7)/8+padding;
33839c51ebe84c67764311d5d4c223ef69a664b571cdirk  length=(unsigned int) image->rows;
3393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  data=(unsigned char *) AcquireQuantumMemory(length,bytes_per_line*
3403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sizeof(*data));
3413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (data == (unsigned char *) NULL)
3423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
3433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  p=data;
3443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (version == 10)
345bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for (i=0; i < (ssize_t) (bytes_per_line*image->rows); (i+=2))
3463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
347920046a438db0d028d27fe7e63c40c3b8560eb42cristy      value=XBMInteger(image,hex_digits);
3483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *p++=(unsigned char) value;
3493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if ((padding == 0) || (((i+2) % bytes_per_line) != 0))
3503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p++=(unsigned char) (value >> 8);
3513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
3523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
353bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for (i=0; i < (ssize_t) (bytes_per_line*image->rows); i++)
3543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
355920046a438db0d028d27fe7e63c40c3b8560eb42cristy      value=XBMInteger(image,hex_digits);
3563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *p++=(unsigned char) value;
3573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
3583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
3593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Convert X bitmap image to pixel packets.
3603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
3613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  p=data;
362bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
3633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
3643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
365acd2ed254c18c254a0ab5aafa06d1645e5d079d8cristy    if (q == (Quantum *) NULL)
3663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
3673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bit=0;
3683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    byte=0;
369bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for (x=0; x < (ssize_t) image->columns; x++)
3703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
3713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (bit == 0)
372bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        byte=(size_t) (*p++);
373f19c990c175215f5a9c709ccf168c07549143e19cristy      SetPixelIndex(image,(Quantum) ((byte & 0x01) != 0 ? 0x01 : 0x00),q);
3743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      bit++;
3753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      byte>>=1;
3763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (bit == 8)
3773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        bit=0;
378ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy      q+=GetPixelChannels(image);
3793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
3803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (SyncAuthenticPixels(image,exception) == MagickFalse)
3813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
382cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy    status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
383c6da28e61bb609d2b2cfdcc7752106c973415edbcristy      image->rows);
3843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
3853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
3863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
3873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  data=(unsigned char *) RelinquishMagickMemory(data);
388ea1a8aa04a9fe1500104284407c1cc06d20da699cristy  (void) SyncImage(image,exception);
3893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
3903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(GetFirstImageInList(image));
3913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
3923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
3943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
3983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e g i s t e r X B M I m a g e                                           %
3993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  RegisterXBMImage() adds attributes for the XBM image format to
4053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the list of supported formats.  The attributes include the image format
4063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  tag, a method to read and/or write the format, whether the format
4073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  supports the saving of more than one frame to the same file or blob,
4083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  whether the format supports native in-memory I/O, and a brief
4093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  description of the format.
4103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the RegisterXBMImage method is:
4123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
413bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%      size_t RegisterXBMImage(void)
4143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
416bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyModuleExport size_t RegisterXBMImage(void)
4173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
4183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickInfo
4193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *entry;
4203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
42106b627a07ff44e1ff93ef1288c9f428066ded10ddirk  entry=AcquireMagickInfo("XBM","XBM",
42206b627a07ff44e1ff93ef1288c9f428066ded10ddirk    "X Windows system bitmap (black and white)");
4233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadXBMImage;
4243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WriteXBMImage;
4253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsXBM;
42608e9a113db499034abb5ad8d59b42f8eca3c641cdirk  entry->flags^=CoderAdjoinFlag;
4273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
4283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickImageCoderSignature);
4293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
4303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
4323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   U n r e g i s t e r X B M I m a g e                                       %
4373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  UnregisterXBMImage() removes format registrations made by the
4433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  XBM module from the list of supported formats.
4443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the UnregisterXBMImage method is:
4463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      UnregisterXBMImage(void)
4483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
4503ed852eea50f9d4cd633efb8c2b054b8e33c253cristyModuleExport void UnregisterXBMImage(void)
4513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
4523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("XBM");
4533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
4543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
4563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e X B M I m a g e                                                 %
4613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
4643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4663a37efd7ece979e9c63dc8f2f2d3816bab8b1156cristy%  WriteXBMImage() writes an image to a file in the X bitmap format.
4673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WriteXBMImage method is:
4693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4703a37efd7ece979e9c63dc8f2f2d3816bab8b1156cristy%      MagickBooleanType WriteXBMImage(const ImageInfo *image_info,
4713a37efd7ece979e9c63dc8f2f2d3816bab8b1156cristy%        Image *image,ExceptionInfo *exception)
4723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows.
4743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
4763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
4783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4793a37efd7ece979e9c63dc8f2f2d3816bab8b1156cristy%    o exception: return any errors or warnings in this structure.
4803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
4813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
4823a37efd7ece979e9c63dc8f2f2d3816bab8b1156cristystatic MagickBooleanType WriteXBMImage(const ImageInfo *image_info,Image *image,
4833a37efd7ece979e9c63dc8f2f2d3816bab8b1156cristy  ExceptionInfo *exception)
4843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
4853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
486151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy    basename[MagickPathExtent],
487151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy    buffer[MagickPathExtent];
4883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
4903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
4913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4924c08aed51c5899665ade97263692328eea4af106cristy  register const Quantum
4933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
4943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
495bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
4963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
4973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
498bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
4993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bit,
5003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    byte;
5013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
502c6da28e61bb609d2b2cfdcc7752106c973415edbcristy  ssize_t
503c6da28e61bb609d2b2cfdcc7752106c973415edbcristy    count,
504c6da28e61bb609d2b2cfdcc7752106c973415edbcristy    y;
505c6da28e61bb609d2b2cfdcc7752106c973415edbcristy
5063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
5073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open output image file.
5083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
5093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
510e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image_info->signature == MagickCoreSignature);
5113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
512e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image->signature == MagickCoreSignature);
5133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
5143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
5153a37efd7ece979e9c63dc8f2f2d3816bab8b1156cristy  assert(exception != (ExceptionInfo *) NULL);
516e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(exception->signature == MagickCoreSignature);
5173a37efd7ece979e9c63dc8f2f2d3816bab8b1156cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
5183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
5193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
520af8d391906d11f0a1f2bbf4e2adbc4995c852d33cristy  (void) TransformImageColorspace(image,sRGBColorspace,exception);
5213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
5223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Write X bitmap header.
5233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
5243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  GetPathComponent(image->filename,BasePath,basename);
525151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy  (void) FormatLocaleString(buffer,MagickPathExtent,"#define %s_width %.20g\n",
526e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy    basename,(double) image->columns);
5273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,strlen(buffer),(unsigned char *) buffer);
528151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy  (void) FormatLocaleString(buffer,MagickPathExtent,"#define %s_height %.20g\n",
529e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy    basename,(double) image->rows);
5303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,strlen(buffer),(unsigned char *) buffer);
531151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy  (void) FormatLocaleString(buffer,MagickPathExtent,
5323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    "static char %s_bits[] = {\n",basename);
5333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,strlen(buffer),(unsigned char *) buffer);
534151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy  (void) CopyMagickString(buffer," ",MagickPathExtent);
5353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,strlen(buffer),(unsigned char *) buffer);
5363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
5373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Convert MIFF to X bitmap pixels.
5383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
539018f07f7333b25743d0afff892450cebdb905c1acristy  (void) SetImageType(image,BilevelType,exception);
5403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  bit=0;
5413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  byte=0;
5423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=0;
5433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  x=0;
5443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  y=0;
545151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy  (void) CopyMagickString(buffer," ",MagickPathExtent);
5463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,strlen(buffer),(unsigned char *) buffer);
547bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
5483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
5493a37efd7ece979e9c63dc8f2f2d3816bab8b1156cristy    p=GetVirtualPixels(image,0,y,image->columns,1,exception);
5504c08aed51c5899665ade97263692328eea4af106cristy    if (p == (const Quantum *) NULL)
5513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
552bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    for (x=0; x < (ssize_t) image->columns; x++)
5533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
5543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      byte>>=1;
555d0323229686850da53ca53c231371ee385b055fccristy      if (GetPixelLuma(image,p) < (QuantumRange/2))
5563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        byte|=0x80;
5573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      bit++;
5583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (bit == 8)
5593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
5603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          /*
5613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            Write a bitmap byte to the image file.
5623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          */
563151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy          (void) FormatLocaleString(buffer,MagickPathExtent,"0x%02X, ",
5643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (unsigned int) (byte & 0xff));
5653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (void) WriteBlob(image,strlen(buffer),(unsigned char *) buffer);
5663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          count++;
5673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (count == 12)
5683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
569151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy              (void) CopyMagickString(buffer,"\n  ",MagickPathExtent);
5703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (void) WriteBlob(image,strlen(buffer),(unsigned char *) buffer);
5713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              count=0;
5723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            };
5733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          bit=0;
5743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          byte=0;
5753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
576ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy        p+=GetPixelChannels(image);
5773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
5783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (bit != 0)
5793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
5803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        /*
5813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Write a bitmap byte to the image file.
5823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        */
5833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        byte>>=(8-bit);
584151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy        (void) FormatLocaleString(buffer,MagickPathExtent,"0x%02X, ",
5853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (unsigned int) (byte & 0xff));
5863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        (void) WriteBlob(image,strlen(buffer),(unsigned char *) buffer);
5873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        count++;
5883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (count == 12)
5893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
590151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy            (void) CopyMagickString(buffer,"\n  ",MagickPathExtent);
5913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            (void) WriteBlob(image,strlen(buffer),(unsigned char *) buffer);
5923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            count=0;
5933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          };
5943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        bit=0;
5953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        byte=0;
5963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      };
597cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy    status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
598c6da28e61bb609d2b2cfdcc7752106c973415edbcristy      image->rows);
5993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
6003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
6013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
602151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy  (void) CopyMagickString(buffer,"};\n",MagickPathExtent);
6033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,strlen(buffer),(unsigned char *) buffer);
6043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
6053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
6063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
607