pdb.c revision de984cdc3631106b1cbbb8d3972b76a0fc27e8e8
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%                                                                             %
20fe676ee3a9cf43404bdc9ba8b27f597b5e4e28f7cristy%  Copyright 1999-2014 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],
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
2713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    attributes, /* TS */
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,
300eaedf06777741da32408da72c1e512975c600c48cristy    num_pad_bytes, /* TS */
301eaedf06777741da32408da72c1e512975c600c48cristy    one,
3023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    packets;
3033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
304aff6d807f839a998fff6e87198f2418868ab508ecristy  ssize_t
305aff6d807f839a998fff6e87198f2418868ab508ecristy    count,
306aff6d807f839a998fff6e87198f2418868ab508ecristy    img_offset, /* TS */
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);
3173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
3183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->debug != MagickFalse)
3193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
3203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image_info->filename);
3213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception != (ExceptionInfo *) NULL);
3223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(exception->signature == MagickSignature);
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  */
3333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=ReadBlob(image,32,(unsigned char *) pdb_info.name);
3343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.attributes=(short) ReadBlobMSBShort(image);
3353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.version=(short) ReadBlobMSBShort(image);
3363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.create_time=ReadBlobMSBLong(image);
3373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.modify_time=ReadBlobMSBLong(image);
3383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.archive_time=ReadBlobMSBLong(image);
3393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.modify_number=ReadBlobMSBLong(image);
3403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.application_info=ReadBlobMSBLong(image);
3413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.sort_info=ReadBlobMSBLong(image);
3423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=ReadBlob(image,4,(unsigned char *) pdb_info.type);
3433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=ReadBlob(image,4,(unsigned char *) pdb_info.id);
3443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((count == 0) || (memcmp(pdb_info.type,"vIMG",4) != 0) ||
3453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (memcmp(pdb_info.id,"View",4) != 0))
3463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
3473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.seed=ReadBlobMSBLong(image);
3483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.next_record=ReadBlobMSBLong(image);
3493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.number_records=(short) ReadBlobMSBShort(image);
3503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (pdb_info.next_record != 0)
3513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CoderError,"MultipleRecordListNotSupported");
3523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
3533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read record header.
3543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
3556cff05d334e9e952b56c59d73dd6b02bd3649c49cristy  img_offset=(int) ReadBlobMSBLong(image); /* TS */
3563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  attributes=(unsigned char) ReadBlobByte(image);
357da16f16767eb31921af855f17bda465fffc4e000cristy  (void) attributes;
3583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=ReadBlob(image,3,(unsigned char *) tag);
3593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (count != 3  ||  memcmp(tag,"\x6f\x80\x00",3) != 0)
3603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(CorruptImageError,"CorruptImage");
3613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (pdb_info.number_records > 1)
3623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
3636cff05d334e9e952b56c59d73dd6b02bd3649c49cristy      comment_offset=(int) ReadBlobMSBLong(image);
3643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      attributes=(unsigned char) ReadBlobByte(image);
3653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count=ReadBlob(image,3,(unsigned char *) tag);
3663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (count != 3  ||  memcmp(tag,"\x6f\x80\x01",3) != 0)
3673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(CorruptImageError,"CorruptImage");
3683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
369bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  num_pad_bytes = (size_t) (img_offset - TellBlob( image ));
3703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  while (num_pad_bytes--) ReadBlobByte( image );
3713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
3723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Read image header.
3733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
3743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  count=ReadBlob(image,32,(unsigned char *) pdb_image.name);
3753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.version=ReadBlobByte(image);
3763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.type=ReadBlobByte(image);
3773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.reserved_1=ReadBlobMSBLong(image);
3783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.note=ReadBlobMSBLong(image);
3793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.x_last=(short) ReadBlobMSBShort(image);
3803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.y_last=(short) ReadBlobMSBShort(image);
3813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.reserved_2=ReadBlobMSBLong(image);
38293b02b797c4127ce2b06dbd3b2d75ecc33fca759dirk  pdb_image.x_anchor=ReadBlobMSBShort(image);
38393b02b797c4127ce2b06dbd3b2d75ecc33fca759dirk  pdb_image.y_anchor=ReadBlobMSBShort(image);
3843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.width=(short) ReadBlobMSBShort(image);
3853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.height=(short) ReadBlobMSBShort(image);
3863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
3873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Initialize image structure.
3883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
389bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->columns=(size_t) pdb_image.width;
390bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  image->rows=(size_t) pdb_image.height;
3913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->depth=8;
3923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  image->storage_class=PseudoClass;
3933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  bits_per_pixel=pdb_image.type == 0 ? 2UL : pdb_image.type == 2 ? 4UL : 1UL;
394eaedf06777741da32408da72c1e512975c600c48cristy  one=1;
395018f07f7333b25743d0afff892450cebdb905c1acristy  if (AcquireImageColormap(image,one << bits_per_pixel,exception) == MagickFalse)
3963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
3973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image_info->ping != MagickFalse)
3983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
3993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) CloseBlob(image);
4003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return(GetFirstImageInList(image));
4013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
4023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  packets=bits_per_pixel*image->columns/8;
4033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pixels=(unsigned char *) AcquireQuantumMemory(packets+256UL,image->rows*
4043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sizeof(*pixels));
4053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (pixels == (unsigned char *) NULL)
4063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
4073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  switch (pdb_image.version & 7) /* TS */
4093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
4103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 0:
4113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
4123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->compression=NoCompression;
4133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      count=(ssize_t) ReadBlob(image, packets * image -> rows, pixels);
4143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
4153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
4163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 1:
4173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
4183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->compression=RLECompression;
4193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (!DecodeImage(image, pixels, packets * image -> rows))
420c5de69967ea7758f3204962a84c780c82d824ca7cristy        ThrowReaderException( CorruptImageError, "RLEDecoderError" ); /* TS */
4213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
4223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
4233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default:
4243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,
425c5de69967ea7758f3204962a84c780c82d824ca7cristy         "UnrecognizedImageCompressionType" );
4263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
4273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  p=pixels;
4283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  switch (bits_per_pixel)
4293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
4303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 1:
4313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
4323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
4333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        bit;
4343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
4363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Read 1-bit PDB image.
4373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
438bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
4393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
4403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
441acd2ed254c18c254a0ab5aafa06d1645e5d079d8cristy        if (q == (Quantum *) NULL)
4423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
443bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < ((ssize_t) image->columns-7); x+=8)
4443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
4453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          for (bit=0; bit < 8; bit++)
4463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
4474c08aed51c5899665ade97263692328eea4af106cristy            index=(Quantum) (*p & (0x80 >> bit) ? 0x00 : 0x01);
4484c08aed51c5899665ade97263692328eea4af106cristy            SetPixelIndex(image,index,q);
449ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy            q+=GetPixelChannels(image);
4503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
4513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p++;
4523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
4533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
4543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
455cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy        status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
456aff6d807f839a998fff6e87198f2418868ab508ecristy          image->rows);
4573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
4583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
4593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
460ea1a8aa04a9fe1500104284407c1cc06d20da699cristy      (void) SyncImage(image,exception);
4613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
4623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
4633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 2:
4643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
4653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
4663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Read 2-bit PDB image.
4673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
468bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
4693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
4703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
471acd2ed254c18c254a0ab5aafa06d1645e5d079d8cristy        if (q == (Quantum *) NULL)
4723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
473bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < (ssize_t) image->columns; x+=4)
4743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
475c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy          index=ConstrainColormapIndex(image,3UL-((*p >> 6) & 0x03),exception);
4764c08aed51c5899665ade97263692328eea4af106cristy          SetPixelIndex(image,index,q);
477ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          q+=GetPixelChannels(image);
478c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy          index=ConstrainColormapIndex(image,3UL-((*p >> 4) & 0x03),exception);
4794c08aed51c5899665ade97263692328eea4af106cristy          SetPixelIndex(image,index,q);
480ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          q+=GetPixelChannels(image);
481c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy          index=ConstrainColormapIndex(image,3UL-((*p >> 2) & 0x03),exception);
4824c08aed51c5899665ade97263692328eea4af106cristy          SetPixelIndex(image,index,q);
483ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          q+=GetPixelChannels(image);
484c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy          index=ConstrainColormapIndex(image,3UL-((*p) & 0x03),exception);
4854c08aed51c5899665ade97263692328eea4af106cristy          SetPixelIndex(image,index,q);
4863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p++;
487ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          q+=GetPixelChannels(image);
4883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
4893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
4903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
491cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy        status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
492aff6d807f839a998fff6e87198f2418868ab508ecristy          image->rows);
4933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
4943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
4953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
496ea1a8aa04a9fe1500104284407c1cc06d20da699cristy      (void) SyncImage(image,exception);
4973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
4983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
4993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case 4:
5003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
5013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
5023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Read 4-bit PDB image.
5033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
504bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      for (y=0; y < (ssize_t) image->rows; y++)
5053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
5063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
507acd2ed254c18c254a0ab5aafa06d1645e5d079d8cristy        if (q == (Quantum *) NULL)
5083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
509bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        for (x=0; x < (ssize_t) image->columns; x+=2)
5103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
511c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy          index=ConstrainColormapIndex(image,15UL-((*p >> 4) & 0x0f),exception);
5124c08aed51c5899665ade97263692328eea4af106cristy          SetPixelIndex(image,index,q);
513ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          q+=GetPixelChannels(image);
514c82a27bb8e3138ff9bbf0f696663bdf3e704cedecristy          index=ConstrainColormapIndex(image,15UL-((*p) & 0x0f),exception);
5154c08aed51c5899665ade97263692328eea4af106cristy          SetPixelIndex(image,index,q);
5163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          p++;
517ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy          q+=GetPixelChannels(image);
5183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
5193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (SyncAuthenticPixels(image,exception) == MagickFalse)
5203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
521cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy        status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y,
522aff6d807f839a998fff6e87198f2418868ab508ecristy          image->rows);
5233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (status == MagickFalse)
5243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          break;
5253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
526ea1a8aa04a9fe1500104284407c1cc06d20da699cristy      (void) SyncImage(image,exception);
5273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
5283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
5293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default:
5303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ThrowReaderException(CorruptImageError,"ImproperImageHeader");
5313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
5323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pixels=(unsigned char *) RelinquishMagickMemory(pixels);
5343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (EOFBlob(image) != MagickFalse)
5353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
5363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      image->filename);
5373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (pdb_info.number_records > 1) /* TS */
5383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
5393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      char
5403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *comment;
5413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      int
5433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        c;
5443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      register char
5463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p;
5473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
548bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      size_t
5493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        length;
5503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
551bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      num_pad_bytes = (size_t) (comment_offset - TellBlob( image ));
5523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      while (num_pad_bytes--) ReadBlobByte( image );
5533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
5553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Read comment.
5563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
5573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      c=ReadBlobByte(image);
5583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      length=MaxTextExtent;
5593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      comment=AcquireString((char *) NULL);
5603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for (p=comment; c != EOF; p++)
5613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      {
5623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if ((size_t) (p-comment+MaxTextExtent) >= length)
5633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          {
5643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            *p='\0';
5653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            length<<=1;
5663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            length+=MaxTextExtent;
5673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            comment=(char *) ResizeQuantumMemory(comment,length+MaxTextExtent,
5683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              sizeof(*comment));
5693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            if (comment == (char *) NULL)
5703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              break;
5713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            p=comment+strlen(comment);
5723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
5733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        *p=c;
5743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        c=ReadBlobByte(image);
5753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
5763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *p='\0';
5773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (comment == (char *) NULL)
5783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
579d15e65928aec551b7388c2863de3e3e628e2e0ddcristy      (void) SetImageProperty(image,"comment",comment,exception);
5803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      comment=DestroyString(comment);
5813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
5823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
5833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(GetFirstImageInList(image));
5843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
5853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
5873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   R e g i s t e r P D B I m a g e                                           %
5923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
5953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
5973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  RegisterPDBImage() adds properties for the PDB image format to
5983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  the list of supported formats.  The properties include the image format
5993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  tag, a method to read and/or write the format, whether the format
6003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  supports the saving of more than one frame to the same file or blob,
6013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  whether the format supports native in-memory I/O, and a brief
6023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  description of the format.
6033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the RegisterPDBImage method is:
6053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
606bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy%      size_t RegisterPDBImage(void)
6073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
609bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyModuleExport size_t RegisterPDBImage(void)
6103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickInfo
6123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *entry;
6133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry=SetMagickInfo("PDB");
6153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->decoder=(DecodeImageHandler *) ReadPDBImage;
6163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->encoder=(EncodeImageHandler *) WritePDBImage;
6173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->magick=(IsImageFormatHandler *) IsPDB;
6183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->description=ConstantString("Palm Database ImageViewer Format");
6193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  entry->module=ConstantString("PDB");
6203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) RegisterMagickInfo(entry);
6213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickImageCoderSignature);
6223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
6233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
6253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   U n r e g i s t e r P D B I m a g e                                       %
6303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  UnregisterPDBImage() removes format registrations made by the
6363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  PDB module from the list of supported formats.
6373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the UnregisterPDBImage method is:
6393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%      UnregisterPDBImage(void)
6413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
6433ed852eea50f9d4cd633efb8c2b054b8e33c253cristyModuleExport void UnregisterPDBImage(void)
6443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) UnregisterMagickInfo("PDB");
6463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
6473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/*
6493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%   W r i t e P D B I m a g e                                                 %
6543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%                                                                             %
6573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  WritePDBImage() writes an image
6603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  The format of the WritePDBImage method is:
6623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6631e178e70fb3c956f9fc1e30c3ba863e882666465cristy%      MagickBooleanType WritePDBImage(const ImageInfo *image_info,
6641e178e70fb3c956f9fc1e30c3ba863e882666465cristy%        Image *image,ExceptionInfo *exception)
6653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%  A description of each parameter follows.
6673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image_info: the image info.
6693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%    o image:  The image.
6713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6721e178e70fb3c956f9fc1e30c3ba863e882666465cristy%    o exception: return any errors or warnings in this structure.
6733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%
6743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/
6753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6763ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic unsigned char *EncodeRLE(unsigned char *destination,
677bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  unsigned char *source,size_t literal,size_t repeat)
6783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (literal > 0)
6803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *destination++=(unsigned char) (literal-1);
6813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickMemory(destination,source,literal);
6823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  destination+=literal;
6833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (repeat > 0)
6843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
6853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *destination++=(unsigned char) (0x80 | (repeat-1));
6863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      *destination++=source[literal];
6873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
6883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(destination);
6893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
6903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6911e178e70fb3c956f9fc1e30c3ba863e882666465cristystatic MagickBooleanType WritePDBImage(const ImageInfo *image_info,Image *image,
6921e178e70fb3c956f9fc1e30c3ba863e882666465cristy  ExceptionInfo *exception)
6933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{
6943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const char
6953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *comment;
6963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int
6983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bits;
6993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MagickBooleanType
7013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    status;
7023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PDBImage
7043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pdb_image;
7053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  PDBInfo
7073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pdb_info;
7083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  QuantumInfo
7103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *quantum_info;
7113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7124c08aed51c5899665ade97263692328eea4af106cristy  register const Quantum
7133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *p;
7143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
715bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  register ssize_t
7163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    x;
7173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  register unsigned char
7193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *q;
7203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t
722aff6d807f839a998fff6e87198f2418868ab508ecristy    bits_per_pixel,
723aff6d807f839a998fff6e87198f2418868ab508ecristy    literal,
724aff6d807f839a998fff6e87198f2418868ab508ecristy    packets,
725aff6d807f839a998fff6e87198f2418868ab508ecristy    packet_size,
726aff6d807f839a998fff6e87198f2418868ab508ecristy    repeat;
727aff6d807f839a998fff6e87198f2418868ab508ecristy
728aff6d807f839a998fff6e87198f2418868ab508ecristy  ssize_t
729aff6d807f839a998fff6e87198f2418868ab508ecristy    y;
7303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned char
7323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *buffer,
7333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *runlength,
7343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    *scanline;
7353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
7373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Open output image file.
7383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
7393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info != (const ImageInfo *) NULL);
7403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image_info->signature == MagickSignature);
7413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image != (Image *) NULL);
7423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(image->signature == MagickSignature);
7433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->debug != MagickFalse)
7443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
7453a37efd7ece979e9c63dc8f2f2d3816bab8b1156cristy  assert(exception != (ExceptionInfo *) NULL);
7463a37efd7ece979e9c63dc8f2f2d3816bab8b1156cristy  assert(exception->signature == MagickSignature);
7471e178e70fb3c956f9fc1e30c3ba863e882666465cristy  status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
7483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (status == MagickFalse)
7493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return(status);
7503d9f5ba107b160e1819bb6baeeb3a9f521e9f450cristy  if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
7518d95109eca7aee289423a1ee81c232e309b383aecristy    (void) TransformImageColorspace(image,sRGBColorspace,exception);
7521e178e70fb3c956f9fc1e30c3ba863e882666465cristy  if (image -> colors <= 2  ||  GetImageType( image, exception ) == BilevelType) { /* TS */
7533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bits_per_pixel = 1;
7543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } else if (image -> colors <= 4) {
7553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bits_per_pixel = 2;
7563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } else if (image -> colors <= 8) {
7573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bits_per_pixel = 3;
7583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } else {
7593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    bits_per_pixel = 4;
7603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
7613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) ResetMagickMemory(pdb_info.name,0,32);
7633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(pdb_info.name,image_info->filename,32);
7643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.attributes=0;
7653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.version=0;
7663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.create_time=time(NULL);
7673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.modify_time=pdb_info.create_time;
7683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.archive_time=0;
7693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.modify_number=0;
7703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.application_info=0;
7713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.sort_info=0;
7723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickMemory(pdb_info.type,"vIMG",4);
7733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickMemory(pdb_info.id,"View",4);
7743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.seed=0;
7753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.next_record=0;
776d15e65928aec551b7388c2863de3e3e628e2e0ddcristy  comment=GetImageProperty(image,"comment",exception);
7773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_info.number_records=(comment == (const char *) NULL ? 1 : 2);
7783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,32,(unsigned char *) pdb_info.name);
7793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBShort(image,(unsigned short) pdb_info.attributes);
7803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBShort(image,(unsigned short) pdb_info.version);
781eaedf06777741da32408da72c1e512975c600c48cristy  (void) WriteBlobMSBLong(image,(unsigned int) pdb_info.create_time);
782eaedf06777741da32408da72c1e512975c600c48cristy  (void) WriteBlobMSBLong(image,(unsigned int) pdb_info.modify_time);
783eaedf06777741da32408da72c1e512975c600c48cristy  (void) WriteBlobMSBLong(image,(unsigned int) pdb_info.archive_time);
784eaedf06777741da32408da72c1e512975c600c48cristy  (void) WriteBlobMSBLong(image,(unsigned int) pdb_info.modify_number);
785eaedf06777741da32408da72c1e512975c600c48cristy  (void) WriteBlobMSBLong(image,(unsigned int) pdb_info.application_info);
786eaedf06777741da32408da72c1e512975c600c48cristy  (void) WriteBlobMSBLong(image,(unsigned int) pdb_info.sort_info);
7873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,(unsigned char *) pdb_info.type);
7883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,4,(unsigned char *) pdb_info.id);
789eaedf06777741da32408da72c1e512975c600c48cristy  (void) WriteBlobMSBLong(image,(unsigned int) pdb_info.seed);
790eaedf06777741da32408da72c1e512975c600c48cristy  (void) WriteBlobMSBLong(image,(unsigned int) pdb_info.next_record);
7913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBShort(image,(unsigned short) pdb_info.number_records);
7923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CopyMagickString(pdb_image.name,pdb_info.name,32);
7933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.version=1;  /* RLE Compressed */
7943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  switch (bits_per_pixel)
7953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
79693b02b797c4127ce2b06dbd3b2d75ecc33fca759dirk    case 1: pdb_image.type=(unsigned char) 0xff; break;  /* monochrome */
79793b02b797c4127ce2b06dbd3b2d75ecc33fca759dirk    case 2: pdb_image.type=(unsigned char) 0x00; break;  /* 2 bit gray */
79893b02b797c4127ce2b06dbd3b2d75ecc33fca759dirk    default: pdb_image.type=(unsigned char) 0x02;  /* 4 bit gray */
7993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
8003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.reserved_1=0;
8013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.note=0;
8023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.x_last=0;
8033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.y_last=0;
8043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.reserved_2=0;
80593b02b797c4127ce2b06dbd3b2d75ecc33fca759dirk  pdb_image.x_anchor=(unsigned short) 0xffff;
80693b02b797c4127ce2b06dbd3b2d75ecc33fca759dirk  pdb_image.y_anchor=(unsigned short) 0xffff;
8073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.width=(short) image->columns;
8083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (image->columns % 16)
8093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    pdb_image.width=(short) (16*(image->columns/16+1));
8103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  pdb_image.height=(short) image->rows;
8113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  packets=(bits_per_pixel*image->columns/8)*image->rows;
8123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  runlength=(unsigned char *) AcquireQuantumMemory(2UL*packets,
8133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sizeof(*runlength));
8143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (runlength == (unsigned char *) NULL)
8153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
8163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer=(unsigned char *) AcquireQuantumMemory(256UL,sizeof(*buffer));
8173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (buffer == (unsigned char *) NULL)
8183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
8193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  packet_size=(size_t) (image->depth > 8 ? 2: 1);
8203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  scanline=(unsigned char *) AcquireQuantumMemory(image->columns,packet_size*
8213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    sizeof(*scanline));
8223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (scanline == (unsigned char *) NULL)
8233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
8243d9f5ba107b160e1819bb6baeeb3a9f521e9f450cristy  if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse)
8258d95109eca7aee289423a1ee81c232e309b383aecristy    (void) TransformImageColorspace(image,sRGBColorspace,exception);
8263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
8273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Convert to GRAY raster scanline.
8283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
8293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info=AcquireQuantumInfo(image_info,image);
8303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (quantum_info == (QuantumInfo *) NULL)
8313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
832f9cca6af1ff9b913c32a2cec81eda059877a8832cristy  bits=8/(int) bits_per_pixel-1;  /* start at most significant bits */
8333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  literal=0;
8343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  repeat=0;
8353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  q=runlength;
8363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer[0]=0x00;
837bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  for (y=0; y < (ssize_t) image->rows; y++)
8383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  {
8391e178e70fb3c956f9fc1e30c3ba863e882666465cristy    p=GetVirtualPixels(image,0,y,image->columns,1,exception);
8404c08aed51c5899665ade97263692328eea4af106cristy    if (p == (const Quantum *) NULL)
8413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
8424c08aed51c5899665ade97263692328eea4af106cristy    (void) ExportQuantumPixels(image,(CacheView *) NULL,quantum_info,
8431e178e70fb3c956f9fc1e30c3ba863e882666465cristy      GrayQuantum,scanline,exception);
8443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    for (x=0; x < pdb_image.width; x++)
8453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
846bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy      if (x < (ssize_t) image->columns)
8473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        buffer[literal+repeat]|=(0xff-scanline[x*packet_size]) >>
8483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          (8-bits_per_pixel) << bits*bits_per_pixel;
8493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      bits--;
8503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (bits < 0)
8513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        {
8523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (((literal+repeat) > 0) &&
8533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              (buffer[literal+repeat] == buffer[literal+repeat-1]))
8543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
8553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (repeat == 0)
8563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
8573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  literal--;
8583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  repeat++;
8593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
8603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat++;
8613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (0x7f < repeat)
8623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
8633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q=EncodeRLE(q,buffer,literal,repeat);
8643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  literal=0;
8653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  repeat=0;
8663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
8673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
8683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          else
8693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            {
8703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (repeat >= 2)
8713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                literal+=repeat;
8723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              else
8733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
8743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q=EncodeRLE(q,buffer,literal,repeat);
8753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  buffer[0]=buffer[literal+repeat];
8763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  literal=0;
8773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
8783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              literal++;
8793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              repeat=0;
8803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              if (0x7f < literal)
8813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                {
8823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  q=EncodeRLE(q,buffer,(literal < 0x80 ? literal : 0x80),0);
8833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  (void) CopyMagickMemory(buffer,buffer+literal+repeat,0x80);
8843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                  literal-=0x80;
8853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                }
8863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            }
887f9cca6af1ff9b913c32a2cec81eda059877a8832cristy        bits=8/(int) bits_per_pixel-1;
8883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        buffer[literal+repeat]=0x00;
8893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
8903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
891cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy    status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,
892cee9711bbc334b5677d5ec4ea1cc70340d35ee35cristy                image->rows);
8933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (status == MagickFalse)
8943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      break;
8953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
8963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  q=EncodeRLE(q,buffer,literal,repeat);
8973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  scanline=(unsigned char *) RelinquishMagickMemory(scanline);
8983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  buffer=(unsigned char *) RelinquishMagickMemory(buffer);
8993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  quantum_info=DestroyQuantumInfo(quantum_info);
9003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
9013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Write the Image record header.
9023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
903f6fe0a138e6b5879b6c11a27d715412479acf128cristy  (void) WriteBlobMSBLong(image,(unsigned int)
9043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (TellBlob(image)+8*pdb_info.number_records));
9053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobByte(image,0x40);
9063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobByte(image,0x6f);
9073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobByte(image,0x80);
9083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobByte(image,0);
9093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (pdb_info.number_records > 1)
9103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    {
9113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      /*
9123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Write the comment record header.
9133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      */
914f6fe0a138e6b5879b6c11a27d715412479acf128cristy      (void) WriteBlobMSBLong(image,(unsigned int) (TellBlob(image)+8+58+q-
9153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        runlength));
9163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobByte(image,0x40);
9173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobByte(image,0x6f);
9183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobByte(image,0x80);
9193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      (void) WriteBlobByte(image,1);
9203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
9213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /*
9223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Write the Image data.
9233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  */
9243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,32,(unsigned char *) pdb_image.name);
9253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobByte(image,(unsigned char) pdb_image.version);
92693b02b797c4127ce2b06dbd3b2d75ecc33fca759dirk  (void) WriteBlobByte(image,pdb_image.type);
927eaedf06777741da32408da72c1e512975c600c48cristy  (void) WriteBlobMSBLong(image,(unsigned int) pdb_image.reserved_1);
928eaedf06777741da32408da72c1e512975c600c48cristy  (void) WriteBlobMSBLong(image,(unsigned int) pdb_image.note);
9293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBShort(image,(unsigned short) pdb_image.x_last);
9303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBShort(image,(unsigned short) pdb_image.y_last);
931eaedf06777741da32408da72c1e512975c600c48cristy  (void) WriteBlobMSBLong(image,(unsigned int) pdb_image.reserved_2);
93293b02b797c4127ce2b06dbd3b2d75ecc33fca759dirk  (void) WriteBlobMSBShort(image,pdb_image.x_anchor);
93393b02b797c4127ce2b06dbd3b2d75ecc33fca759dirk  (void) WriteBlobMSBShort(image,pdb_image.y_anchor);
9343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBShort(image,(unsigned short) pdb_image.width);
9353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlobMSBShort(image,(unsigned short) pdb_image.height);
9363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) WriteBlob(image,(size_t) (q-runlength),runlength);
9373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  runlength=(unsigned char *) RelinquishMagickMemory(runlength);
9383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (pdb_info.number_records > 1)
9393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    (void) WriteBlobString(image,comment);
9403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  (void) CloseBlob(image);
9413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return(MagickTrue);
9423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
943