pdb.c revision e1c94d9d25db6b0dd7a5028ffee31d1057855d73
13ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
23ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
33ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
43ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
53ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
63ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                            PPPP   DDDD   BBBB                               %
73ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                            P   P  D   D  B   B                              %
83ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                            PPPP   D   D  BBBB                               %
93ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                            P      D   D  B   B                              %
103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                            P      DDDD   BBBB                               %
113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%               Read/Write Palm Database ImageViewer Image Format             %
143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                              Software Design                                %
16de984cdc3631106b1cbbb8d3972b76a0fc27e8e8cristy%                                   Cristy                                    %
173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                 July 1992                                   %
183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
20b56bb24a985ca4366713bcd8ffdfacbb48a98a2fcristy%  Copyright 1999-2015 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%
3798cba568aa6dae69149f99b572a7ad3e5fd6ff9acristy%   20071202 TS * rewrote RLE decoder - old version could cause buffer overflows
3898cba568aa6dae69149f99b572a7ad3e5fd6ff9acristy%               * failure of RLE decoding now thows error RLEDecoderError
3998cba568aa6dae69149f99b572a7ad3e5fd6ff9acristy%               * fixed bug in RLE decoding - now all rows are decoded, not just
4098cba568aa6dae69149f99b572a7ad3e5fd6ff9acristy%     the first one
4198cba568aa6dae69149f99b572a7ad3e5fd6ff9acristy%   * fixed bug in reader - record offsets now handled correctly
4298cba568aa6dae69149f99b572a7ad3e5fd6ff9acristy%   * fixed bug in reader - only bits 0..2 indicate compression type
4398cba568aa6dae69149f99b572a7ad3e5fd6ff9acristy%               * in writer: now using image color count instead of depth
443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Include declarations.
483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
494c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/studio.h"
504c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/attribute.h"
514c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/blob.h"
524c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/blob-private.h"
534c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/cache.h"
544c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/colormap-private.h"
554c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/color-private.h"
564c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/colormap.h"
574c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/colorspace.h"
58510d06a3f7063e91993e13d546d5685048248074cristy#include "MagickCore/colorspace-private.h"
594c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/constitute.h"
604c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/exception.h"
614c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/exception-private.h"
624c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/image.h"
634c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/image-private.h"
644c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/list.h"
654c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/magick.h"
664c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/memory_.h"
674c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/monitor.h"
684c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/monitor-private.h"
694c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/pixel-accessor.h"
704c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/property.h"
714c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/quantum-private.h"
724c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/quantum-private.h"
734c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/static.h"
744c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/string_.h"
754c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/module.h"
763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Typedef declarations.
793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
803ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _PDBInfo
813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    name[32];
843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  short int
863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    attributes,
873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    version;
883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
89bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    create_time,
913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    modify_time,
923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    archive_time,
933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    modify_number,
943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    application_info,
953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sort_info;
963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    type[4],  /* database type identifier "vIMG" */
993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    id[4];    /* database creator identifier "View" */
1003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
101bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
1023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    seed,
1033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    next_record;
1043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  short int
1063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    number_records;
1073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} PDBInfo;
1083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1093ed852eea50f9d4cd633efb8c2b054b8e33c253cristytypedef struct _PDBImage
1103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  char
1123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    name[32],
11393b02b797c4127ce2b06dbd3b2d75ecc33fca759dirk    version;
1143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
115bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
1163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reserved_1,
1173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    note;
1183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  short int
1203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x_last,
1213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y_last;
1223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
123bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
1243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reserved_2;
1253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  short int
1273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    width,
1283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    height;
12993b02b797c4127ce2b06dbd3b2d75ecc33fca759dirk
13093b02b797c4127ce2b06dbd3b2d75ecc33fca759dirk  unsigned char
13193b02b797c4127ce2b06dbd3b2d75ecc33fca759dirk    type;
13293b02b797c4127ce2b06dbd3b2d75ecc33fca759dirk
13393b02b797c4127ce2b06dbd3b2d75ecc33fca759dirk  unsigned short
13493b02b797c4127ce2b06dbd3b2d75ecc33fca759dirk    x_anchor,
13593b02b797c4127ce2b06dbd3b2d75ecc33fca759dirk    y_anchor;
1363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} PDBImage;
1373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Forward declarations.
1393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1403ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
1411e178e70fb3c956f9fc1e30c3ba863e882666465cristy  WritePDBImage(const ImageInfo *,Image *,ExceptionInfo *);
1423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   D e c o d e I m a g e                                                     %
1493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  DecodeImage unpacks the packed image pixels into runlength-encoded
1553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pixel packets.
1563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the DecodeImage method is:
1583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType DecodeImage(Image *image,unsigned char *pixels,
1603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        const size_t length)
1613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
1633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the address of a structure of type Image.
1653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o pixels:  The address of a byte (8 bits) array of pixel data created by
1673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      the decoding process.
1683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length:  Number of bytes to read into buffer 'pixels'.
1703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1723ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType DecodeImage(Image *image, unsigned char *pixels,
1733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const size_t length)
1743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define RLE_MODE_NONE -1
1763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define RLE_MODE_COPY  0
1773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define RLE_MODE_RUN   1
1783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
179c5de69967ea7758f3204962a84c780c82d824ca7cristy  int           data = 0, count = 0;
180c5de69967ea7758f3204962a84c780c82d824ca7cristy  unsigned char *p;
181c5de69967ea7758f3204962a84c780c82d824ca7cristy  int           mode = RLE_MODE_NONE;
1823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
183c5de69967ea7758f3204962a84c780c82d824ca7cristy  for (p = pixels; p < pixels + length; p++) {
184c5de69967ea7758f3204962a84c780c82d824ca7cristy    if (0 == count) {
185c5de69967ea7758f3204962a84c780c82d824ca7cristy      data = ReadBlobByte( image );
186c5de69967ea7758f3204962a84c780c82d824ca7cristy      if (-1 == data) return MagickFalse;
187c5de69967ea7758f3204962a84c780c82d824ca7cristy      if (data > 128) {
188c5de69967ea7758f3204962a84c780c82d824ca7cristy        mode  = RLE_MODE_RUN;
189c5de69967ea7758f3204962a84c780c82d824ca7cristy        count = data - 128 + 1;
190c5de69967ea7758f3204962a84c780c82d824ca7cristy        data  = ReadBlobByte( image );
191c5de69967ea7758f3204962a84c780c82d824ca7cristy        if (-1 == data) return MagickFalse;
192c5de69967ea7758f3204962a84c780c82d824ca7cristy      } else {
193c5de69967ea7758f3204962a84c780c82d824ca7cristy        mode  = RLE_MODE_COPY;
194c5de69967ea7758f3204962a84c780c82d824ca7cristy        count = data + 1;
195c5de69967ea7758f3204962a84c780c82d824ca7cristy      }
196c5de69967ea7758f3204962a84c780c82d824ca7cristy    }
1973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
198c5de69967ea7758f3204962a84c780c82d824ca7cristy    if (RLE_MODE_COPY == mode) {
199c5de69967ea7758f3204962a84c780c82d824ca7cristy      data = ReadBlobByte( image );
200c5de69967ea7758f3204962a84c780c82d824ca7cristy      if (-1 == data) return MagickFalse;
201c5de69967ea7758f3204962a84c780c82d824ca7cristy    }
202c5de69967ea7758f3204962a84c780c82d824ca7cristy    *p = (unsigned char)data;
203c5de69967ea7758f3204962a84c780c82d824ca7cristy    --count;
204c5de69967ea7758f3204962a84c780c82d824ca7cristy  }
205c5de69967ea7758f3204962a84c780c82d824ca7cristy  return MagickTrue;
2063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
2073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
2093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s P D B                                                                 %
2143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsPDB() returns MagickTrue if the image format type, identified by the
2203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is PDB.
2213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadPDBImage method is:
2233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsPDB(const unsigned char *magick,const size_t length)
2253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
2273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
2293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
2313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
2333ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsPDB(const unsigned char *magick,const size_t length)
2343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 68)
2363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
2373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick+60,"vIMGView",8) == 0)
2383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
2393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
2403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
2413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
2433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d P D B I m a g e                                                   %
2483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadPDBImage() reads an Pilot image file and returns it.  It
2543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  allocates the memory necessary for the new Image structure and returns a
2553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pointer to the new image.
2563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadPDBImage method is:
2583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadPDBImage(const ImageInfo *image_info,ExceptionInfo *exception)
2603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
2623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
2643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
2663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
2683ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPDBImage(const ImageInfo *image_info,ExceptionInfo *exception)
2693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
27198cba568aa6dae69149f99b572a7ad3e5fd6ff9acristy    attributes,
2723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tag[3];
2733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
2753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
2763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
2783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
2793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PDBImage
2813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pdb_image;
2823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PDBInfo
2843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pdb_info;
2853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2864c08aed51c5899665ade97263692328eea4af106cristy  Quantum
2874c08aed51c5899665ade97263692328eea4af106cristy    index;
2883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
289bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
2903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
2913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2924c08aed51c5899665ade97263692328eea4af106cristy  register Quantum
2933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
2943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
2963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
2973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
298bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
2993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bits_per_pixel,
30098cba568aa6dae69149f99b572a7ad3e5fd6ff9acristy    num_pad_bytes,
301eaedf06777741da32408da72c1e512975c600c48cristy    one,
3023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    packets;
3033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
304aff6d807f839a998fff6e87198f2418868ab508ecristy  ssize_t
305aff6d807f839a998fff6e87198f2418868ab508ecristy    count,
30698cba568aa6dae69149f99b572a7ad3e5fd6ff9acristy    img_offset,
307aff6d807f839a998fff6e87198f2418868ab508ecristy    comment_offset = 0,
308aff6d807f839a998fff6e87198f2418868ab508ecristy    y;
309aff6d807f839a998fff6e87198f2418868ab508ecristy
310aff6d807f839a998fff6e87198f2418868ab508ecristy  unsigned char
311aff6d807f839a998fff6e87198f2418868ab508ecristy    *pixels;
312aff6d807f839a998fff6e87198f2418868ab508ecristy
3133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
3143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
3153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
3163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
317e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image_info->signature == MagickCoreSignature);
3183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->debug != MagickFalse)
3193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
3203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_info->filename);
3213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
322e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(exception->signature == MagickCoreSignature);
3239950d57e1124b73f684fb5946e206994cefda628cristy  image=AcquireImage(image_info,exception);
3243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
3253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
3263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
3273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=DestroyImageList(image);
3283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
3293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
3303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
3313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Determine if this a PDB image file.
3323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
333ca793d76191054d3659644139269c742c44bcab7cristy  count=ReadBlob(image,sizeof(pdb_info.name),(unsigned char *) pdb_info.name);
334ca793d76191054d3659644139269c742c44bcab7cristy  if (count != sizeof(pdb_info.name))
335ca793d76191054d3659644139269c742c44bcab7cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
3363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.attributes=(short) ReadBlobMSBShort(image);
3373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.version=(short) ReadBlobMSBShort(image);
3383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.create_time=ReadBlobMSBLong(image);
3393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.modify_time=ReadBlobMSBLong(image);
3403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.archive_time=ReadBlobMSBLong(image);
3413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.modify_number=ReadBlobMSBLong(image);
3423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.application_info=ReadBlobMSBLong(image);
3433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.sort_info=ReadBlobMSBLong(image);
3447e5d1daafe9f9ee96028d51b33ddc734493fb296cristy  (void) ReadBlob(image,4,(unsigned char *) pdb_info.type);
3457e5d1daafe9f9ee96028d51b33ddc734493fb296cristy  (void) ReadBlob(image,4,(unsigned char *) pdb_info.id);
3463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.seed=ReadBlobMSBLong(image);
3473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.next_record=ReadBlobMSBLong(image);
3483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.number_records=(short) ReadBlobMSBShort(image);
3497e5d1daafe9f9ee96028d51b33ddc734493fb296cristy  if ((memcmp(pdb_info.type,"vIMG",4) != 0) ||
3507e5d1daafe9f9ee96028d51b33ddc734493fb296cristy      (memcmp(pdb_info.id,"View",4) != 0))
3517e5d1daafe9f9ee96028d51b33ddc734493fb296cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
3523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (pdb_info.next_record != 0)
3533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CoderError,"MultipleRecordListNotSupported");
3543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
3553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read record header.
3563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
35798cba568aa6dae69149f99b572a7ad3e5fd6ff9acristy  img_offset=(ssize_t) ((int) ReadBlobMSBLong(image));
3583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  attributes=(unsigned char) ReadBlobByte(image);
359da16f16767eb31921af855f17bda465fffc4e000cristy  (void) attributes;
3603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=ReadBlob(image,3,(unsigned char *) tag);
3613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (count != 3  ||  memcmp(tag,"\x6f\x80\x00",3) != 0)
3623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"CorruptImage");
3633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (pdb_info.number_records > 1)
3643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
36598cba568aa6dae69149f99b572a7ad3e5fd6ff9acristy      comment_offset=(ssize_t) ((int) ReadBlobMSBLong(image));
3663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      attributes=(unsigned char) ReadBlobByte(image);
3673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count=ReadBlob(image,3,(unsigned char *) tag);
3683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (count != 3  ||  memcmp(tag,"\x6f\x80\x01",3) != 0)
3693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(CorruptImageError,"CorruptImage");
3703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
371bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  num_pad_bytes = (size_t) (img_offset - TellBlob( image ));
37289f839d02a8f261c94f7f7075c3cf90724802958cristy  while (num_pad_bytes-- != 0)
37389f839d02a8f261c94f7f7075c3cf90724802958cristy  {
37489f839d02a8f261c94f7f7075c3cf90724802958cristy    int
37589f839d02a8f261c94f7f7075c3cf90724802958cristy      c;
37689f839d02a8f261c94f7f7075c3cf90724802958cristy
37789f839d02a8f261c94f7f7075c3cf90724802958cristy    c=ReadBlobByte(image);
37889f839d02a8f261c94f7f7075c3cf90724802958cristy    if (c == EOF)
37989f839d02a8f261c94f7f7075c3cf90724802958cristy      break;
38089f839d02a8f261c94f7f7075c3cf90724802958cristy  }
3813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
3823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read image header.
3833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
384ca793d76191054d3659644139269c742c44bcab7cristy  count=ReadBlob(image,sizeof(pdb_image.name),(unsigned char *) pdb_image.name);
385ca793d76191054d3659644139269c742c44bcab7cristy  if (count != sizeof(pdb_image.name))
386ca793d76191054d3659644139269c742c44bcab7cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
3873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.version=ReadBlobByte(image);
38898cba568aa6dae69149f99b572a7ad3e5fd6ff9acristy  pdb_image.type=(unsigned char) ((int) ReadBlobByte(image));
3893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.reserved_1=ReadBlobMSBLong(image);
3903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.note=ReadBlobMSBLong(image);
3913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.x_last=(short) ReadBlobMSBShort(image);
3923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.y_last=(short) ReadBlobMSBShort(image);
3933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.reserved_2=ReadBlobMSBLong(image);
39493b02b797c4127ce2b06dbd3b2d75ecc33fca759dirk  pdb_image.x_anchor=ReadBlobMSBShort(image);
39593b02b797c4127ce2b06dbd3b2d75ecc33fca759dirk  pdb_image.y_anchor=ReadBlobMSBShort(image);
3963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.width=(short) ReadBlobMSBShort(image);
3973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.height=(short) ReadBlobMSBShort(image);
3983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
3993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image structure.
4003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
401bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->columns=(size_t) pdb_image.width;
402bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->rows=(size_t) pdb_image.height;
4033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->depth=8;
404acabb847a592ca5e430c1c0949d03acfc0b78bb9cristy  status=SetImageExtent(image,image->columns,image->rows,exception);
405acabb847a592ca5e430c1c0949d03acfc0b78bb9cristy  if (status == MagickFalse)
406acabb847a592ca5e430c1c0949d03acfc0b78bb9cristy    return(DestroyImageList(image));
4073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->storage_class=PseudoClass;
4083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  bits_per_pixel=pdb_image.type == 0 ? 2UL : pdb_image.type == 2 ? 4UL : 1UL;
409eaedf06777741da32408da72c1e512975c600c48cristy  one=1;
410018f07f7333b25743d0afff892450cebdb905c1acristy  if (AcquireImageColormap(image,one << bits_per_pixel,exception) == MagickFalse)
4113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
4123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->ping != MagickFalse)
4133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
4143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) CloseBlob(image);
4153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(GetFirstImageInList(image));
4163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
41755a26ef4cf0b32cc3d19a3b6cfb02496b4f49b5acristy  packets=(bits_per_pixel*image->columns+7)/8;
4183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pixels=(unsigned char *) AcquireQuantumMemory(packets+256UL,image->rows*
4193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sizeof(*pixels));
4203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (pixels == (unsigned char *) NULL)
4213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
42298cba568aa6dae69149f99b572a7ad3e5fd6ff9acristy  switch (pdb_image.version & 0x07)
4233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
4243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 0:
4253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
4263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->compression=NoCompression;
4273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count=(ssize_t) ReadBlob(image, packets * image -> rows, pixels);
4283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
4293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
4303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 1:
4313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
4323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->compression=RLECompression;
4333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (!DecodeImage(image, pixels, packets * image -> rows))
43498cba568aa6dae69149f99b572a7ad3e5fd6ff9acristy        ThrowReaderException( CorruptImageError, "RLEDecoderError" );
4353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
4363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
4373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default:
4383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,
439c5de69967ea7758f3204962a84c780c82d824ca7cristy         "UnrecognizedImageCompressionType" );
4403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
4413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  p=pixels;
4423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  switch (bits_per_pixel)
4433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
4443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 1:
4453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
4463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
4473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        bit;
4483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
4503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Read 1-bit PDB image.
4513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
452bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
4533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
4543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
455acd2ed254c18c254a0ab5aafa06d1645e5d079d8cristy        if (q == (Quantum *) NULL)
4563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
457bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < ((ssize_t) image->columns-7); x+=8)
4583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
4593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          for (bit=0; bit < 8; bit++)
4603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4614c08aed51c5899665ade97263692328eea4af106cristy            index=(Quantum) (*p & (0x80 >> bit) ? 0x00 : 0x01);
4624c08aed51c5899665ade97263692328eea4af106cristy            SetPixelIndex(image,index,q);
463ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy            q+=GetPixelChannels(image);
4643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
4653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p++;
4663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
4673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
4683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
469cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy        status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
470aff6d807f839a998fff6e87198f2418868ab508ecristy          image->rows);
4713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
4723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
4733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
474ea1a8aa04a9fe1500104284407c1cc06d20da699cristy      (void) SyncImage(image,exception);
4753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
4763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
4773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 2:
4783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
4793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
4803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Read 2-bit PDB image.
4813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
482bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
4833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
4843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
485acd2ed254c18c254a0ab5aafa06d1645e5d079d8cristy        if (q == (Quantum *) NULL)
4863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
48729d4033ce05787ac6e266a9e63d9e8e6d0030d44cristy        for (x=0; x < (ssize_t) image->columns-3; x+=4)
4883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
489c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy          index=ConstrainColormapIndex(image,3UL-((*p >> 6) & 0x03),exception);
4904c08aed51c5899665ade97263692328eea4af106cristy          SetPixelIndex(image,index,q);
491ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          q+=GetPixelChannels(image);
492c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy          index=ConstrainColormapIndex(image,3UL-((*p >> 4) & 0x03),exception);
4934c08aed51c5899665ade97263692328eea4af106cristy          SetPixelIndex(image,index,q);
494ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          q+=GetPixelChannels(image);
495c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy          index=ConstrainColormapIndex(image,3UL-((*p >> 2) & 0x03),exception);
4964c08aed51c5899665ade97263692328eea4af106cristy          SetPixelIndex(image,index,q);
497ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          q+=GetPixelChannels(image);
498c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy          index=ConstrainColormapIndex(image,3UL-((*p) & 0x03),exception);
4994c08aed51c5899665ade97263692328eea4af106cristy          SetPixelIndex(image,index,q);
5003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p++;
501ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          q+=GetPixelChannels(image);
5023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
5033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
5043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
505cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy        status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
506aff6d807f839a998fff6e87198f2418868ab508ecristy          image->rows);
5073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
5083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
5093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
510ea1a8aa04a9fe1500104284407c1cc06d20da699cristy      (void) SyncImage(image,exception);
5113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
5123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
5133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 4:
5143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
5153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
5163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Read 4-bit PDB image.
5173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
518bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
5193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
5203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
521acd2ed254c18c254a0ab5aafa06d1645e5d079d8cristy        if (q == (Quantum *) NULL)
5223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
52329d4033ce05787ac6e266a9e63d9e8e6d0030d44cristy        for (x=0; x < (ssize_t) image->columns-1; x+=2)
5243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
525c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy          index=ConstrainColormapIndex(image,15UL-((*p >> 4) & 0x0f),exception);
5264c08aed51c5899665ade97263692328eea4af106cristy          SetPixelIndex(image,index,q);
527ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          q+=GetPixelChannels(image);
528c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy          index=ConstrainColormapIndex(image,15UL-((*p) & 0x0f),exception);
5294c08aed51c5899665ade97263692328eea4af106cristy          SetPixelIndex(image,index,q);
5303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p++;
531ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          q+=GetPixelChannels(image);
5323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
5333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
5343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
535cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy        status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
536aff6d807f839a998fff6e87198f2418868ab508ecristy          image->rows);
5373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
5383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
5393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
540ea1a8aa04a9fe1500104284407c1cc06d20da699cristy      (void) SyncImage(image,exception);
5413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
5423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
5433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default:
5443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"ImproperImageHeader");
5453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
5463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pixels=(unsigned char *) RelinquishMagickMemory(pixels);
5473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (EOFBlob(image) != MagickFalse)
5483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
5493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->filename);
55098cba568aa6dae69149f99b572a7ad3e5fd6ff9acristy  if (pdb_info.number_records > 1)
5513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
5523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      char
5533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *comment;
5543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
5563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        c;
5573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register char
5593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
5603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
561bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      size_t
5623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        length;
5633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
564bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      num_pad_bytes = (size_t) (comment_offset - TellBlob( image ));
5653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (num_pad_bytes--) ReadBlobByte( image );
5663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
5683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Read comment.
5693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
5703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      c=ReadBlobByte(image);
571151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy      length=MagickPathExtent;
5723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      comment=AcquireString((char *) NULL);
5733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (p=comment; c != EOF; p++)
5743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
575151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy        if ((size_t) (p-comment+MagickPathExtent) >= length)
5763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *p='\0';
5783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            length<<=1;
579151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy            length+=MagickPathExtent;
580151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy            comment=(char *) ResizeQuantumMemory(comment,length+MagickPathExtent,
5813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              sizeof(*comment));
5823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (comment == (char *) NULL)
5833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
5843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=comment+strlen(comment);
5853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
5863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p=c;
5873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        c=ReadBlobByte(image);
5883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
5893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *p='\0';
5903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (comment == (char *) NULL)
5913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
592d15e65928aec551b7388c2863de3e3e628e2e0ddcristy      (void) SetImageProperty(image,"comment",comment,exception);
5933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      comment=DestroyString(comment);
5943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
5953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
5963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(GetFirstImageInList(image));
5973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
5983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
6003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e g i s t e r P D B I m a g e                                           %
6053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  RegisterPDBImage() adds properties for the PDB image format to
6113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the list of supported formats.  The properties include the image format
6123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  tag, a method to read and/or write the format, whether the format
6133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  supports the saving of more than one frame to the same file or blob,
6143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  whether the format supports native in-memory I/O, and a brief
6153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  description of the format.
6163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the RegisterPDBImage method is:
6183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
619bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%      size_t RegisterPDBImage(void)
6203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
622bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyModuleExport size_t RegisterPDBImage(void)
6233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickInfo
6253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *entry;
6263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
62706b627a07ff44e1ff93ef1288c9f428066ded10ddirk  entry=AcquireMagickInfo("PDB","PDB","Palm Database ImageViewer Format");
6283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPDBImage;
6293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePDBImage;
6303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPDB;
6313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
6323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickImageCoderSignature);
6333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
6343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
6363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   U n r e g i s t e r P D B I m a g e                                       %
6413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  UnregisterPDBImage() removes format registrations made by the
6473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PDB module from the list of supported formats.
6483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the UnregisterPDBImage method is:
6503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      UnregisterPDBImage(void)
6523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
6543ed852eea50f9d4cd633efb8c2b054b8e33c253cristyModuleExport void UnregisterPDBImage(void)
6553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PDB");
6573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
6583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
6603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e P D B I m a g e                                                 %
6653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WritePDBImage() writes an image
6713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WritePDBImage method is:
6733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6741e178e70fb3c956f9fc1e30c3ba863e882666465cristy%      MagickBooleanType WritePDBImage(const ImageInfo *image_info,
6751e178e70fb3c956f9fc1e30c3ba863e882666465cristy%        Image *image,ExceptionInfo *exception)
6763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows.
6783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
6803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
6823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6831e178e70fb3c956f9fc1e30c3ba863e882666465cristy%    o exception: return any errors or warnings in this structure.
6843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
6863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6873ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic unsigned char *EncodeRLE(unsigned char *destination,
688bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  unsigned char *source,size_t literal,size_t repeat)
6893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (literal > 0)
6913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *destination++=(unsigned char) (literal-1);
6923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickMemory(destination,source,literal);
6933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  destination+=literal;
6943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (repeat > 0)
6953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
6963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *destination++=(unsigned char) (0x80 | (repeat-1));
6973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *destination++=source[literal];
6983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
6993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(destination);
7003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
7013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7021e178e70fb3c956f9fc1e30c3ba863e882666465cristystatic MagickBooleanType WritePDBImage(const ImageInfo *image_info,Image *image,
7031e178e70fb3c956f9fc1e30c3ba863e882666465cristy  ExceptionInfo *exception)
7043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
7053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
7063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *comment;
7073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
7093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bits;
7103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
7123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
7133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PDBImage
7153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pdb_image;
7163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PDBInfo
7183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pdb_info;
7193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  QuantumInfo
7213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *quantum_info;
7223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7234c08aed51c5899665ade97263692328eea4af106cristy  register const Quantum
7243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
7253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
726bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
7273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
7283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
7303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
7313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
733aff6d807f839a998fff6e87198f2418868ab508ecristy    bits_per_pixel,
734aff6d807f839a998fff6e87198f2418868ab508ecristy    literal,
735aff6d807f839a998fff6e87198f2418868ab508ecristy    packets,
736aff6d807f839a998fff6e87198f2418868ab508ecristy    packet_size,
737aff6d807f839a998fff6e87198f2418868ab508ecristy    repeat;
738aff6d807f839a998fff6e87198f2418868ab508ecristy
739aff6d807f839a998fff6e87198f2418868ab508ecristy  ssize_t
740aff6d807f839a998fff6e87198f2418868ab508ecristy    y;
7413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
7433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *buffer,
7443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *runlength,
7453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *scanline;
7463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
7483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open output image file.
7493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
7503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
751e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image_info->signature == MagickCoreSignature);
7523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
753e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(image->signature == MagickCoreSignature);
7543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
7553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
7563a37efd7ece979e9c63dc8f2f2d3816bab8b1156cristy  assert(exception != (ExceptionInfo *) NULL);
757e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy  assert(exception->signature == MagickCoreSignature);
7581e178e70fb3c956f9fc1e30c3ba863e882666465cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
7593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
7603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
761af8d391906d11f0a1f2bbf4e2adbc4995c852d33cristy  (void) TransformImageColorspace(image,sRGBColorspace,exception);
76298cba568aa6dae69149f99b572a7ad3e5fd6ff9acristy  if ((image->colors <= 2) ||
76398cba568aa6dae69149f99b572a7ad3e5fd6ff9acristy      (GetImageType(image,exception ) == BilevelType)) {
76498cba568aa6dae69149f99b572a7ad3e5fd6ff9acristy    bits_per_pixel=1;
76598cba568aa6dae69149f99b572a7ad3e5fd6ff9acristy  } else if (image->colors <= 4) {
76698cba568aa6dae69149f99b572a7ad3e5fd6ff9acristy    bits_per_pixel=2;
76798cba568aa6dae69149f99b572a7ad3e5fd6ff9acristy  } else if (image->colors <= 8) {
76898cba568aa6dae69149f99b572a7ad3e5fd6ff9acristy    bits_per_pixel=3;
7693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } else {
77098cba568aa6dae69149f99b572a7ad3e5fd6ff9acristy    bits_per_pixel=4;
7713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
7727243780e395bd4e966c539c4afabef83d54191fccristy  (void) ResetMagickMemory(&pdb_info,0,sizeof(pdb_info));
773ca793d76191054d3659644139269c742c44bcab7cristy  (void) CopyMagickString(pdb_info.name,image_info->filename,
774ca793d76191054d3659644139269c742c44bcab7cristy    sizeof(pdb_info.name));
7753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.attributes=0;
7763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.version=0;
7773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.create_time=time(NULL);
7783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.modify_time=pdb_info.create_time;
7793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.archive_time=0;
7803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.modify_number=0;
7813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.application_info=0;
7823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.sort_info=0;
7833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickMemory(pdb_info.type,"vIMG",4);
7843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickMemory(pdb_info.id,"View",4);
7853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.seed=0;
7863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.next_record=0;
787d15e65928aec551b7388c2863de3e3e628e2e0ddcristy  comment=GetImageProperty(image,"comment",exception);
7883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.number_records=(comment == (const char *) NULL ? 1 : 2);
789ca793d76191054d3659644139269c742c44bcab7cristy  (void) WriteBlob(image,sizeof(pdb_info.name),(unsigned char *) pdb_info.name);
7903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBShort(image,(unsigned short) pdb_info.attributes);
7913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBShort(image,(unsigned short) pdb_info.version);
792eaedf06777741da32408da72c1e512975c600c48cristy  (void) WriteBlobMSBLong(image,(unsigned int) pdb_info.create_time);
793eaedf06777741da32408da72c1e512975c600c48cristy  (void) WriteBlobMSBLong(image,(unsigned int) pdb_info.modify_time);
794eaedf06777741da32408da72c1e512975c600c48cristy  (void) WriteBlobMSBLong(image,(unsigned int) pdb_info.archive_time);
795eaedf06777741da32408da72c1e512975c600c48cristy  (void) WriteBlobMSBLong(image,(unsigned int) pdb_info.modify_number);
796eaedf06777741da32408da72c1e512975c600c48cristy  (void) WriteBlobMSBLong(image,(unsigned int) pdb_info.application_info);
797eaedf06777741da32408da72c1e512975c600c48cristy  (void) WriteBlobMSBLong(image,(unsigned int) pdb_info.sort_info);
7983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,(unsigned char *) pdb_info.type);
7993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,(unsigned char *) pdb_info.id);
800eaedf06777741da32408da72c1e512975c600c48cristy  (void) WriteBlobMSBLong(image,(unsigned int) pdb_info.seed);
801eaedf06777741da32408da72c1e512975c600c48cristy  (void) WriteBlobMSBLong(image,(unsigned int) pdb_info.next_record);
8023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBShort(image,(unsigned short) pdb_info.number_records);
803ca793d76191054d3659644139269c742c44bcab7cristy  (void) CopyMagickString(pdb_image.name,pdb_info.name,sizeof(pdb_image.name));
8043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.version=1;  /* RLE Compressed */
8053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  switch (bits_per_pixel)
8063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
80793b02b797c4127ce2b06dbd3b2d75ecc33fca759dirk    case 1: pdb_image.type=(unsigned char) 0xff; break;  /* monochrome */
80893b02b797c4127ce2b06dbd3b2d75ecc33fca759dirk    case 2: pdb_image.type=(unsigned char) 0x00; break;  /* 2 bit gray */
80993b02b797c4127ce2b06dbd3b2d75ecc33fca759dirk    default: pdb_image.type=(unsigned char) 0x02;  /* 4 bit gray */
8103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
8113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.reserved_1=0;
8123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.note=0;
8133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.x_last=0;
8143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.y_last=0;
8153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.reserved_2=0;
81693b02b797c4127ce2b06dbd3b2d75ecc33fca759dirk  pdb_image.x_anchor=(unsigned short) 0xffff;
81793b02b797c4127ce2b06dbd3b2d75ecc33fca759dirk  pdb_image.y_anchor=(unsigned short) 0xffff;
8183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.width=(short) image->columns;
8193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->columns % 16)
8203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pdb_image.width=(short) (16*(image->columns/16+1));
8213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.height=(short) image->rows;
8227e5d1daafe9f9ee96028d51b33ddc734493fb296cristy  packets=((bits_per_pixel*image->columns+7)/8);
8233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  runlength=(unsigned char *) AcquireQuantumMemory(2UL*packets,
8247e5d1daafe9f9ee96028d51b33ddc734493fb296cristy    image->rows*sizeof(*runlength));
8253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (runlength == (unsigned char *) NULL)
8263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
8273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer=(unsigned char *) AcquireQuantumMemory(256UL,sizeof(*buffer));
8283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (buffer == (unsigned char *) NULL)
8293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
8303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  packet_size=(size_t) (image->depth > 8 ? 2: 1);
8313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  scanline=(unsigned char *) AcquireQuantumMemory(image->columns,packet_size*
8323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sizeof(*scanline));
8333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (scanline == (unsigned char *) NULL)
8343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
8353d9f5ba107b160e1819bb6baeeb3a9f521e9f450cristy  if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
8368d95109eca7aee289423a1ee81c232e309b383aecristy    (void) TransformImageColorspace(image,sRGBColorspace,exception);
8373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
8383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Convert to GRAY raster scanline.
8393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
8405f766ef8b0cd9906c2c3a56d845828380a251073cristy  quantum_info=AcquireQuantumInfo(image_info,image);
8413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (quantum_info == (QuantumInfo *) NULL)
8423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
843f9cca6af1ff9b913c32a2cec81eda059877a8832cristy  bits=8/(int) bits_per_pixel-1;  /* start at most significant bits */
8443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  literal=0;
8453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  repeat=0;
8463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  q=runlength;
8473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[0]=0x00;
848bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
8493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
8501e178e70fb3c956f9fc1e30c3ba863e882666465cristy    p=GetVirtualPixels(image,0,y,image->columns,1,exception);
8514c08aed51c5899665ade97263692328eea4af106cristy    if (p == (const Quantum *) NULL)
8523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
8534c08aed51c5899665ade97263692328eea4af106cristy    (void) ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
8541e178e70fb3c956f9fc1e30c3ba863e882666465cristy      GrayQuantum,scanline,exception);
85598cba568aa6dae69149f99b572a7ad3e5fd6ff9acristy    for (x=0; x < (ssize_t) pdb_image.width; x++)
8563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
857bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      if (x < (ssize_t) image->columns)
8583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        buffer[literal+repeat]|=(0xff-scanline[x*packet_size]) >>
8593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (8-bits_per_pixel) << bits*bits_per_pixel;
8603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      bits--;
8613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (bits < 0)
8623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
8633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (((literal+repeat) > 0) &&
8643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (buffer[literal+repeat] == buffer[literal+repeat-1]))
8653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
8663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (repeat == 0)
8673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
8683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  literal--;
8693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  repeat++;
8703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
8713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat++;
8723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (0x7f < repeat)
8733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
8743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q=EncodeRLE(q,buffer,literal,repeat);
8753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  literal=0;
8763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  repeat=0;
8773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
8783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
8793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
8803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
8813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (repeat >= 2)
8823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                literal+=repeat;
8833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
8843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
8853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q=EncodeRLE(q,buffer,literal,repeat);
8863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  buffer[0]=buffer[literal+repeat];
8873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  literal=0;
8883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
8893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              literal++;
8903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=0;
8913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (0x7f < literal)
8923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
8933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q=EncodeRLE(q,buffer,(literal < 0x80 ? literal : 0x80),0);
8943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) CopyMagickMemory(buffer,buffer+literal+repeat,0x80);
8953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  literal-=0x80;
8963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
8973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
898f9cca6af1ff9b913c32a2cec81eda059877a8832cristy        bits=8/(int) bits_per_pixel-1;
8993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        buffer[literal+repeat]=0x00;
9003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
9013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
902cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy    status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
90398cba568aa6dae69149f99b572a7ad3e5fd6ff9acristy      image->rows);
9043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
9053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
9063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
9073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  q=EncodeRLE(q,buffer,literal,repeat);
9083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  scanline=(unsigned char *) RelinquishMagickMemory(scanline);
9093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer=(unsigned char *) RelinquishMagickMemory(buffer);
9103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info=DestroyQuantumInfo(quantum_info);
9113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
9123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Write the Image record header.
9133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
914f6fe0a138e6b5879b6c11a27d715412479acf128cristy  (void) WriteBlobMSBLong(image,(unsigned int)
9153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (TellBlob(image)+8*pdb_info.number_records));
9163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobByte(image,0x40);
9173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobByte(image,0x6f);
9183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobByte(image,0x80);
9193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobByte(image,0);
9203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (pdb_info.number_records > 1)
9213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
9223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
9233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the comment record header.
9243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
925f6fe0a138e6b5879b6c11a27d715412479acf128cristy      (void) WriteBlobMSBLong(image,(unsigned int) (TellBlob(image)+8+58+q-
9263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        runlength));
9273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobByte(image,0x40);
9283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobByte(image,0x6f);
9293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobByte(image,0x80);
9303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobByte(image,1);
9313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
9323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
9333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Write the Image data.
9343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
935ca793d76191054d3659644139269c742c44bcab7cristy  (void) WriteBlob(image,sizeof(pdb_image.name),(unsigned char *)
936ca793d76191054d3659644139269c742c44bcab7cristy    pdb_image.name);
9373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobByte(image,(unsigned char) pdb_image.version);
93893b02b797c4127ce2b06dbd3b2d75ecc33fca759dirk  (void) WriteBlobByte(image,pdb_image.type);
939eaedf06777741da32408da72c1e512975c600c48cristy  (void) WriteBlobMSBLong(image,(unsigned int) pdb_image.reserved_1);
940eaedf06777741da32408da72c1e512975c600c48cristy  (void) WriteBlobMSBLong(image,(unsigned int) pdb_image.note);
9413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBShort(image,(unsigned short) pdb_image.x_last);
9423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBShort(image,(unsigned short) pdb_image.y_last);
943eaedf06777741da32408da72c1e512975c600c48cristy  (void) WriteBlobMSBLong(image,(unsigned int) pdb_image.reserved_2);
94493b02b797c4127ce2b06dbd3b2d75ecc33fca759dirk  (void) WriteBlobMSBShort(image,pdb_image.x_anchor);
94593b02b797c4127ce2b06dbd3b2d75ecc33fca759dirk  (void) WriteBlobMSBShort(image,pdb_image.y_anchor);
9463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBShort(image,(unsigned short) pdb_image.width);
9473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBShort(image,(unsigned short) pdb_image.height);
9483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,(size_t) (q-runlength),runlength);
9493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  runlength=(unsigned char *) RelinquishMagickMemory(runlength);
9503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (pdb_info.number_records > 1)
9513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobString(image,comment);
9523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
9533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
9543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
955