pdb.c revision acd2ed254c18c254a0ab5aafa06d1645e5d079d8
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                                %
163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                John Cristy                                  %
173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                 July 1992                                   %
183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
207e41fe84a841d7b9d7b36b245b65e9dcb3314943cristy%  Copyright 1999-2011 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    20071202 TS * rewrote RLE decoder - old version could cause buffer overflows
383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                * failure of RLE decoding now thows error RLEDecoderError
393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                * fixed bug in RLE decoding - now all rows are decoded, not just
40c5de69967ea7758f3204962a84c780c82d824ca7cristy      the first one
41c5de69967ea7758f3204962a84c780c82d824ca7cristy    * fixed bug in reader - record offsets now handled correctly
42c5de69967ea7758f3204962a84c780c82d824ca7cristy    * fixed bug in reader - only bits 0..2 indicate compression type
433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                * 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],
1133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    version,
1143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    type;
1153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
116bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
1173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reserved_1,
1183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    note;
1193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  short int
1213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x_last,
1223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y_last;
1233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
124bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
1253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reserved_2;
1263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  short int
1283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x_anchor,
1293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    y_anchor,
1303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    width,
1313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    height;
1323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} PDBImage;
1333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Forward declarations.
1353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1363ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType
1371e178e70fb3c956f9fc1e30c3ba863e882666465cristy  WritePDBImage(const ImageInfo *,Image *,ExceptionInfo *);
1383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
1403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   D e c o d e I m a g e                                                     %
1453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
1483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  DecodeImage unpacks the packed image pixels into runlength-encoded
1513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pixel packets.
1523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the DecodeImage method is:
1543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType DecodeImage(Image *image,unsigned char *pixels,
1563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%        const size_t length)
1573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
1593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image: the address of a structure of type Image.
1613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o pixels:  The address of a byte (8 bits) array of pixel data created by
1633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      the decoding process.
1643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length:  Number of bytes to read into buffer 'pixels'.
1663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
1673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
1683ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType DecodeImage(Image *image, unsigned char *pixels,
1693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const size_t length)
1703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
1713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define RLE_MODE_NONE -1
1723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define RLE_MODE_COPY  0
1733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define RLE_MODE_RUN   1
1743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
175c5de69967ea7758f3204962a84c780c82d824ca7cristy  int           data = 0, count = 0;
176c5de69967ea7758f3204962a84c780c82d824ca7cristy  unsigned char *p;
177c5de69967ea7758f3204962a84c780c82d824ca7cristy  int           mode = RLE_MODE_NONE;
1783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
179c5de69967ea7758f3204962a84c780c82d824ca7cristy  for (p = pixels; p < pixels + length; p++) {
180c5de69967ea7758f3204962a84c780c82d824ca7cristy    if (0 == count) {
181c5de69967ea7758f3204962a84c780c82d824ca7cristy      data = ReadBlobByte( image );
182c5de69967ea7758f3204962a84c780c82d824ca7cristy      if (-1 == data) return MagickFalse;
183c5de69967ea7758f3204962a84c780c82d824ca7cristy      if (data > 128) {
184c5de69967ea7758f3204962a84c780c82d824ca7cristy        mode  = RLE_MODE_RUN;
185c5de69967ea7758f3204962a84c780c82d824ca7cristy        count = data - 128 + 1;
186c5de69967ea7758f3204962a84c780c82d824ca7cristy        data  = ReadBlobByte( image );
187c5de69967ea7758f3204962a84c780c82d824ca7cristy        if (-1 == data) return MagickFalse;
188c5de69967ea7758f3204962a84c780c82d824ca7cristy      } else {
189c5de69967ea7758f3204962a84c780c82d824ca7cristy        mode  = RLE_MODE_COPY;
190c5de69967ea7758f3204962a84c780c82d824ca7cristy        count = data + 1;
191c5de69967ea7758f3204962a84c780c82d824ca7cristy      }
192c5de69967ea7758f3204962a84c780c82d824ca7cristy    }
1933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
194c5de69967ea7758f3204962a84c780c82d824ca7cristy    if (RLE_MODE_COPY == mode) {
195c5de69967ea7758f3204962a84c780c82d824ca7cristy      data = ReadBlobByte( image );
196c5de69967ea7758f3204962a84c780c82d824ca7cristy      if (-1 == data) return MagickFalse;
197c5de69967ea7758f3204962a84c780c82d824ca7cristy    }
198c5de69967ea7758f3204962a84c780c82d824ca7cristy    *p = (unsigned char)data;
199c5de69967ea7758f3204962a84c780c82d824ca7cristy    --count;
200c5de69967ea7758f3204962a84c780c82d824ca7cristy  }
201c5de69967ea7758f3204962a84c780c82d824ca7cristy  return MagickTrue;
2023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
2033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
2053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   I s P D B                                                                 %
2103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  IsPDB() returns MagickTrue if the image format type, identified by the
2163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  magick string, is PDB.
2173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadPDBImage method is:
2193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      MagickBooleanType IsPDB(const unsigned char *magick,const size_t length)
2213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
2233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o magick: compare image format pattern against these bytes.
2253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o length: Specifies the length of the magick string.
2273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
2293ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType IsPDB(const unsigned char *magick,const size_t length)
2303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (length < 68)
2323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickFalse);
2333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (memcmp(magick+60,"vIMGView",8) == 0)
2343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(MagickTrue);
2353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickFalse);
2363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
2373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
2393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e a d P D B I m a g e                                                   %
2443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
2473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  ReadPDBImage() reads an Pilot image file and returns it.  It
2503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  allocates the memory necessary for the new Image structure and returns a
2513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  pointer to the new image.
2523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the ReadPDBImage method is:
2543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      Image *ReadPDBImage(const ImageInfo *image_info,ExceptionInfo *exception)
2563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows:
2583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
2603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o exception: return any errors or warnings in this structure.
2623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
2633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
2643ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic Image *ReadPDBImage(const ImageInfo *image_info,ExceptionInfo *exception)
2653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
2663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
2673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    attributes, /* TS */
2683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tag[3];
2693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Image
2713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *image;
2723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
2743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
2753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PDBImage
2773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pdb_image;
2783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PDBInfo
2803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pdb_info;
2813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2824c08aed51c5899665ade97263692328eea4af106cristy  Quantum
2834c08aed51c5899665ade97263692328eea4af106cristy    index;
2843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
285bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
2863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
2873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2884c08aed51c5899665ade97263692328eea4af106cristy  register Quantum
2893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
2903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
2923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
2933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
294bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  size_t
2953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bits_per_pixel,
296eaedf06777741da32408da72c1e512975c600c48cristy    num_pad_bytes, /* TS */
297eaedf06777741da32408da72c1e512975c600c48cristy    one,
2983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    packets;
2993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
300aff6d807f839a998fff6e87198f2418868ab508ecristy  ssize_t
301aff6d807f839a998fff6e87198f2418868ab508ecristy    count,
302aff6d807f839a998fff6e87198f2418868ab508ecristy    img_offset, /* TS */
303aff6d807f839a998fff6e87198f2418868ab508ecristy    comment_offset = 0,
304aff6d807f839a998fff6e87198f2418868ab508ecristy    y;
305aff6d807f839a998fff6e87198f2418868ab508ecristy
306aff6d807f839a998fff6e87198f2418868ab508ecristy  unsigned char
307aff6d807f839a998fff6e87198f2418868ab508ecristy    *pixels;
308aff6d807f839a998fff6e87198f2418868ab508ecristy
3093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
3103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open image file.
3113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
3123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
3133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
3143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->debug != MagickFalse)
3153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
3163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_info->filename);
3173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
3183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
3193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image=AcquireImage(image_info);
3203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
3213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
3223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
3233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image=DestroyImageList(image);
3243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return((Image *) NULL);
3253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
3263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
3273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Determine if this a PDB image file.
3283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
3293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=ReadBlob(image,32,(unsigned char *) pdb_info.name);
3303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.attributes=(short) ReadBlobMSBShort(image);
3313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.version=(short) ReadBlobMSBShort(image);
3323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.create_time=ReadBlobMSBLong(image);
3333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.modify_time=ReadBlobMSBLong(image);
3343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.archive_time=ReadBlobMSBLong(image);
3353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.modify_number=ReadBlobMSBLong(image);
3363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.application_info=ReadBlobMSBLong(image);
3373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.sort_info=ReadBlobMSBLong(image);
3383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=ReadBlob(image,4,(unsigned char *) pdb_info.type);
3393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=ReadBlob(image,4,(unsigned char *) pdb_info.id);
3403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((count == 0) || (memcmp(pdb_info.type,"vIMG",4) != 0) ||
3413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (memcmp(pdb_info.id,"View",4) != 0))
3423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
3433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.seed=ReadBlobMSBLong(image);
3443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.next_record=ReadBlobMSBLong(image);
3453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.number_records=(short) ReadBlobMSBShort(image);
3463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (pdb_info.next_record != 0)
3473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CoderError,"MultipleRecordListNotSupported");
3483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
3493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read record header.
3503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
3516cff05d334e9e952b56c59d73dd6b02bd3649c49cristy  img_offset=(int) ReadBlobMSBLong(image); /* TS */
3523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  attributes=(unsigned char) ReadBlobByte(image);
353da16f16767eb31921af855f17bda465fffc4e000cristy  (void) attributes;
3543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=ReadBlob(image,3,(unsigned char *) tag);
3553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (count != 3  ||  memcmp(tag,"\x6f\x80\x00",3) != 0)
3563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"CorruptImage");
3573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (pdb_info.number_records > 1)
3583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
3596cff05d334e9e952b56c59d73dd6b02bd3649c49cristy      comment_offset=(int) ReadBlobMSBLong(image);
3603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      attributes=(unsigned char) ReadBlobByte(image);
3613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count=ReadBlob(image,3,(unsigned char *) tag);
3623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (count != 3  ||  memcmp(tag,"\x6f\x80\x01",3) != 0)
3633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(CorruptImageError,"CorruptImage");
3643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
365bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  num_pad_bytes = (size_t) (img_offset - TellBlob( image ));
3663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (num_pad_bytes--) ReadBlobByte( image );
3673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
3683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read image header.
3693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
3703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=ReadBlob(image,32,(unsigned char *) pdb_image.name);
3713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.version=ReadBlobByte(image);
3723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.type=ReadBlobByte(image);
3733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.reserved_1=ReadBlobMSBLong(image);
3743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.note=ReadBlobMSBLong(image);
3753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.x_last=(short) ReadBlobMSBShort(image);
3763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.y_last=(short) ReadBlobMSBShort(image);
3773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.reserved_2=ReadBlobMSBLong(image);
3783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.x_anchor=(short) ReadBlobMSBShort(image);
3793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.y_anchor=(short) ReadBlobMSBShort(image);
3803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.width=(short) ReadBlobMSBShort(image);
3813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.height=(short) ReadBlobMSBShort(image);
3823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
3833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image structure.
3843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
385bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->columns=(size_t) pdb_image.width;
386bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->rows=(size_t) pdb_image.height;
3873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->depth=8;
3883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->storage_class=PseudoClass;
3893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  bits_per_pixel=pdb_image.type == 0 ? 2UL : pdb_image.type == 2 ? 4UL : 1UL;
390eaedf06777741da32408da72c1e512975c600c48cristy  one=1;
391eaedf06777741da32408da72c1e512975c600c48cristy  if (AcquireImageColormap(image,one << bits_per_pixel) == MagickFalse)
3923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
3933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->ping != MagickFalse)
3943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
3953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) CloseBlob(image);
3963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(GetFirstImageInList(image));
3973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
3983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  packets=bits_per_pixel*image->columns/8;
3993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pixels=(unsigned char *) AcquireQuantumMemory(packets+256UL,image->rows*
4003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sizeof(*pixels));
4013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (pixels == (unsigned char *) NULL)
4023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
4033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  switch (pdb_image.version & 7) /* TS */
4053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
4063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 0:
4073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
4083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->compression=NoCompression;
4093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count=(ssize_t) ReadBlob(image, packets * image -> rows, pixels);
4103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
4113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
4123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 1:
4133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
4143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->compression=RLECompression;
4153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (!DecodeImage(image, pixels, packets * image -> rows))
416c5de69967ea7758f3204962a84c780c82d824ca7cristy        ThrowReaderException( CorruptImageError, "RLEDecoderError" ); /* TS */
4173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
4183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
4193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default:
4203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,
421c5de69967ea7758f3204962a84c780c82d824ca7cristy         "UnrecognizedImageCompressionType" );
4223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
4233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  p=pixels;
4243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  switch (bits_per_pixel)
4253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
4263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 1:
4273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
4283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
4293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        bit;
4303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
4323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Read 1-bit PDB image.
4333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
434bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
4353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
4363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
437acd2ed254c18c254a0ab5aafa06d1645e5d079d8cristy        if (q == (Quantum *) NULL)
4383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
439bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < ((ssize_t) image->columns-7); x+=8)
4403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
4413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          for (bit=0; bit < 8; bit++)
4423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4434c08aed51c5899665ade97263692328eea4af106cristy            index=(Quantum) (*p & (0x80 >> bit) ? 0x00 : 0x01);
4444c08aed51c5899665ade97263692328eea4af106cristy            SetPixelIndex(image,index,q);
445ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy            q+=GetPixelChannels(image);
4463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
4473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p++;
4483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
4493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
4503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
451cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy        status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
452aff6d807f839a998fff6e87198f2418868ab508ecristy          image->rows);
4533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
4543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
4553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
456aff6d807f839a998fff6e87198f2418868ab508ecristy      (void) SyncImage(image);
4573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
4583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
4593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 2:
4603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
4613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
4623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Read 2-bit PDB image.
4633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
464bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
4653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
4663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
467acd2ed254c18c254a0ab5aafa06d1645e5d079d8cristy        if (q == (Quantum *) NULL)
4683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
469bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < (ssize_t) image->columns; x+=4)
4703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
4713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          index=ConstrainColormapIndex(image,3UL-((*p >> 6) & 0x03));
4724c08aed51c5899665ade97263692328eea4af106cristy          SetPixelIndex(image,index,q);
473ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          q+=GetPixelChannels(image);
4743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          index=ConstrainColormapIndex(image,3UL-((*p >> 4) & 0x03));
4754c08aed51c5899665ade97263692328eea4af106cristy          SetPixelIndex(image,index,q);
476ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          q+=GetPixelChannels(image);
4773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          index=ConstrainColormapIndex(image,3UL-((*p >> 2) & 0x03));
4784c08aed51c5899665ade97263692328eea4af106cristy          SetPixelIndex(image,index,q);
479ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          q+=GetPixelChannels(image);
4803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          index=ConstrainColormapIndex(image,3UL-((*p) & 0x03));
4814c08aed51c5899665ade97263692328eea4af106cristy          SetPixelIndex(image,index,q);
4823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p++;
483ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          q+=GetPixelChannels(image);
4843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
4853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
4863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
487cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy        status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
488aff6d807f839a998fff6e87198f2418868ab508ecristy          image->rows);
4893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
4903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
4913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
492aff6d807f839a998fff6e87198f2418868ab508ecristy      (void) SyncImage(image);
4933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
4943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
4953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 4:
4963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
4973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
4983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Read 4-bit PDB image.
4993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
500bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
5013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
5023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
503acd2ed254c18c254a0ab5aafa06d1645e5d079d8cristy        if (q == (Quantum *) NULL)
5043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
505bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < (ssize_t) image->columns; x+=2)
5063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
5073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          index=ConstrainColormapIndex(image,15UL-((*p >> 4) & 0x0f));
5084c08aed51c5899665ade97263692328eea4af106cristy          SetPixelIndex(image,index,q);
509ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          q+=GetPixelChannels(image);
5103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          index=ConstrainColormapIndex(image,15UL-((*p) & 0x0f));
5114c08aed51c5899665ade97263692328eea4af106cristy          SetPixelIndex(image,index,q);
5123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p++;
513ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          q+=GetPixelChannels(image);
5143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
5153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
5163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
517cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy        status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
518aff6d807f839a998fff6e87198f2418868ab508ecristy          image->rows);
5193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
5203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
5213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
522aff6d807f839a998fff6e87198f2418868ab508ecristy      (void) SyncImage(image);
5233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
5243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
5253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default:
5263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"ImproperImageHeader");
5273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
5283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pixels=(unsigned char *) RelinquishMagickMemory(pixels);
5303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (EOFBlob(image) != MagickFalse)
5313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
5323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->filename);
5333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (pdb_info.number_records > 1) /* TS */
5343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
5353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      char
5363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *comment;
5373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
5393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        c;
5403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register char
5423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
5433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
544bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      size_t
5453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        length;
5463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
547bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      num_pad_bytes = (size_t) (comment_offset - TellBlob( image ));
5483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (num_pad_bytes--) ReadBlobByte( image );
5493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
5513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Read comment.
5523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
5533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      c=ReadBlobByte(image);
5543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      length=MaxTextExtent;
5553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      comment=AcquireString((char *) NULL);
5563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (p=comment; c != EOF; p++)
5573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
5583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((size_t) (p-comment+MaxTextExtent) >= length)
5593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *p='\0';
5613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            length<<=1;
5623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            length+=MaxTextExtent;
5633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            comment=(char *) ResizeQuantumMemory(comment,length+MaxTextExtent,
5643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              sizeof(*comment));
5653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (comment == (char *) NULL)
5663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
5673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=comment+strlen(comment);
5683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
5693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p=c;
5703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        c=ReadBlobByte(image);
5713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
5723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *p='\0';
5733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (comment == (char *) NULL)
5743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
5753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) SetImageProperty(image,"comment",comment);
5763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      comment=DestroyString(comment);
5773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
5783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
5793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(GetFirstImageInList(image));
5803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
5813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
5833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e g i s t e r P D B I m a g e                                           %
5883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  RegisterPDBImage() adds properties for the PDB image format to
5943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the list of supported formats.  The properties include the image format
5953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  tag, a method to read and/or write the format, whether the format
5963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  supports the saving of more than one frame to the same file or blob,
5973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  whether the format supports native in-memory I/O, and a brief
5983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  description of the format.
5993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the RegisterPDBImage method is:
6013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
602bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%      size_t RegisterPDBImage(void)
6033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
605bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyModuleExport size_t RegisterPDBImage(void)
6063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickInfo
6083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *entry;
6093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PDB");
6113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPDBImage;
6123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePDBImage;
6133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPDB;
6143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Palm Database ImageViewer Format");
6153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PDB");
6163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
6173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickImageCoderSignature);
6183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
6193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
6213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   U n r e g i s t e r P D B I m a g e                                       %
6263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  UnregisterPDBImage() removes format registrations made by the
6323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PDB module from the list of supported formats.
6333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the UnregisterPDBImage method is:
6353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      UnregisterPDBImage(void)
6373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
6393ed852eea50f9d4cd633efb8c2b054b8e33c253cristyModuleExport void UnregisterPDBImage(void)
6403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PDB");
6423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
6433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
6453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e P D B I m a g e                                                 %
6503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WritePDBImage() writes an image
6563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WritePDBImage method is:
6583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6591e178e70fb3c956f9fc1e30c3ba863e882666465cristy%      MagickBooleanType WritePDBImage(const ImageInfo *image_info,
6601e178e70fb3c956f9fc1e30c3ba863e882666465cristy%        Image *image,ExceptionInfo *exception)
6613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows.
6633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
6653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
6673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6681e178e70fb3c956f9fc1e30c3ba863e882666465cristy%    o exception: return any errors or warnings in this structure.
6693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
6713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6723ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic unsigned char *EncodeRLE(unsigned char *destination,
673bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  unsigned char *source,size_t literal,size_t repeat)
6743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (literal > 0)
6763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *destination++=(unsigned char) (literal-1);
6773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickMemory(destination,source,literal);
6783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  destination+=literal;
6793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (repeat > 0)
6803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
6813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *destination++=(unsigned char) (0x80 | (repeat-1));
6823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *destination++=source[literal];
6833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
6843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(destination);
6853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
6863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6871e178e70fb3c956f9fc1e30c3ba863e882666465cristystatic MagickBooleanType WritePDBImage(const ImageInfo *image_info,Image *image,
6881e178e70fb3c956f9fc1e30c3ba863e882666465cristy  ExceptionInfo *exception)
6893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
6913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *comment;
6923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
6943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bits;
6953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
6973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
6983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PDBImage
7003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pdb_image;
7013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PDBInfo
7033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pdb_info;
7043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  QuantumInfo
7063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *quantum_info;
7073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7084c08aed51c5899665ade97263692328eea4af106cristy  register const Quantum
7093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
7103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
711bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
7123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
7133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
7153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
7163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
718aff6d807f839a998fff6e87198f2418868ab508ecristy    bits_per_pixel,
719aff6d807f839a998fff6e87198f2418868ab508ecristy    literal,
720aff6d807f839a998fff6e87198f2418868ab508ecristy    packets,
721aff6d807f839a998fff6e87198f2418868ab508ecristy    packet_size,
722aff6d807f839a998fff6e87198f2418868ab508ecristy    repeat;
723aff6d807f839a998fff6e87198f2418868ab508ecristy
724aff6d807f839a998fff6e87198f2418868ab508ecristy  ssize_t
725aff6d807f839a998fff6e87198f2418868ab508ecristy    y;
7263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
7283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *buffer,
7293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *runlength,
7303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *scanline;
7313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
7333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open output image file.
7343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
7353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
7363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
7373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
7383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
7393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
7403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
7413a37efd7ece979e9c63dc8f2f2d3816bab8b1156cristy  assert(exception != (ExceptionInfo *) NULL);
7423a37efd7ece979e9c63dc8f2f2d3816bab8b1156cristy  assert(exception->signature == MagickSignature);
7431e178e70fb3c956f9fc1e30c3ba863e882666465cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
7443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
7453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
746510d06a3f7063e91993e13d546d5685048248074cristy  if (IsRGBColorspace(image->colorspace) == MagickFalse)
7473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) TransformImageColorspace(image,RGBColorspace);
7483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7491e178e70fb3c956f9fc1e30c3ba863e882666465cristy  if (image -> colors <= 2  ||  GetImageType( image, exception ) == BilevelType) { /* TS */
7503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bits_per_pixel = 1;
7513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } else if (image -> colors <= 4) {
7523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bits_per_pixel = 2;
7533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } else if (image -> colors <= 8) {
7543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bits_per_pixel = 3;
7553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } else {
7563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bits_per_pixel = 4;
7573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
7583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(pdb_info.name,0,32);
7603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(pdb_info.name,image_info->filename,32);
7613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.attributes=0;
7623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.version=0;
7633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.create_time=time(NULL);
7643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.modify_time=pdb_info.create_time;
7653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.archive_time=0;
7663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.modify_number=0;
7673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.application_info=0;
7683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.sort_info=0;
7693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickMemory(pdb_info.type,"vIMG",4);
7703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickMemory(pdb_info.id,"View",4);
7713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.seed=0;
7723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.next_record=0;
7733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  comment=GetImageProperty(image,"comment");
7743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.number_records=(comment == (const char *) NULL ? 1 : 2);
7753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,32,(unsigned char *) pdb_info.name);
7763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBShort(image,(unsigned short) pdb_info.attributes);
7773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBShort(image,(unsigned short) pdb_info.version);
778eaedf06777741da32408da72c1e512975c600c48cristy  (void) WriteBlobMSBLong(image,(unsigned int) pdb_info.create_time);
779eaedf06777741da32408da72c1e512975c600c48cristy  (void) WriteBlobMSBLong(image,(unsigned int) pdb_info.modify_time);
780eaedf06777741da32408da72c1e512975c600c48cristy  (void) WriteBlobMSBLong(image,(unsigned int) pdb_info.archive_time);
781eaedf06777741da32408da72c1e512975c600c48cristy  (void) WriteBlobMSBLong(image,(unsigned int) pdb_info.modify_number);
782eaedf06777741da32408da72c1e512975c600c48cristy  (void) WriteBlobMSBLong(image,(unsigned int) pdb_info.application_info);
783eaedf06777741da32408da72c1e512975c600c48cristy  (void) WriteBlobMSBLong(image,(unsigned int) pdb_info.sort_info);
7843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,(unsigned char *) pdb_info.type);
7853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,(unsigned char *) pdb_info.id);
786eaedf06777741da32408da72c1e512975c600c48cristy  (void) WriteBlobMSBLong(image,(unsigned int) pdb_info.seed);
787eaedf06777741da32408da72c1e512975c600c48cristy  (void) WriteBlobMSBLong(image,(unsigned int) pdb_info.next_record);
7883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBShort(image,(unsigned short) pdb_info.number_records);
7893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(pdb_image.name,pdb_info.name,32);
7903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.version=1;  /* RLE Compressed */
7913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  switch (bits_per_pixel)
7923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
7933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 1: pdb_image.type=(char) 0xff; break;  /* monochrome */
7943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 2: pdb_image.type=(char) 0x00; break;  /* 2 bit gray */
7953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default: pdb_image.type=(char) 0x02;  /* 4 bit gray */
7963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
7973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.reserved_1=0;
7983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.note=0;
7993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.x_last=0;
8003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.y_last=0;
8013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.reserved_2=0;
8023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.x_anchor=(short) 0xffff;
8033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.y_anchor=(short) 0xffff;
8043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.width=(short) image->columns;
8053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->columns % 16)
8063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pdb_image.width=(short) (16*(image->columns/16+1));
8073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.height=(short) image->rows;
8083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  packets=(bits_per_pixel*image->columns/8)*image->rows;
8093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  runlength=(unsigned char *) AcquireQuantumMemory(2UL*packets,
8103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sizeof(*runlength));
8113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (runlength == (unsigned char *) NULL)
8123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
8133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer=(unsigned char *) AcquireQuantumMemory(256UL,sizeof(*buffer));
8143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (buffer == (unsigned char *) NULL)
8153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
8163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  packet_size=(size_t) (image->depth > 8 ? 2: 1);
8173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  scanline=(unsigned char *) AcquireQuantumMemory(image->columns,packet_size*
8183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sizeof(*scanline));
8193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (scanline == (unsigned char *) NULL)
8203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
821510d06a3f7063e91993e13d546d5685048248074cristy  if (IsRGBColorspace(image->colorspace) == MagickFalse)
8223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) TransformImageColorspace(image,RGBColorspace);
8233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
8243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Convert to GRAY raster scanline.
8253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
8263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info=AcquireQuantumInfo(image_info,image);
8273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (quantum_info == (QuantumInfo *) NULL)
8283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
829f9cca6af1ff9b913c32a2cec81eda059877a8832cristy  bits=8/(int) bits_per_pixel-1;  /* start at most significant bits */
8303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  literal=0;
8313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  repeat=0;
8323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  q=runlength;
8333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[0]=0x00;
834bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
8353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
8361e178e70fb3c956f9fc1e30c3ba863e882666465cristy    p=GetVirtualPixels(image,0,y,image->columns,1,exception);
8374c08aed51c5899665ade97263692328eea4af106cristy    if (p == (const Quantum *) NULL)
8383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
8394c08aed51c5899665ade97263692328eea4af106cristy    (void) ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
8401e178e70fb3c956f9fc1e30c3ba863e882666465cristy      GrayQuantum,scanline,exception);
8413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (x=0; x < pdb_image.width; x++)
8423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
843bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      if (x < (ssize_t) image->columns)
8443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        buffer[literal+repeat]|=(0xff-scanline[x*packet_size]) >>
8453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (8-bits_per_pixel) << bits*bits_per_pixel;
8463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      bits--;
8473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (bits < 0)
8483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
8493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (((literal+repeat) > 0) &&
8503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (buffer[literal+repeat] == buffer[literal+repeat-1]))
8513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
8523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (repeat == 0)
8533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
8543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  literal--;
8553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  repeat++;
8563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
8573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat++;
8583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (0x7f < repeat)
8593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
8603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q=EncodeRLE(q,buffer,literal,repeat);
8613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  literal=0;
8623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  repeat=0;
8633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
8643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
8653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
8663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
8673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (repeat >= 2)
8683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                literal+=repeat;
8693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
8703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
8713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q=EncodeRLE(q,buffer,literal,repeat);
8723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  buffer[0]=buffer[literal+repeat];
8733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  literal=0;
8743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
8753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              literal++;
8763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=0;
8773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (0x7f < literal)
8783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
8793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q=EncodeRLE(q,buffer,(literal < 0x80 ? literal : 0x80),0);
8803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) CopyMagickMemory(buffer,buffer+literal+repeat,0x80);
8813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  literal-=0x80;
8823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
8833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
884f9cca6af1ff9b913c32a2cec81eda059877a8832cristy        bits=8/(int) bits_per_pixel-1;
8853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        buffer[literal+repeat]=0x00;
8863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
8873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
888cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy    status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
889cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy                image->rows);
8903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
8913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
8923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
8933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  q=EncodeRLE(q,buffer,literal,repeat);
8943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  scanline=(unsigned char *) RelinquishMagickMemory(scanline);
8953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer=(unsigned char *) RelinquishMagickMemory(buffer);
8963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info=DestroyQuantumInfo(quantum_info);
8973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
8983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Write the Image record header.
8993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
900f6fe0a138e6b5879b6c11a27d715412479acf128cristy  (void) WriteBlobMSBLong(image,(unsigned int)
9013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (TellBlob(image)+8*pdb_info.number_records));
9023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobByte(image,0x40);
9033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobByte(image,0x6f);
9043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobByte(image,0x80);
9053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobByte(image,0);
9063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (pdb_info.number_records > 1)
9073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
9083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
9093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the comment record header.
9103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
911f6fe0a138e6b5879b6c11a27d715412479acf128cristy      (void) WriteBlobMSBLong(image,(unsigned int) (TellBlob(image)+8+58+q-
9123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        runlength));
9133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobByte(image,0x40);
9143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobByte(image,0x6f);
9153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobByte(image,0x80);
9163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobByte(image,1);
9173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
9183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
9193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Write the Image data.
9203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
9213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,32,(unsigned char *) pdb_image.name);
9223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobByte(image,(unsigned char) pdb_image.version);
9233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobByte(image,(unsigned char) pdb_image.type);
924eaedf06777741da32408da72c1e512975c600c48cristy  (void) WriteBlobMSBLong(image,(unsigned int) pdb_image.reserved_1);
925eaedf06777741da32408da72c1e512975c600c48cristy  (void) WriteBlobMSBLong(image,(unsigned int) pdb_image.note);
9263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBShort(image,(unsigned short) pdb_image.x_last);
9273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBShort(image,(unsigned short) pdb_image.y_last);
928eaedf06777741da32408da72c1e512975c600c48cristy  (void) WriteBlobMSBLong(image,(unsigned int) pdb_image.reserved_2);
9293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBShort(image,(unsigned short) pdb_image.x_anchor);
9303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBShort(image,(unsigned short) pdb_image.y_anchor);
9313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBShort(image,(unsigned short) pdb_image.width);
9323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBShort(image,(unsigned short) pdb_image.height);
9333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,(size_t) (q-runlength),runlength);
9343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  runlength=(unsigned char *) RelinquishMagickMemory(runlength);
9353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (pdb_info.number_records > 1)
9363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobString(image,comment);
9373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
9383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
9393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
940