Blame libdjvu/DjVuToPS.cpp

Packit df99a1
//C-  -*- C++ -*-
Packit df99a1
//C- -------------------------------------------------------------------
Packit df99a1
//C- DjVuLibre-3.5
Packit df99a1
//C- Copyright (c) 2002  Leon Bottou and Yann Le Cun.
Packit df99a1
//C- Copyright (c) 2001  AT&T
Packit df99a1
//C-
Packit df99a1
//C- This software is subject to, and may be distributed under, the
Packit df99a1
//C- GNU General Public License, either Version 2 of the license,
Packit df99a1
//C- or (at your option) any later version. The license should have
Packit df99a1
//C- accompanied the software or you may obtain a copy of the license
Packit df99a1
//C- from the Free Software Foundation at http://www.fsf.org .
Packit df99a1
//C-
Packit df99a1
//C- This program is distributed in the hope that it will be useful,
Packit df99a1
//C- but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit df99a1
//C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit df99a1
//C- GNU General Public License for more details.
Packit df99a1
//C- 
Packit df99a1
//C- DjVuLibre-3.5 is derived from the DjVu(r) Reference Library from
Packit df99a1
//C- Lizardtech Software.  Lizardtech Software has authorized us to
Packit df99a1
//C- replace the original DjVu(r) Reference Library notice by the following
Packit df99a1
//C- text (see doc/lizard2002.djvu and doc/lizardtech2007.djvu):
Packit df99a1
//C-
Packit df99a1
//C-  ------------------------------------------------------------------
Packit df99a1
//C- | DjVu (r) Reference Library (v. 3.5)
Packit df99a1
//C- | Copyright (c) 1999-2001 LizardTech, Inc. All Rights Reserved.
Packit df99a1
//C- | The DjVu Reference Library is protected by U.S. Pat. No.
Packit df99a1
//C- | 6,058,214 and patents pending.
Packit df99a1
//C- |
Packit df99a1
//C- | This software is subject to, and may be distributed under, the
Packit df99a1
//C- | GNU General Public License, either Version 2 of the license,
Packit df99a1
//C- | or (at your option) any later version. The license should have
Packit df99a1
//C- | accompanied the software or you may obtain a copy of the license
Packit df99a1
//C- | from the Free Software Foundation at http://www.fsf.org .
Packit df99a1
//C- |
Packit df99a1
//C- | The computer code originally released by LizardTech under this
Packit df99a1
//C- | license and unmodified by other parties is deemed "the LIZARDTECH
Packit df99a1
//C- | ORIGINAL CODE."  Subject to any third party intellectual property
Packit df99a1
//C- | claims, LizardTech grants recipient a worldwide, royalty-free, 
Packit df99a1
//C- | non-exclusive license to make, use, sell, or otherwise dispose of 
Packit df99a1
//C- | the LIZARDTECH ORIGINAL CODE or of programs derived from the 
Packit df99a1
//C- | LIZARDTECH ORIGINAL CODE in compliance with the terms of the GNU 
Packit df99a1
//C- | General Public License.   This grant only confers the right to 
Packit df99a1
//C- | infringe patent claims underlying the LIZARDTECH ORIGINAL CODE to 
Packit df99a1
//C- | the extent such infringement is reasonably necessary to enable 
Packit df99a1
//C- | recipient to make, have made, practice, sell, or otherwise dispose 
Packit df99a1
//C- | of the LIZARDTECH ORIGINAL CODE (or portions thereof) and not to 
Packit df99a1
//C- | any greater extent that may be necessary to utilize further 
Packit df99a1
//C- | modifications or combinations.
Packit df99a1
//C- |
Packit df99a1
//C- | The LIZARDTECH ORIGINAL CODE is provided "AS IS" WITHOUT WARRANTY
Packit df99a1
//C- | OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
Packit df99a1
//C- | TO ANY WARRANTY OF NON-INFRINGEMENT, OR ANY IMPLIED WARRANTY OF
Packit df99a1
//C- | MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
Packit df99a1
//C- +------------------------------------------------------------------
Packit df99a1
Packit df99a1
#ifdef HAVE_CONFIG_H
Packit df99a1
# include "config.h"
Packit df99a1
#endif
Packit df99a1
#if NEED_GNUG_PRAGMAS
Packit df99a1
# pragma implementation
Packit df99a1
#endif
Packit df99a1
Packit df99a1
#include "DjVuToPS.h"
Packit df99a1
#include "IFFByteStream.h"
Packit df99a1
#include "BSByteStream.h"
Packit df99a1
#include "DjVuImage.h"
Packit df99a1
#include "DjVuText.h"
Packit df99a1
#include "DataPool.h"
Packit df99a1
#include "IW44Image.h"
Packit df99a1
#include "JB2Image.h"
Packit df99a1
#include "GBitmap.h"
Packit df99a1
#include "GPixmap.h"
Packit df99a1
#include "debug.h"
Packit df99a1
#include <stdarg.h>
Packit df99a1
#include <stddef.h>
Packit df99a1
#include <stdlib.h>
Packit df99a1
#include <stdio.h>
Packit df99a1
#include <time.h>
Packit df99a1
#include <math.h>
Packit df99a1
#ifdef UNIX
Packit df99a1
#include <pwd.h>
Packit df99a1
#include <grp.h>
Packit df99a1
#include <unistd.h>
Packit df99a1
#endif
Packit df99a1
Packit df99a1
Packit df99a1
#ifdef HAVE_NAMESPACES
Packit df99a1
namespace DJVU {
Packit df99a1
# ifdef NOT_DEFINED // Just to fool emacs c++ mode
Packit df99a1
}
Packit df99a1
#endif
Packit df99a1
#endif
Packit df99a1
Packit df99a1
Packit df99a1
static const size_t ps_string_size=15000;
Packit df99a1
Packit df99a1
// ***************************************************************************
Packit df99a1
// ****************************** Options ************************************
Packit df99a1
// ***************************************************************************
Packit df99a1
Packit df99a1
DjVuToPS::Options::
Packit df99a1
Options(void)
Packit df99a1
: format(PS), 
Packit df99a1
  level(2), 
Packit df99a1
  orientation(AUTO), 
Packit df99a1
  mode(COLOR), 
Packit df99a1
  zoom(0),
Packit df99a1
  color(true), 
Packit df99a1
  calibrate(true), 
Packit df99a1
  text(false),
Packit df99a1
  gamma((double)2.2), 
Packit df99a1
  copies(1), 
Packit df99a1
  frame(false),
Packit df99a1
  cropmarks(false),
Packit df99a1
  bookletmode(OFF),
Packit df99a1
  bookletmax(0),
Packit df99a1
  bookletalign(0),
Packit df99a1
  bookletfold(18),
Packit df99a1
  bookletxfold(200)
Packit df99a1
{}
Packit df99a1
Packit df99a1
void
Packit df99a1
DjVuToPS::Options::
Packit df99a1
set_format(Format xformat)
Packit df99a1
{
Packit df99a1
  if (xformat != EPS && xformat != PS)
Packit df99a1
    G_THROW(ERR_MSG("DjVuToPS.bad_format"));
Packit df99a1
  format=xformat;
Packit df99a1
}
Packit df99a1
Packit df99a1
void
Packit df99a1
DjVuToPS::Options::
Packit df99a1
set_level(int xlevel)
Packit df99a1
{
Packit df99a1
  if (xlevel<1 || xlevel>3)
Packit df99a1
    G_THROW(ERR_MSG("DjVuToPS.bad_level")
Packit df99a1
           + GUTF8String("\t") + GUTF8String(xlevel));
Packit df99a1
  level=xlevel;
Packit df99a1
}
Packit df99a1
Packit df99a1
void
Packit df99a1
DjVuToPS::Options::
Packit df99a1
set_orientation(Orientation xorientation)
Packit df99a1
{
Packit df99a1
  if (xorientation!=PORTRAIT && 
Packit df99a1
      xorientation!=LANDSCAPE &&
Packit df99a1
      xorientation!=AUTO )
Packit df99a1
    G_THROW(ERR_MSG("DjVuToPS.bad_orient"));
Packit df99a1
  orientation=xorientation;
Packit df99a1
}
Packit df99a1
Packit df99a1
void
Packit df99a1
DjVuToPS::Options::
Packit df99a1
set_mode(Mode xmode)
Packit df99a1
{
Packit df99a1
  if (xmode!=COLOR && xmode!=FORE && xmode!=BACK && xmode!=BW)
Packit df99a1
    G_THROW(ERR_MSG("DjVuToPS.bad_mode"));
Packit df99a1
  mode=xmode;
Packit df99a1
}
Packit df99a1
Packit df99a1
void
Packit df99a1
DjVuToPS::Options::
Packit df99a1
set_zoom(int xzoom)
Packit df99a1
{
Packit df99a1
  if (xzoom!=0 && !(xzoom>=5 && xzoom<=999))
Packit df99a1
    G_THROW(ERR_MSG("DjVuToPS.bad_zoom"));
Packit df99a1
  zoom=xzoom;
Packit df99a1
}
Packit df99a1
Packit df99a1
void
Packit df99a1
DjVuToPS::Options::
Packit df99a1
set_color(bool xcolor)
Packit df99a1
{
Packit df99a1
  color=xcolor;
Packit df99a1
}
Packit df99a1
Packit df99a1
void 
Packit df99a1
DjVuToPS::Options::
Packit df99a1
set_sRGB(bool xcalibrate)
Packit df99a1
{
Packit df99a1
  calibrate=xcalibrate;
Packit df99a1
}
Packit df99a1
Packit df99a1
void
Packit df99a1
DjVuToPS::Options::
Packit df99a1
set_gamma(double xgamma)
Packit df99a1
{
Packit df99a1
  if  (xgamma<(double)(0.3-0.0001) || xgamma>(double)(5.0+0.0001))
Packit df99a1
    G_THROW(ERR_MSG("DjVuToPS.bad_gamma"));
Packit df99a1
  gamma=xgamma;
Packit df99a1
}
Packit df99a1
Packit df99a1
void
Packit df99a1
DjVuToPS::Options::
Packit df99a1
set_copies(int xcopies)
Packit df99a1
{
Packit df99a1
  if (xcopies<=0)
Packit df99a1
    G_THROW(ERR_MSG("DjVuToPS.bad_number"));
Packit df99a1
  copies=xcopies;
Packit df99a1
}
Packit df99a1
Packit df99a1
void
Packit df99a1
DjVuToPS::Options::
Packit df99a1
set_frame(bool xframe)
Packit df99a1
{
Packit df99a1
  frame=xframe;
Packit df99a1
}
Packit df99a1
Packit df99a1
void
Packit df99a1
DjVuToPS::Options::
Packit df99a1
set_cropmarks(bool xmarks)
Packit df99a1
{
Packit df99a1
  cropmarks=xmarks;
Packit df99a1
}
Packit df99a1
Packit df99a1
void
Packit df99a1
DjVuToPS::Options::
Packit df99a1
set_text(bool xtext)
Packit df99a1
{
Packit df99a1
  text=xtext;
Packit df99a1
}
Packit df99a1
Packit df99a1
void 
Packit df99a1
DjVuToPS::Options::
Packit df99a1
set_bookletmode(BookletMode m)
Packit df99a1
{
Packit df99a1
  bookletmode = m;
Packit df99a1
}
Packit df99a1
Packit df99a1
void 
Packit df99a1
DjVuToPS::Options::
Packit df99a1
set_bookletmax(int m)
Packit df99a1
{
Packit df99a1
  bookletmax = 0;
Packit df99a1
  if (m > 0)
Packit df99a1
    bookletmax = (m+3)/4;
Packit df99a1
  bookletmax *= 4;
Packit df99a1
}
Packit df99a1
Packit df99a1
void 
Packit df99a1
DjVuToPS::Options::
Packit df99a1
set_bookletalign(int m)
Packit df99a1
{
Packit df99a1
  bookletalign = m;
Packit df99a1
}
Packit df99a1
Packit df99a1
void 
Packit df99a1
DjVuToPS::Options::
Packit df99a1
set_bookletfold(int fold, int xfold)
Packit df99a1
{
Packit df99a1
  if (fold >= 0)
Packit df99a1
    bookletfold = fold;
Packit df99a1
  if (xfold >= 0)
Packit df99a1
    bookletxfold = xfold;
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
// ***************************************************************************
Packit df99a1
// ******************************* DjVuToPS **********************************
Packit df99a1
// ***************************************************************************
Packit df99a1
Packit df99a1
static char bin2hex[256][2];
Packit df99a1
Packit df99a1
DjVuToPS::DjVuToPS(void)
Packit df99a1
{
Packit df99a1
  DEBUG_MSG("DjVuToPS::DjVuToPS(): initializing...\n");
Packit df99a1
  DEBUG_MAKE_INDENT(3);
Packit df99a1
  DEBUG_MSG("Initializing dig2hex[]\n");
Packit df99a1
  // Creating tables for bin=>text translation
Packit df99a1
  static const char * dig2hex="0123456789ABCDEF";
Packit df99a1
  int i;
Packit df99a1
  for(i=0;i<256;i++)
Packit df99a1
    {
Packit df99a1
      bin2hex[i][0]=dig2hex[i/16];
Packit df99a1
      bin2hex[i][1]=dig2hex[i%16];
Packit df99a1
    }
Packit df99a1
  refresh_cb=0;
Packit df99a1
  refresh_cl_data=0;
Packit df99a1
  prn_progress_cb=0;
Packit df99a1
  prn_progress_cl_data=0;
Packit df99a1
  dec_progress_cb=0;
Packit df99a1
  dec_progress_cl_data=0;
Packit df99a1
  info_cb=0;
Packit df99a1
  info_cl_data=0;
Packit df99a1
}
Packit df99a1
Packit df99a1
#ifdef __GNUC__
Packit df99a1
static void
Packit df99a1
write(ByteStream &str, const char *format, ...)
Packit df99a1
__attribute__((format (printf, 2, 3)));
Packit df99a1
#endif
Packit df99a1
Packit df99a1
static void
Packit df99a1
write(ByteStream &str, const char *format, ...)
Packit df99a1
{
Packit df99a1
  /* Will output the formated string to the specified \Ref{ByteStream}
Packit df99a1
     like #fprintf# would do it for a #FILE#. */
Packit df99a1
  va_list args;
Packit df99a1
  va_start(args, format);
Packit df99a1
  GUTF8String tmp;
Packit df99a1
  tmp.vformat(format, args);
Packit df99a1
  str.writall((const char *) tmp, tmp.length());
Packit df99a1
}
Packit df99a1
Packit df99a1
// ************************* DOCUMENT LEVEL *********************************
Packit df99a1
Packit df99a1
void
Packit df99a1
DjVuToPS::
Packit df99a1
store_doc_prolog(ByteStream &str, int pages, int dpi, GRect *grect)
Packit df99a1
{
Packit df99a1
  /* Will store the {\em document prolog}, which is basically a
Packit df99a1
     block of document-level comments in PS DSC 3.0 format.
Packit df99a1
     @param str Stream where PostScript data should be written
Packit df99a1
     @param pages Total number of pages
Packit df99a1
     @param dpi (EPS mode only) 
Packit df99a1
     @param grect (EPS mode only) */
Packit df99a1
  DEBUG_MSG("storing the document prolog\n");
Packit df99a1
  DEBUG_MAKE_INDENT(3);
Packit df99a1
  if (options.get_format()==Options::EPS)
Packit df99a1
    write(str,
Packit df99a1
          "%%!PS-Adobe-3.0 EPSF 3.0\n"
Packit df99a1
          "%%%%BoundingBox: 0 0 %d %d\n",
Packit df99a1
          (grect->width()*100+dpi-1)/dpi, 
Packit df99a1
          (grect->height()*100+dpi-1)/dpi );
Packit df99a1
  else
Packit df99a1
    write(str, "%%!PS-Adobe-3.0\n");
Packit df99a1
  write(str,
Packit df99a1
        "%%%%Title: DjVu PostScript document\n"
Packit df99a1
        "%%%%Copyright: Copyright (c) 1998-1999 AT&T\n"
Packit df99a1
        "%%%%Creator: DjVu (code by Andrei Erofeev)\n"
Packit df99a1
        "%%%%DocumentData: Clean7Bit\n");
Packit df99a1
  // Date
Packit df99a1
  time_t tm=time(0);
Packit df99a1
  write(str, "%%%%CreationDate: %s", ctime(&tm));
Packit df99a1
  // For
Packit df99a1
#ifdef UNIX
Packit df99a1
  passwd *pswd = getpwuid(getuid());
Packit df99a1
  if (pswd)
Packit df99a1
    {
Packit df99a1
      char *s = strchr(pswd->pw_gecos, ',');
Packit df99a1
      if (s) 
Packit df99a1
        *s = 0;
Packit df99a1
      s = 0;
Packit df99a1
      if (pswd->pw_gecos && strlen(pswd->pw_gecos))
Packit df99a1
        s = pswd->pw_gecos;
Packit df99a1
      else if (pswd->pw_name && strlen(pswd->pw_name))
Packit df99a1
        s = pswd->pw_name;
Packit df99a1
      if (s)
Packit df99a1
        write(str, "%%%%For: %s\n", s);
Packit df99a1
    }
Packit df99a1
#endif
Packit df99a1
  // Language
Packit df99a1
  write(str, "%%%%LanguageLevel: %d\n", options.get_level());
Packit df99a1
  if (options.get_level()<2 && options.get_color())
Packit df99a1
    write(str, "%%%%Extensions: CMYK\n");
Packit df99a1
  // Pages
Packit df99a1
  write(str, "%%%%Pages: %d\n",pages );
Packit df99a1
  write(str, "%%%%PageOrder: Ascend\n");
Packit df99a1
  // Orientation
Packit df99a1
  if (options.get_orientation() != Options::AUTO)
Packit df99a1
    write(str, "%%%%Orientation: %s\n", 
Packit df99a1
          options.get_orientation()==Options::PORTRAIT ?
Packit df99a1
          "Portrait" : "Landscape" );
Packit df99a1
  // Requirements
Packit df99a1
  if (options.get_format() == Options::PS)
Packit df99a1
    {
Packit df99a1
      write(str, "%%%%Requirements:");
Packit df99a1
      if (options.get_color())
Packit df99a1
        write(str, " color");
Packit df99a1
      if (options.get_copies()>1)
Packit df99a1
        write(str, " numcopies(%d)", options.get_copies());
Packit df99a1
      if (options.get_level()>=2)
Packit df99a1
        {
Packit df99a1
          if (options.get_copies()>1)
Packit df99a1
            write(str, " collate");
Packit df99a1
          if (options.get_bookletmode() == Options::RECTOVERSO)
Packit df99a1
            write(str, " duplex(tumble)");
Packit df99a1
        }
Packit df99a1
      write(str, "\n");
Packit df99a1
    }
Packit df99a1
  // End
Packit df99a1
  write(str,
Packit df99a1
        "%%%%EndComments\n"
Packit df99a1
        "%%%%EndProlog\n"
Packit df99a1
        "\n");
Packit df99a1
}
Packit df99a1
Packit df99a1
void
Packit df99a1
DjVuToPS::
Packit df99a1
store_doc_setup(ByteStream &str)
Packit df99a1
{
Packit df99a1
  /* Will store the {\em document setup}, which is a set of
Packit df99a1
     PostScript commands and functions used to inspect and prepare
Packit df99a1
     the PostScript interpreter environment before displaying images. */
Packit df99a1
  write(str, 
Packit df99a1
        "%%%%BeginSetup\n"
Packit df99a1
        "/doc-origstate save def\n");
Packit df99a1
  if (options.get_level()>=2)
Packit df99a1
    {
Packit df99a1
      if (options.get_format() == Options::PS)
Packit df99a1
        {
Packit df99a1
          if (options.get_copies()>1)
Packit df99a1
            write(str, 
Packit df99a1
                  "[{\n"
Packit df99a1
                  "%%%%BeginFeature: NumCopies %d\n"
Packit df99a1
                  "<< /NumCopies %d >> setpagedevice\n"
Packit df99a1
                  "%%%%EndFeature\n"
Packit df99a1
                  "} stopped cleartomark\n"
Packit df99a1
                  "[{\n"
Packit df99a1
                  "%%%%BeginFeature: Collate\n"
Packit df99a1
                  "<< /Collate true >> setpagedevice\n"
Packit df99a1
                  "%%%%EndFeature\n"
Packit df99a1
                  "} stopped cleartomark\n",
Packit df99a1
                  options.get_copies(),
Packit df99a1
                  options.get_copies() );
Packit df99a1
          if (options.get_bookletmode()==Options::RECTOVERSO)
Packit df99a1
            write(str, 
Packit df99a1
                  "[{\n"
Packit df99a1
                  "%%%%BeginFeature: Duplex DuplexTumble\n"
Packit df99a1
                  "<< /Duplex true /Tumble true >> setpagedevice\n"
Packit df99a1
                  "%%%%EndFeature\n"
Packit df99a1
                  "} stopped cleartomark\n");
Packit df99a1
        }
Packit df99a1
      if (options.get_color())
Packit df99a1
        write(str, 
Packit df99a1
              "%% -- procs for reading color image\n"
Packit df99a1
              "/readR () def\n"
Packit df99a1
              "/readG () def\n"
Packit df99a1
              "/readB () def\n"
Packit df99a1
              "/ReadData {\n"
Packit df99a1
              "   currentfile /ASCII85Decode filter dup\n"
Packit df99a1
              "   /RunLengthDecode filter\n"
Packit df99a1
              "   bufferR readstring pop /readR exch def\n"
Packit df99a1
              "   dup status { flushfile } { pop } ifelse\n"
Packit df99a1
              "   currentfile /ASCII85Decode filter dup\n"
Packit df99a1
              "   /RunLengthDecode filter\n"
Packit df99a1
              "   bufferG readstring pop /readG exch def\n"
Packit df99a1
              "   dup status { flushfile } { pop } ifelse\n"
Packit df99a1
              "   currentfile /ASCII85Decode filter dup\n"
Packit df99a1
              "   /RunLengthDecode filter\n"
Packit df99a1
              "   bufferB readstring pop /readB exch def\n"
Packit df99a1
              "   dup status { flushfile } { pop } ifelse\n"
Packit df99a1
              "} bind def\n"
Packit df99a1
              "/ReadR {\n"
Packit df99a1
              "   readR length 0 eq { ReadData } if\n"
Packit df99a1
              "   readR /readR () def\n"
Packit df99a1
              "} bind def\n"
Packit df99a1
              "/ReadG {\n"
Packit df99a1
              "   readG length 0 eq { ReadData } if\n"
Packit df99a1
              "   readG /readG () def\n"
Packit df99a1
              "} bind def\n"
Packit df99a1
              "/ReadB {\n"
Packit df99a1
              "   readB length 0 eq { ReadData } if\n"
Packit df99a1
              "   readB /readB () def\n"
Packit df99a1
              "} bind def\n");
Packit df99a1
      write(str,
Packit df99a1
            "%% -- procs for foreground layer\n"
Packit df99a1
            "/g {gsave 0 0 0 0 5 index 5 index setcachedevice\n"
Packit df99a1
            "    true [1 0 0 1 0 0] 5 4 roll imagemask grestore\n"
Packit df99a1
            "} bind def\n"
Packit df99a1
            "/gn {gsave 0 0 0 0 6 index 6 index setcachedevice\n"
Packit df99a1
            "  true [1 0 0 1 0 0] 3 2 roll 5 1 roll \n"
Packit df99a1
            "  { 1 sub 0 index 2 add 1 index  1 add roll\n"
Packit df99a1
            "  } imagemask grestore pop \n"
Packit df99a1
            "} bind def\n"
Packit df99a1
            "/c {setcolor rmoveto glyphshow} bind def\n"
Packit df99a1
            "/s {rmoveto glyphshow} bind def\n"
Packit df99a1
            "/S {rmoveto gsave show grestore} bind def\n" 
Packit df99a1
            "/F {(Helvetica) findfont exch scalefont setfont} bind def\n"
Packit df99a1
            "%% -- emulations\n"
Packit df99a1
            "systemdict /rectstroke known not {\n"
Packit df99a1
            "  /rectstroke  %% stack : x y width height \n"
Packit df99a1
            "  { newpath 4 2 roll moveto 1 index 0 rlineto\n"
Packit df99a1
            "    0 exch rlineto neg 0 rlineto closepath stroke\n"
Packit df99a1
            "  } bind def } if\n"
Packit df99a1
            "systemdict /rectclip known not {\n"
Packit df99a1
            "  /rectclip  %% stack : x y width height \n"
Packit df99a1
            "  { newpath 4 2 roll moveto 1 index 0 rlineto\n"
Packit df99a1
            "    0 exch rlineto neg 0 rlineto closepath clip\n"
Packit df99a1
            "  } bind def } if\n"
Packit df99a1
            "%% -- color space\n" );
Packit df99a1
      if (options.get_sRGB())
Packit df99a1
        write(str,
Packit df99a1
              "/DjVuColorSpace [ %s\n"
Packit df99a1
              "<< /DecodeLMN [ { dup 0.03928 le {\n"
Packit df99a1
              "       12.92321 div\n"
Packit df99a1
              "     } {\n"
Packit df99a1
              "       0.055 add 1.055 div 2.4 exp\n"
Packit df99a1
              "     } ifelse } bind dup dup ]\n"
Packit df99a1
              "   /MatrixLMN [\n"
Packit df99a1
              "      0.412457 0.212673 0.019334\n"
Packit df99a1
              "      0.357576 0.715152 0.119192\n"
Packit df99a1
              "      0.180437 0.072175 0.950301 ]\n"
Packit df99a1
              "   /WhitePoint [ 0.9505 1 1.0890 ] %% D65 \n"
Packit df99a1
              "   /BlackPoint[0 0 0] >> ] def\n",
Packit df99a1
              (options.get_color()) ? "/CIEBasedABC" : "/CIEBasedA" );
Packit df99a1
      else if (options.get_color())
Packit df99a1
        write(str,"/DjVuColorSpace /DeviceRGB def\n");
Packit df99a1
      else
Packit df99a1
        write(str,"/DjVuColorSpace /DeviceGray def\n");
Packit df99a1
    } 
Packit df99a1
  else 
Packit df99a1
    {
Packit df99a1
      // level<2
Packit df99a1
      if (options.get_format() == Options::PS)
Packit df99a1
        if (options.get_copies() > 1)
Packit df99a1
          write(str,"/#copies %d def\n", options.get_copies());
Packit df99a1
      if (options.get_color())
Packit df99a1
        write(str, 
Packit df99a1
              "%% -- buffers for reading image\n"
Packit df99a1
              "/buffer8 () def\n"
Packit df99a1
              "/buffer24 () def\n"
Packit df99a1
              "%% -- colorimage emulation\n"
Packit df99a1
              "systemdict /colorimage known {\n"
Packit df99a1
              "   /ColorProc {\n"
Packit df99a1
              "      currentfile buffer24 readhexstring pop\n"
Packit df99a1
              "   } bind def\n"
Packit df99a1
              "   /ColorImage {\n"
Packit df99a1
              "      colorimage\n"
Packit df99a1
              "   } bind def\n"
Packit df99a1
              "} {\n"
Packit df99a1
              "   /ColorProc {\n"
Packit df99a1
              "      currentfile buffer24 readhexstring pop\n"
Packit df99a1
              "      /data exch def /datalen data length def\n"
Packit df99a1
              "      /cnt 0 def\n"
Packit df99a1
              "      0 1 datalen 3 idiv 1 sub {\n"
Packit df99a1
              "         buffer8 exch\n"
Packit df99a1
              "                data cnt get 20 mul /cnt cnt 1 add def\n"
Packit df99a1
              "                data cnt get 32 mul /cnt cnt 1 add def\n"
Packit df99a1
              "                data cnt get 12 mul /cnt cnt 1 add def\n"
Packit df99a1
              "                add add 64 idiv put\n"
Packit df99a1
              "      } for\n"
Packit df99a1
              "      buffer8 0 datalen 3 idiv getinterval\n"
Packit df99a1
              "   } bind def\n"
Packit df99a1
              "   /ColorImage {\n"
Packit df99a1
              "      pop pop image\n"
Packit df99a1
              "   } bind def\n"
Packit df99a1
              "} ifelse\n");
Packit df99a1
    } // level<2
Packit df99a1
  write(str, "%%%%EndSetup\n\n");
Packit df99a1
}
Packit df99a1
Packit df99a1
void
Packit df99a1
DjVuToPS::
Packit df99a1
store_doc_trailer(ByteStream &str)
Packit df99a1
{
Packit df99a1
  /* Will store the {\em document trailer}, which is a clean-up code
Packit df99a1
     used to return the PostScript interpeter back to the state, in which
Packit df99a1
     it was before displaying this document. */
Packit df99a1
  write(str, 
Packit df99a1
        "%%%%Trailer\n"
Packit df99a1
        "doc-origstate restore\n"
Packit df99a1
        "%%%%EOF\n");
Packit df99a1
}
Packit df99a1
Packit df99a1
// ***********************************************************************
Packit df99a1
// ***************************** PAGE LEVEL ******************************
Packit df99a1
// ***********************************************************************
Packit df99a1
Packit df99a1
static unsigned char *
Packit df99a1
ASCII85_encode(unsigned char * dst, 
Packit df99a1
               const unsigned char * src_start,
Packit df99a1
               const unsigned char * src_end)
Packit df99a1
{
Packit df99a1
  /* Will read data between #src_start# and #src_end# pointers (excluding byte
Packit df99a1
     pointed by #src_end#), encode it using {\bf ASCII85} algorithm, and
Packit df99a1
     output the result into the destination buffer pointed by #dst#.  The
Packit df99a1
     function returns pointer to the first unused byte in the destination
Packit df99a1
     buffer. */
Packit df99a1
  int symbols=0;
Packit df99a1
  const unsigned char * ptr;
Packit df99a1
  for(ptr=src_start;ptr
Packit df99a1
    {
Packit df99a1
      unsigned int num=0;
Packit df99a1
      if (ptr+3
Packit df99a1
        {
Packit df99a1
          num |= ptr[0] << 24; 
Packit df99a1
          num |= ptr[1] << 16; 
Packit df99a1
          num |= ptr[2] << 8; 
Packit df99a1
          num |= ptr[3];
Packit df99a1
        }
Packit df99a1
      else
Packit df99a1
        {
Packit df99a1
          num |= ptr[0] << 24; 
Packit df99a1
          if (ptr+1
Packit df99a1
            num |= ptr[1] << 16; 
Packit df99a1
          if (ptr+2
Packit df99a1
            num |= ptr[2] << 8; 
Packit df99a1
        }
Packit df99a1
      int a1, a2, a3, a4, a5;
Packit df99a1
      a5=num % 85; num/=85;
Packit df99a1
      a4=num % 85; num/=85;
Packit df99a1
      a3=num % 85; num/=85;
Packit df99a1
      a2=num % 85;
Packit df99a1
      a1=num / 85;
Packit df99a1
      *dst++ = a1+33;
Packit df99a1
      *dst++ = a2+33;
Packit df99a1
      if (ptr+1
Packit df99a1
        *dst++ = a3+33;
Packit df99a1
      if (ptr+2
Packit df99a1
        *dst++ = a4+33;
Packit df99a1
      if (ptr+3
Packit df99a1
        *dst++ = a5+33;
Packit df99a1
      symbols += 5;
Packit df99a1
      if (symbols > 70 && ptr+4
Packit df99a1
        { 
Packit df99a1
          *dst++='\n'; 
Packit df99a1
          symbols=0; 
Packit df99a1
        }
Packit df99a1
    }
Packit df99a1
  return dst;
Packit df99a1
}
Packit df99a1
Packit df99a1
static unsigned char *
Packit df99a1
RLE_encode(unsigned char * dst,
Packit df99a1
           const unsigned char * src_start,
Packit df99a1
           const unsigned char * src_end)
Packit df99a1
{
Packit df99a1
  /* Will read data between #src_start# and #src_end# pointers (excluding byte
Packit df99a1
     pointed by #src_end#), RLE encode it, and output the result into the
Packit df99a1
     destination buffer pointed by #dst#.  #counter# is used to count the
Packit df99a1
     number of output bytes.  The function returns pointer to the first unused
Packit df99a1
     byte in the destination buffer. */
Packit df99a1
  const unsigned char * ptr;
Packit df99a1
  for(ptr=src_start;ptr
Packit df99a1
    {
Packit df99a1
      if (ptr==src_end-1)
Packit df99a1
        {
Packit df99a1
          *dst++=0; *dst++=*ptr;
Packit df99a1
        } 
Packit df99a1
      else if (ptr[0]!=ptr[1])
Packit df99a1
        {
Packit df99a1
          // Guess how many non repeating bytes we have
Packit df99a1
          const unsigned char * ptr1;
Packit df99a1
          for(ptr1=ptr+1;ptr1
Packit df99a1
            if (ptr1[0]==ptr1[1] || ptr1-ptr>=128) break;
Packit df99a1
          int pixels=ptr1-ptr;
Packit df99a1
          *dst++=pixels-1;
Packit df99a1
          for(int cnt=0;cnt
Packit df99a1
            *dst++=*ptr++;
Packit df99a1
          ptr--;
Packit df99a1
        } 
Packit df99a1
      else
Packit df99a1
        {
Packit df99a1
          // Get the number of repeating bytes
Packit df99a1
          const unsigned char * ptr1;
Packit df99a1
          for(ptr1=ptr+1;ptr1
Packit df99a1
            if (ptr1[0]!=ptr1[1] || ptr1-ptr+1>=128) break;
Packit df99a1
          int pixels=ptr1-ptr+1;
Packit df99a1
          *dst++=257-pixels;
Packit df99a1
          *dst++=*ptr;
Packit df99a1
          ptr=ptr1;
Packit df99a1
        }
Packit df99a1
    }
Packit df99a1
  return dst;
Packit df99a1
}
Packit df99a1
Packit df99a1
#define GRAY(r,g,b) (((r)*20+(g)*32+(b)*12)/64)
Packit df99a1
Packit df99a1
void
Packit df99a1
DjVuToPS::
Packit df99a1
store_page_setup(ByteStream &str, 
Packit df99a1
                 int dpi, 
Packit df99a1
                 const GRect &grect, 
Packit df99a1
                 int align )
Packit df99a1
{
Packit df99a1
  /* Will store PostScript code necessary to prepare page for
Packit df99a1
     the coming \Ref{DjVuImage}. This is basically a scaling
Packit df99a1
     code plus initialization of some buffers. */
Packit df99a1
  if (options.get_format() == Options::EPS)
Packit df99a1
    write(str, 
Packit df99a1
          "/page-origstate save def\n"
Packit df99a1
          "%% -- coordinate system\n"
Packit df99a1
          "/image-dpi %d def\n"
Packit df99a1
          "/image-x 0 def\n"
Packit df99a1
          "/image-y 0 def\n"
Packit df99a1
          "/image-width  %d def\n"
Packit df99a1
          "/image-height %d def\n"
Packit df99a1
          "/coeff 100 image-dpi div def\n"
Packit df99a1
          "/a11 coeff def\n"
Packit df99a1
          "/a12 0 def\n"
Packit df99a1
          "/a13 0 def\n"
Packit df99a1
          "/a21 0 def\n"
Packit df99a1
          "/a22 coeff def\n"
Packit df99a1
          "/a23 0 def\n"
Packit df99a1
          "[a11 a21 a12 a22 a13 a23] concat\n"
Packit df99a1
          "gsave 0 0 image-width image-height rectclip\n"
Packit df99a1
          "%% -- begin printing\n",
Packit df99a1
          dpi, grect.width(), grect.height() );
Packit df99a1
  else
Packit df99a1
    {
Packit df99a1
      int margin = 0;
Packit df99a1
      const char *xauto = "false";
Packit df99a1
      const char *xportrait = "false";
Packit df99a1
      const char *xfit = "false";
Packit df99a1
      if (options.get_orientation()==Options::AUTO)
Packit df99a1
        xauto = "true";
Packit df99a1
      if (options.get_orientation()==Options::PORTRAIT)
Packit df99a1
        xportrait = "true";
Packit df99a1
      if (options.get_zoom()<=0)
Packit df99a1
        xfit = "true";
Packit df99a1
      if (options.get_cropmarks())
Packit df99a1
        margin = 36;
Packit df99a1
      else if (options.get_frame())
Packit df99a1
        margin = 6;
Packit df99a1
      write(str, 
Packit df99a1
            "/page-origstate save def\n"
Packit df99a1
            "%% -- coordinate system\n"
Packit df99a1
            "/auto-orient %s def\n"
Packit df99a1
            "/portrait %s def\n"
Packit df99a1
            "/fit-page %s def\n"
Packit df99a1
            "/zoom %d def\n"
Packit df99a1
            "/image-dpi %d def\n"
Packit df99a1
            "clippath pathbbox newpath\n"
Packit df99a1
            "2 index sub exch 3 index sub\n"
Packit df99a1
            "/page-width exch def\n"
Packit df99a1
            "/page-height exch def\n"
Packit df99a1
            "/page-y exch def\n"
Packit df99a1
            "/page-x exch def\n"
Packit df99a1
            "/image-x 0 def\n"
Packit df99a1
            "/image-y 0 def\n"
Packit df99a1
            "/image-width  %d def\n"
Packit df99a1
            "/image-height %d def\n"
Packit df99a1
            "/margin %d def\n"
Packit df99a1
            "/halign %d def\n"
Packit df99a1
            "/valign 0 def\n",
Packit df99a1
            xauto, xportrait, xfit, options.get_zoom(), 
Packit df99a1
            dpi, grect.width(), grect.height(),
Packit df99a1
            margin, align );
Packit df99a1
      write(str, 
Packit df99a1
            "%% -- position page\n"
Packit df99a1
            "auto-orient {\n"
Packit df99a1
            "  image-height image-width sub\n"
Packit df99a1
            "  page-height page-width sub\n"
Packit df99a1
            "  mul 0 ge /portrait exch def\n" 
Packit df99a1
            "} if\n"
Packit df99a1
            "fit-page {\n"
Packit df99a1
            "  /page-width page-width margin sub\n"
Packit df99a1
            "     halign 0 eq { margin sub } if def\n"
Packit df99a1
            "  /page-height page-height margin sub\n"
Packit df99a1
            "     valign 0 eq { margin sub } if def\n"
Packit df99a1
            "  /page-x page-x halign 0 ge { margin add } if def\n"
Packit df99a1
            "  /page-y page-y valign 0 ge { margin add } if def\n"
Packit df99a1
            "} if\n"
Packit df99a1
            "portrait {\n"
Packit df99a1
            "  fit-page {\n"
Packit df99a1
            "    image-height page-height div\n"
Packit df99a1
            "    image-width page-width div\n"
Packit df99a1
            "    gt {\n"
Packit df99a1
            "      page-height image-height div /coeff exch def\n"
Packit df99a1
            "    } {\n"
Packit df99a1
            "      page-width image-width div /coeff exch def\n"
Packit df99a1
            "    } ifelse\n"
Packit df99a1
            "  } {\n"
Packit df99a1
            "    /coeff 72 image-dpi div zoom mul 100 div def\n"
Packit df99a1
            "  } ifelse\n"
Packit df99a1
            "  /start-x page-x page-width image-width\n"
Packit df99a1
            "    coeff mul sub 2 div halign 1 add mul add def\n"
Packit df99a1
            "  /start-y page-y page-height image-height\n"
Packit df99a1
            "    coeff mul sub 2 div valign 1 add mul add def\n"
Packit df99a1
            "  /a11 coeff def\n"
Packit df99a1
            "  /a12 0 def\n"
Packit df99a1
            "  /a13 start-x def\n"
Packit df99a1
            "  /a21 0 def\n"
Packit df99a1
            "  /a22 coeff def\n"
Packit df99a1
            "  /a23 start-y def\n"
Packit df99a1
            "} { %% landscape\n"
Packit df99a1
            "  fit-page {\n"
Packit df99a1
            "    image-height page-width div\n"
Packit df99a1
            "    image-width page-height div\n"
Packit df99a1
            "    gt {\n"
Packit df99a1
            "      page-width image-height div /coeff exch def\n"
Packit df99a1
            "    } {\n"
Packit df99a1
            "      page-height image-width div /coeff exch def\n"
Packit df99a1
            "    } ifelse\n"
Packit df99a1
            "  } {\n"
Packit df99a1
            "    /coeff 72 image-dpi div zoom mul 100 div def\n"
Packit df99a1
            "  } ifelse\n"
Packit df99a1
            "  /start-x page-x page-width add page-width image-height\n"
Packit df99a1
            "    coeff mul sub 2 div valign 1 add mul sub def\n"
Packit df99a1
            "  /start-y page-y page-height image-width\n"
Packit df99a1
            "    coeff mul sub 2 div halign 1 add mul add def\n"
Packit df99a1
            "  /a11 0 def\n"
Packit df99a1
            "  /a12 coeff neg def\n"
Packit df99a1
            "  /a13 start-x image-y coeff neg mul sub def\n"
Packit df99a1
            "  /a21 coeff def\n"
Packit df99a1
            "  /a22 0 def\n"
Packit df99a1
            "  /a23 start-y image-x coeff mul add def \n"
Packit df99a1
            "} ifelse\n"
Packit df99a1
            "[a11 a21 a12 a22 a13 a23] concat\n"
Packit df99a1
            "gsave 0 0 image-width image-height rectclip\n"
Packit df99a1
            "%% -- begin print\n");
Packit df99a1
    }
Packit df99a1
}
Packit df99a1
Packit df99a1
void
Packit df99a1
DjVuToPS::
Packit df99a1
store_page_trailer(ByteStream &str)
Packit df99a1
{
Packit df99a1
  write(str, 
Packit df99a1
        "%% -- end print\n" 
Packit df99a1
        "grestore\n");
Packit df99a1
  if (options.get_frame())
Packit df99a1
    write(str, 
Packit df99a1
          "%% Drawing frame\n"
Packit df99a1
          "gsave 0.7 setgray 0.5 coeff div setlinewidth 0 0\n"
Packit df99a1
          "image-width image-height rectstroke\n"
Packit df99a1
          "grestore\n");
Packit df99a1
  if (options.get_cropmarks() &&
Packit df99a1
      options.get_format() != Options::EPS )
Packit df99a1
    write(str,
Packit df99a1
          "%% Drawing crop marks\n"
Packit df99a1
          "/cm { gsave translate rotate 1 coeff div dup scale\n"
Packit df99a1
          "      0 setgray 0.5 setlinewidth -36 0 moveto 0 0 lineto\n"
Packit df99a1
          "      0 -36 lineto stroke grestore } bind def\n"
Packit df99a1
          "0 0 0 cm 180 image-width image-height cm\n"
Packit df99a1
          "90 image-width 0 cm 270 0 image-height cm\n");
Packit df99a1
  write(str,
Packit df99a1
        "page-origstate restore\n");
Packit df99a1
}
Packit df99a1
Packit df99a1
static int
Packit df99a1
compute_red(int w, int h, int rw, int rh)
Packit df99a1
{
Packit df99a1
  for (int red=1; red<16; red++)
Packit df99a1
    if (((w+red-1)/red==rw) && ((h+red-1)/red==rh))
Packit df99a1
      return red;
Packit df99a1
  return 16;
Packit df99a1
}
Packit df99a1
Packit df99a1
static int
Packit df99a1
get_bg_red(GP<DjVuImage> dimg) 
Packit df99a1
{
Packit df99a1
  GP<GPixmap> pm = 0;
Packit df99a1
  // Access image size
Packit df99a1
  int width = dimg->get_width();
Packit df99a1
  int height = dimg->get_height();
Packit df99a1
  if (width<=0 || height<=0) return 0;
Packit df99a1
  // CASE1: Incremental BG IW44Image
Packit df99a1
  GP<IW44Image> bg44 = dimg->get_bg44();
Packit df99a1
  if (bg44)
Packit df99a1
    {
Packit df99a1
      int w = bg44->get_width();
Packit df99a1
      int h = bg44->get_height();
Packit df99a1
      // Avoid silly cases
Packit df99a1
      if (w==0 || h==0 || width==0 || height==0)
Packit df99a1
        return 0;
Packit df99a1
      return compute_red(width,height,w,h);
Packit df99a1
    }
Packit df99a1
  // CASE 2: Raw background pixmap
Packit df99a1
  GP<GPixmap>  bgpm = dimg->get_bgpm();
Packit df99a1
  if (bgpm)
Packit df99a1
    {
Packit df99a1
      int w = bgpm->columns();
Packit df99a1
      int h = bgpm->rows();
Packit df99a1
      // Avoid silly cases
Packit df99a1
      if (w==0 || h==0 || width==0 || height==0)
Packit df99a1
        return 0;
Packit df99a1
      return compute_red(width,height,w,h);
Packit df99a1
    }
Packit df99a1
  return 0;
Packit df99a1
}
Packit df99a1
Packit df99a1
static GP<GPixmap>
Packit df99a1
get_bg_pixmap(GP<DjVuImage> dimg, const GRect &rect)
Packit df99a1
{
Packit df99a1
  GP<GPixmap> pm = 0;
Packit df99a1
  // Access image size
Packit df99a1
  int width = dimg->get_width();
Packit df99a1
  int height = dimg->get_height();
Packit df99a1
  GP<DjVuInfo> info = dimg->get_info();
Packit df99a1
  if (width<=0 || height<=0 || !info) return 0;
Packit df99a1
  // CASE1: Incremental BG IW44Image
Packit df99a1
  GP<IW44Image> bg44 = dimg->get_bg44();
Packit df99a1
  if (bg44)
Packit df99a1
    {
Packit df99a1
      int w = bg44->get_width();
Packit df99a1
      int h = bg44->get_height();
Packit df99a1
      // Avoid silly cases
Packit df99a1
      if (w==0 || h==0 || width==0 || height==0)
Packit df99a1
        return 0;
Packit df99a1
      pm = bg44->get_pixmap(1,rect);
Packit df99a1
      return pm;
Packit df99a1
    }
Packit df99a1
  // CASE 2: Raw background pixmap
Packit df99a1
  GP<GPixmap>  bgpm = dimg->get_bgpm();
Packit df99a1
  if (bgpm)
Packit df99a1
    {
Packit df99a1
      int w = bgpm->columns();
Packit df99a1
      int h = bgpm->rows();
Packit df99a1
      // Avoid silly cases
Packit df99a1
      if (w==0 || h==0 || width==0 || height==0)
Packit df99a1
        return 0;
Packit df99a1
      pm->init(*bgpm, rect);
Packit df99a1
      return pm;
Packit df99a1
    }
Packit df99a1
  // FAILURE
Packit df99a1
  return 0;
Packit df99a1
}
Packit df99a1
Packit df99a1
void 
Packit df99a1
DjVuToPS::
Packit df99a1
make_gamma_ramp(GP<DjVuImage> dimg)
Packit df99a1
{
Packit df99a1
  double targetgamma = options.get_gamma();
Packit df99a1
  double whitepoint = (options.get_sRGB() ? 255 : 280);
Packit df99a1
  for (int i=0; i<256; i++)
Packit df99a1
    ramp[i] = i;
Packit df99a1
  if (! dimg->get_info()) 
Packit df99a1
    return;
Packit df99a1
  if (targetgamma < 0.1)
Packit df99a1
    return;
Packit df99a1
  double filegamma = dimg->get_info()->gamma;
Packit df99a1
  double correction = filegamma / targetgamma;
Packit df99a1
  if (correction<0.1 || correction>10)
Packit df99a1
    return;
Packit df99a1
  {
Packit df99a1
    for (int i=0; i<256; i++)
Packit df99a1
    {
Packit df99a1
      double x = (double)(i)/255.0;
Packit df99a1
      if (correction != 1.0) 
Packit df99a1
        x = pow(x, correction);        
Packit df99a1
      int j = (int) floor(whitepoint * x + 0.5);
Packit df99a1
      ramp[i] = (j>255) ? 255 : (j<0) ? 0 : j;
Packit df99a1
    }
Packit df99a1
  }
Packit df99a1
}
Packit df99a1
Packit df99a1
void
Packit df99a1
DjVuToPS::
Packit df99a1
print_fg_2layer(ByteStream &str, 
Packit df99a1
                GP<DjVuImage> dimg,
Packit df99a1
                const GRect &prn_rect, 
Packit df99a1
                unsigned char *blit_list)
Packit df99a1
{
Packit df99a1
  // Pure-jb2 or color-jb2 case.
Packit df99a1
  GPixel p;
Packit df99a1
  int currentx=0;
Packit df99a1
  int currenty=0;
Packit df99a1
  GP<DjVuPalette> pal = dimg->get_fgbc();
Packit df99a1
  GP<JB2Image> jb2 = dimg->get_fgjb();
Packit df99a1
  if (! jb2) return;
Packit df99a1
  int num_blits = jb2->get_blit_count();
Packit df99a1
  int current_blit;
Packit df99a1
  for(current_blit=0; current_blit
Packit df99a1
    {
Packit df99a1
      if (blit_list[current_blit])
Packit df99a1
        {
Packit df99a1
          JB2Blit *blit = jb2->get_blit(current_blit);
Packit df99a1
          if ((pal) && !(options.get_mode()==Options::BW))
Packit df99a1
            {
Packit df99a1
              pal->index_to_color(pal->colordata[current_blit], p);
Packit df99a1
              if (options.get_color())
Packit df99a1
                {
Packit df99a1
                  write(str,"/%d %d %d %f %f %f c\n",
Packit df99a1
                        blit->shapeno, 
Packit df99a1
                        blit->left-currentx, blit->bottom-currenty,
Packit df99a1
                        ramp[p.r]/255.0, ramp[p.g]/255.0, ramp[p.b]/255.0);
Packit df99a1
                } 
Packit df99a1
              else
Packit df99a1
                {
Packit df99a1
                  write(str,"/%d %d %d %f c\n",
Packit df99a1
                        blit->shapeno, 
Packit df99a1
                        blit->left-currentx, blit->bottom-currenty,
Packit df99a1
                        ramp[GRAY(p.r, p.g, p.b)]/255.0);
Packit df99a1
                }
Packit df99a1
            }
Packit df99a1
          else
Packit df99a1
            {
Packit df99a1
              write(str,"/%d %d %d s\n", 
Packit df99a1
                    blit->shapeno, 
Packit df99a1
                    blit->left-currentx, blit->bottom-currenty);
Packit df99a1
            }
Packit df99a1
          currentx = blit->left;
Packit df99a1
          currenty = blit->bottom;
Packit df99a1
        }
Packit df99a1
    }
Packit df99a1
}
Packit df99a1
Packit df99a1
void
Packit df99a1
DjVuToPS::
Packit df99a1
print_fg_3layer(ByteStream &str, 
Packit df99a1
                GP<DjVuImage> dimg,
Packit df99a1
                const GRect &cprn_rect, 
Packit df99a1
                unsigned char *blit_list )
Packit df99a1
{
Packit df99a1
  GRect prn_rect;
Packit df99a1
  GP<GPixmap> brush = dimg->get_fgpm();
Packit df99a1
  if (! brush) return;
Packit df99a1
  int br = brush->rows();
Packit df99a1
  int bc = brush->columns();
Packit df99a1
  int red = compute_red(dimg->get_width(),dimg->get_height(),bc,br);
Packit df99a1
  prn_rect.ymin = (cprn_rect.ymin)/red;
Packit df99a1
  prn_rect.xmin = (cprn_rect.xmin)/red;
Packit df99a1
  prn_rect.ymax = (cprn_rect.ymax+red-1)/red;
Packit df99a1
  prn_rect.xmax = (cprn_rect.xmax+red-1)/red;
Packit df99a1
  int color_nb = ((options.get_color()) ? 3 : 1);
Packit df99a1
  GP<JB2Image> jb2 = dimg->get_fgjb();
Packit df99a1
  if (! jb2) return;
Packit df99a1
  int pw = bc;
Packit df99a1
  int ph = 2;
Packit df99a1
Packit df99a1
  write(str,
Packit df99a1
        "/P {\n" 
Packit df99a1
        "  11 dict dup begin 4 1 roll\n"
Packit df99a1
        "    /PatternType 1 def\n"
Packit df99a1
        "    /PaintType 1 def\n"
Packit df99a1
        "    /TilingType 1 def\n"
Packit df99a1
        "    /H exch def\n"
Packit df99a1
        "    /W exch def\n"
Packit df99a1
        "    /Red %d def\n"
Packit df99a1
        "    /PatternString exch def\n"
Packit df99a1
        "    /XStep W Red mul def\n"
Packit df99a1
        "    /YStep H Red mul def\n"
Packit df99a1
        "    /BBox [0 0 XStep YStep] def\n"
Packit df99a1
        "    /PaintProc { begin\n"
Packit df99a1
        "       Red dup scale\n"
Packit df99a1
        "       << /ImageType 1 /Width W /Height H\n"
Packit df99a1
        "          /BitsPerComponent 8 /Interpolate false\n"
Packit df99a1
        "          /Decode [%s] /ImageMatrix [1 0 0 1 0 0]\n"
Packit df99a1
        "          /DataSource PatternString >> image\n"
Packit df99a1
        "       end } bind def\n"
Packit df99a1
        "     0 0 XStep YStep rectclip\n"
Packit df99a1
        "     end matrix makepattern\n"
Packit df99a1
        "  /Pattern setcolorspace setpattern\n"
Packit df99a1
        "  0 0 moveto\n"
Packit df99a1
        "} def\n", red, (color_nb == 1) ? "0 1" : "0 1 0 1 0 1" );
Packit df99a1
Packit df99a1
  unsigned char *s;
Packit df99a1
  GPBuffer<unsigned char> gs(s,pw*ph*color_nb);
Packit df99a1
  unsigned char *s_ascii_encoded;
Packit df99a1
  GPBuffer<unsigned char> gs_ascii_encoded(s_ascii_encoded,pw*ph*2*color_nb);
Packit df99a1
    {
Packit df99a1
      for (int y=prn_rect.ymin; y
Packit df99a1
        for (int x=prn_rect.xmin; x
Packit df99a1
          {
Packit df99a1
            int w = ((x+pw > prn_rect.xmax) ? prn_rect.xmax-x : pw);
Packit df99a1
            int h = ((y+ph > prn_rect.ymax) ? prn_rect.ymax-y : ph);
Packit df99a1
            int currentx = x * red;
Packit df99a1
            int currenty = y * red;
Packit df99a1
            // Find first intersecting blit
Packit df99a1
            int current_blit;
Packit df99a1
            int num_blits = jb2->get_blit_count();
Packit df99a1
            GRect rect1(currentx,currenty, w*red, h*red);
Packit df99a1
            for(current_blit=0; current_blit
Packit df99a1
              if (blit_list[current_blit])
Packit df99a1
                {
Packit df99a1
                  JB2Blit *blit = jb2->get_blit(current_blit);
Packit df99a1
                  GRect rect2(blit->left, blit->bottom,
Packit df99a1
                              jb2->get_shape(blit->shapeno).bits->columns(),
Packit df99a1
                              jb2->get_shape(blit->shapeno).bits->rows());
Packit df99a1
                  if (rect2.intersect(rect1,rect2)) 
Packit df99a1
                    break;
Packit df99a1
                }
Packit df99a1
            if (current_blit >= num_blits)
Packit df99a1
              continue;
Packit df99a1
            // Setup pattern
Packit df99a1
            write(str,"gsave %d %d translate\n", currentx, currenty);
Packit df99a1
            write(str,"<~");
Packit df99a1
            unsigned char *q = s;
Packit df99a1
            for(int current_row = y; current_row
Packit df99a1
              { 
Packit df99a1
                GPixel *row_pix = (*brush)[current_row];
Packit df99a1
                for(int current_col = x; current_col
Packit df99a1
                  { 
Packit df99a1
                    GPixel &p = row_pix[current_col];
Packit df99a1
                    if (color_nb>1)
Packit df99a1
                      {
Packit df99a1
                        *q++ = ramp[p.r];
Packit df99a1
                        *q++ = ramp[p.g];
Packit df99a1
                        *q++ = ramp[p.b];
Packit df99a1
                      }
Packit df99a1
                    else
Packit df99a1
                      {
Packit df99a1
                        *q++ = ramp[GRAY(p.r,p.g,p.b)];
Packit df99a1
                      }
Packit df99a1
                  }
Packit df99a1
              }
Packit df99a1
            unsigned char *stop_ascii = 
Packit df99a1
              ASCII85_encode(s_ascii_encoded,s,s+w*h*color_nb);
Packit df99a1
            *stop_ascii++='\0';
Packit df99a1
            write(str,"%s",s_ascii_encoded);
Packit df99a1
            write(str,"~> %d %d P\n", w, h);
Packit df99a1
            // Keep performing blits
Packit df99a1
            for(; current_blit
Packit df99a1
              if (blit_list[current_blit])
Packit df99a1
                {
Packit df99a1
                  JB2Blit *blit = jb2->get_blit(current_blit);
Packit df99a1
                  GRect rect2(blit->left, blit->bottom,
Packit df99a1
                              jb2->get_shape(blit->shapeno).bits->columns(),
Packit df99a1
                              jb2->get_shape(blit->shapeno).bits->rows()); 
Packit df99a1
                  if (rect2.intersect(rect1,rect2)) 
Packit df99a1
                    {   
Packit df99a1
                      write(str,"/%d %d %d s\n",
Packit df99a1
                            blit->shapeno, 
Packit df99a1
                            blit->left-currentx, blit->bottom-currenty);
Packit df99a1
                      currentx = blit->left;
Packit df99a1
                      currenty = blit->bottom;
Packit df99a1
                    }
Packit df99a1
                }
Packit df99a1
            write(str,"grestore\n");
Packit df99a1
          }
Packit df99a1
      // Cleanup
Packit df99a1
    }
Packit df99a1
}
Packit df99a1
Packit df99a1
void
Packit df99a1
DjVuToPS::
Packit df99a1
print_fg(ByteStream &str, 
Packit df99a1
         GP<DjVuImage> dimg,
Packit df99a1
         const GRect &prn_rect )
Packit df99a1
{
Packit df99a1
  GP<JB2Image> jb2=dimg->get_fgjb();
Packit df99a1
  if (! jb2) return;
Packit df99a1
  int num_blits = jb2->get_blit_count();
Packit df99a1
  int num_shapes = jb2->get_shape_count();
Packit df99a1
  unsigned char *dict_shapes = 0;
Packit df99a1
  unsigned char *blit_list = 0;
Packit df99a1
  GPBuffer<unsigned char> gdict_shapes(dict_shapes,num_shapes);
Packit df99a1
  GPBuffer<unsigned char> gblit_list(blit_list,num_blits);
Packit df99a1
  for(int i=0; i
Packit df99a1
  {
Packit df99a1
    dict_shapes[i]=0;
Packit df99a1
  }
Packit df99a1
  for(int current_blit=0; current_blit
Packit df99a1
  {
Packit df99a1
    JB2Blit *blit = jb2->get_blit(current_blit);
Packit df99a1
    JB2Shape *shape = & jb2->get_shape(blit->shapeno);
Packit df99a1
    blit_list[current_blit] = 0;
Packit df99a1
    if (! shape->bits) 
Packit df99a1
      continue;
Packit df99a1
    GRect rect2(blit->left, blit->bottom, 
Packit df99a1
      shape->bits->columns(), shape->bits->rows());
Packit df99a1
    if (rect2.intersect(rect2, prn_rect))
Packit df99a1
    {
Packit df99a1
      dict_shapes[blit->shapeno] = 1;
Packit df99a1
      blit_list[current_blit] = 1;
Packit df99a1
    }
Packit df99a1
  }
Packit df99a1
  write(str,
Packit df99a1
    "%% --- now doing the foreground\n"
Packit df99a1
    "gsave DjVuColorSpace setcolorspace\n" );
Packit df99a1
      // Define font
Packit df99a1
  write(str,
Packit df99a1
    "/$DjVuLocalFont 7 dict def\n"
Packit df99a1
    "$DjVuLocalFont begin\n"
Packit df99a1
    "/FontType 3 def \n"
Packit df99a1
    "/FontMatrix [1 0 0 1 0 0] def\n"
Packit df99a1
    "/FontBBox [0 0 1 .5] def\n"
Packit df99a1
    "/CharStrings %d dict def\n"
Packit df99a1
    "/Encoding 2 array def\n"
Packit df99a1
    "0 1 1 {Encoding exch /.notdef put} for \n"
Packit df99a1
    "CharStrings begin\n"
Packit df99a1
    "/.notdef {} def\n",
Packit df99a1
    num_shapes+1);
Packit df99a1
  for(int current_shape=0; current_shape
Packit df99a1
  {
Packit df99a1
    if (dict_shapes[current_shape])
Packit df99a1
    {
Packit df99a1
      JB2Shape *shape = & jb2->get_shape(current_shape);
Packit df99a1
      GP<GBitmap> bitmap = shape->bits;
Packit df99a1
      int rows = bitmap->rows();
Packit df99a1
      int columns = bitmap->columns();
Packit df99a1
      int nbytes = (columns+7)/8*rows+1;
Packit df99a1
      int nrows = rows;
Packit df99a1
      int nstrings=0;
Packit df99a1
      if (nbytes>(int)ps_string_size)   //max string length
Packit df99a1
      {
Packit df99a1
        nrows=ps_string_size/((columns+7)/8);
Packit df99a1
        nbytes=(columns+7)/8*nrows+1;
Packit df99a1
      }
Packit df99a1
      unsigned char *s_start;
Packit df99a1
      GPBuffer<unsigned char> gs_start(s_start,nbytes);
Packit df99a1
      unsigned char *s_ascii;
Packit df99a1
      GPBuffer<unsigned char> gs_ascii(s_ascii,nbytes*2);
Packit df99a1
      write(str,"/%d {",current_shape);
Packit df99a1
Packit df99a1
      unsigned char *s = s_start;
Packit df99a1
      for(int current_row=0; current_row
Packit df99a1
      {  
Packit df99a1
        unsigned char * row_bits = (*bitmap)[current_row];
Packit df99a1
        unsigned char acc = 0;
Packit df99a1
        unsigned char mask = 0;
Packit df99a1
        for(int current_col=0; current_col
Packit df99a1
        {
Packit df99a1
          if (mask == 0)
Packit df99a1
            mask = 0x80;
Packit df99a1
          if (row_bits[current_col])
Packit df99a1
            acc |= mask;
Packit df99a1
          mask >>= 1;
Packit df99a1
          if (mask == 0)
Packit df99a1
          {
Packit df99a1
            *s=acc;
Packit df99a1
            s++;
Packit df99a1
            acc = mask = 0;
Packit df99a1
          }
Packit df99a1
        }
Packit df99a1
        if (mask != 0)
Packit df99a1
        {
Packit df99a1
          *s=acc;
Packit df99a1
          s++;
Packit df99a1
        }
Packit df99a1
        if (!((current_row+1)%nrows))
Packit df99a1
        {
Packit df99a1
          unsigned char *stop_ascii = ASCII85_encode(s_ascii,s_start,s); 
Packit df99a1
          *stop_ascii++='\0';
Packit df99a1
          write(str,"<~%s~> ",s_ascii);
Packit df99a1
          s=s_start;
Packit df99a1
          nstrings++;
Packit df99a1
        }
Packit df99a1
      }
Packit df99a1
      if (s!=s_start)
Packit df99a1
      {
Packit df99a1
        unsigned char *stop_ascii = ASCII85_encode(s_ascii,s_start,s);
Packit df99a1
        *stop_ascii++='\0';
Packit df99a1
        write(str,"<~%s~> ",s_ascii);
Packit df99a1
          nstrings++;
Packit df99a1
      }
Packit df99a1
      if (nstrings==1)
Packit df99a1
        write(str," %d %d g} def\n", columns, rows);                  
Packit df99a1
      else
Packit df99a1
        write(str," %d %d %d gn} def\n", columns, rows,nstrings);
Packit df99a1
    }
Packit df99a1
  }
Packit df99a1
  write(str, 
Packit df99a1
    "end\n"
Packit df99a1
    "/BuildGlyph {\n"
Packit df99a1
    "  exch /CharStrings get exch\n"
Packit df99a1
    "  2 copy known not\n"
Packit df99a1
    "  {pop /.notdef} if\n"
Packit df99a1
    "  get exec \n"
Packit df99a1
    "} bind def\n"
Packit df99a1
    "end\n"
Packit df99a1
    "/LocalDjVuFont $DjVuLocalFont definefont pop\n"
Packit df99a1
    "/LocalDjVuFont findfont setfont\n" );
Packit df99a1
  write(str,
Packit df99a1
    "-%d -%d translate\n"
Packit df99a1
    "0 0 moveto\n",
Packit df99a1
    prn_rect.xmin, prn_rect.ymin);
Packit df99a1
  // Print the foreground layer
Packit df99a1
  if (dimg->get_fgpm() && !(options.get_mode()==Options::BW)) 
Packit df99a1
    print_fg_3layer(str, dimg, prn_rect, blit_list);
Packit df99a1
  else
Packit df99a1
    print_fg_2layer(str, dimg, prn_rect, blit_list);        
Packit df99a1
  write(str, "/LocalDjVuFont undefinefont grestore\n");
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
void 
Packit df99a1
DjVuToPS::
Packit df99a1
print_bg(ByteStream &str, 
Packit df99a1
         GP<DjVuImage> dimg,
Packit df99a1
         const GRect &cprn_rect)
Packit df99a1
{
Packit df99a1
  GP<GPixmap> pm;
Packit df99a1
  GRect prn_rect;
Packit df99a1
  double print_done = 0;
Packit df99a1
  int red = 0;
Packit df99a1
  write(str, "%% --- now doing the background\n");
Packit df99a1
  if (! (red = get_bg_red(dimg)))
Packit df99a1
    return;
Packit df99a1
  write(str, 
Packit df99a1
        "gsave -%d -%d translate\n"
Packit df99a1
        "/bgred %d def bgred bgred scale\n",
Packit df99a1
        cprn_rect.xmin % red, 
Packit df99a1
        cprn_rect.ymin % red, 
Packit df99a1
        red);
Packit df99a1
  prn_rect.ymin = (cprn_rect.ymin)/red;
Packit df99a1
  prn_rect.ymax = (cprn_rect.ymax+red-1)/red;
Packit df99a1
  prn_rect.xmin = (cprn_rect.xmin)/red;
Packit df99a1
  prn_rect.xmax = (cprn_rect.xmax+red-1)/red;
Packit df99a1
  // Display image
Packit df99a1
  int band_bytes = 125000;
Packit df99a1
  int band_height = band_bytes/prn_rect.width();
Packit df99a1
  int buffer_size = band_height*prn_rect.width();
Packit df99a1
  int ps_chunk_height = 30960/prn_rect.width()+1;
Packit df99a1
  buffer_size = buffer_size*23/10;
Packit df99a1
  bool do_color = options.get_color();
Packit df99a1
  if ((!dimg->is_legal_photo() &&
Packit df99a1
       !dimg->is_legal_compound())
Packit df99a1
      || options.get_mode()==Options::BW)
Packit df99a1
    do_color = false;
Packit df99a1
  if (do_color) 
Packit df99a1
    buffer_size *= 3;
Packit df99a1
  if (do_color)
Packit df99a1
    write(str, 
Packit df99a1
          "/bufferR %d string def\n"
Packit df99a1
          "/bufferG %d string def\n"
Packit df99a1
          "/bufferB %d string def\n"
Packit df99a1
          "DjVuColorSpace setcolorspace\n"
Packit df99a1
          "<< /ImageType 1\n"
Packit df99a1
          "   /Width %d\n"
Packit df99a1
          "   /Height %d\n"
Packit df99a1
          "   /BitsPerComponent 8\n"
Packit df99a1
          "   /Decode [0 1 0 1 0 1]\n"
Packit df99a1
          "   /ImageMatrix [1 0 0 1 0 0]\n"
Packit df99a1
          "   /MultipleDataSources true\n"
Packit df99a1
          "   /DataSource [ { ReadR } { ReadG } { ReadB } ]\n"
Packit df99a1
          "   /Interpolate false >> image\n",
Packit df99a1
          ps_chunk_height*prn_rect.width(),
Packit df99a1
          ps_chunk_height*prn_rect.width(),
Packit df99a1
          ps_chunk_height*prn_rect.width(),
Packit df99a1
          prn_rect.width(), prn_rect.height());
Packit df99a1
  else
Packit df99a1
    write(str, 
Packit df99a1
          "DjVuColorSpace setcolorspace\n"
Packit df99a1
          "<< /ImageType 1\n"
Packit df99a1
          "   /Width %d\n"
Packit df99a1
          "   /Height %d\n"
Packit df99a1
          "   /BitsPerComponent 8\n"
Packit df99a1
          "   /Decode [0 1]\n"
Packit df99a1
          "   /ImageMatrix [1 0 0 1 0 0]\n"
Packit df99a1
          "   /DataSource currentfile /ASCII85Decode\n"
Packit df99a1
          "      filter /RunLengthDecode filter\n"
Packit df99a1
          "   /Interpolate false >> image\n",
Packit df99a1
          prn_rect.width(), prn_rect.height());
Packit df99a1
  
Packit df99a1
  unsigned char *buffer;
Packit df99a1
  GPBuffer<unsigned char> gbuffer(buffer,buffer_size);
Packit df99a1
  unsigned char *rle_in;
Packit df99a1
  GPBuffer<unsigned char> grle_in(rle_in,ps_chunk_height*prn_rect.width());
Packit df99a1
  unsigned char *rle_out;
Packit df99a1
  GPBuffer<unsigned char> grle_out(rle_out,2*ps_chunk_height*prn_rect.width());
Packit df99a1
  {
Packit df99a1
    // Start storing image in bands
Packit df99a1
    unsigned char * rle_out_end = rle_out;
Packit df99a1
    GRect grectBand = prn_rect;
Packit df99a1
    grectBand.ymax = grectBand.ymin;
Packit df99a1
    while(grectBand.ymax < prn_rect.ymax)
Packit df99a1
      {
Packit df99a1
        GP<GPixmap> pm = 0;
Packit df99a1
        // Compute next band
Packit df99a1
        grectBand.ymin=grectBand.ymax;
Packit df99a1
        grectBand.ymax=grectBand.ymin+band_bytes/grectBand.width();
Packit df99a1
        if (grectBand.ymax>prn_rect.ymax)
Packit df99a1
          grectBand.ymax=prn_rect.ymax;
Packit df99a1
        pm = get_bg_pixmap(dimg, grectBand);
Packit df99a1
        unsigned char *buf_ptr = buffer;
Packit df99a1
        if (pm)
Packit df99a1
          {
Packit df99a1
            if (do_color)
Packit df99a1
              {
Packit df99a1
                int y=0;
Packit df99a1
                while(y
Packit df99a1
                  {
Packit df99a1
                    int row, y1;
Packit df99a1
                    unsigned char *ptr, *ptr1;
Packit df99a1
                    // Doing R component of current chunk
Packit df99a1
                    for (row=0,ptr=rle_in,y1=y; 
Packit df99a1
                         row
Packit df99a1
                         row++,y1++)
Packit df99a1
                      {
Packit df99a1
                        GPixel *pix = (*pm)[y1];
Packit df99a1
                        for (int x=grectBand.width(); x>0; x--,pix++)
Packit df99a1
                          *ptr++ = ramp[pix->r];
Packit df99a1
                      }
Packit df99a1
                    ptr1 = RLE_encode(rle_out, rle_in, ptr); 
Packit df99a1
                    *ptr1++ = 0x80;
Packit df99a1
                    buf_ptr = ASCII85_encode(buf_ptr, rle_out, ptr1);
Packit df99a1
                    *buf_ptr++ = '~'; *buf_ptr++ = '>'; *buf_ptr++ = '\n';
Packit df99a1
                    // Doing G component of current chunk
Packit df99a1
                    for (row=0,ptr=rle_in,y1=y; 
Packit df99a1
                         row
Packit df99a1
                         row++,y1++)
Packit df99a1
                      {
Packit df99a1
                        GPixel *pix = (*pm)[y1];
Packit df99a1
                        for (int x=grectBand.width(); x>0; x--,pix++)
Packit df99a1
                          *ptr++ = ramp[pix->g];
Packit df99a1
                      }
Packit df99a1
                    ptr1 = RLE_encode(rle_out, rle_in, ptr); 
Packit df99a1
                    *ptr1++ = 0x80;
Packit df99a1
                    buf_ptr = ASCII85_encode(buf_ptr, rle_out, ptr1);
Packit df99a1
                    *buf_ptr++ = '~'; 
Packit df99a1
                    *buf_ptr++ = '>'; 
Packit df99a1
                    *buf_ptr++ = '\n';
Packit df99a1
                    // Doing B component of current chunk
Packit df99a1
                    for (row=0, ptr=rle_in, y1=y;
Packit df99a1
                         row
Packit df99a1
                         row++,y1++)
Packit df99a1
                      {
Packit df99a1
                        GPixel *pix = (*pm)[y1];
Packit df99a1
                        for (int x=grectBand.width(); x>0; x--,pix++)
Packit df99a1
                          *ptr++ = ramp[pix->b];
Packit df99a1
                      }
Packit df99a1
                    ptr1 = RLE_encode(rle_out, rle_in, ptr);
Packit df99a1
                    *ptr1++ = 0x80;
Packit df99a1
                    buf_ptr = ASCII85_encode(buf_ptr, rle_out, ptr1);
Packit df99a1
                    *buf_ptr++ = '~'; 
Packit df99a1
                    *buf_ptr++ = '>'; 
Packit df99a1
                    *buf_ptr++ = '\n';
Packit df99a1
                    y=y1;
Packit df99a1
                    if (refresh_cb) 
Packit df99a1
                      refresh_cb(refresh_cl_data);
Packit df99a1
                  } //while (y>=0)
Packit df99a1
              } 
Packit df99a1
            else
Packit df99a1
              {
Packit df99a1
                // Don't use color
Packit df99a1
                int y=0;
Packit df99a1
                while(y
Packit df99a1
                  {
Packit df99a1
                    unsigned char *ptr = rle_in;
Packit df99a1
                    for(int row=0; 
Packit df99a1
                        row
Packit df99a1
                        row++,y++)
Packit df99a1
                      {
Packit df99a1
                        GPixel *pix = (*pm)[y];
Packit df99a1
                        for (int x=grectBand.width(); x>0; x--,pix++)
Packit df99a1
                          *ptr++ = ramp[GRAY(pix->r,pix->g,pix->b)];
Packit df99a1
                      }
Packit df99a1
                    rle_out_end = RLE_encode(rle_out_end, rle_in, ptr);
Packit df99a1
                    unsigned char *encode_to 
Packit df99a1
                      = rle_out+(rle_out_end-rle_out)/4*4;
Packit df99a1
                    int bytes_left = rle_out_end-encode_to;
Packit df99a1
                    buf_ptr = ASCII85_encode(buf_ptr, rle_out, encode_to);
Packit df99a1
                    *buf_ptr++ = '\n';
Packit df99a1
                    memcpy(rle_out, encode_to, bytes_left);
Packit df99a1
                    rle_out_end = rle_out+bytes_left;
Packit df99a1
                    if (refresh_cb) 
Packit df99a1
                      refresh_cb(refresh_cl_data);
Packit df99a1
                  }
Packit df99a1
              }
Packit df99a1
          } // if (pm)
Packit df99a1
        str.writall(buffer, buf_ptr-buffer);
Packit df99a1
        if (prn_progress_cb)
Packit df99a1
          {
Packit df99a1
            double done=(double)(grectBand.ymax 
Packit df99a1
                                 - prn_rect.ymin)/prn_rect.height();
Packit df99a1
            if ((int) (20*print_done)!=(int) (20*done))
Packit df99a1
              {
Packit df99a1
                print_done=done;
Packit df99a1
                prn_progress_cb(done, prn_progress_cl_data);
Packit df99a1
              }
Packit df99a1
          }
Packit df99a1
      } // while(grectBand.yax
Packit df99a1
    if (! do_color)
Packit df99a1
      {
Packit df99a1
        unsigned char * buf_ptr = buffer;
Packit df99a1
        *rle_out_end++ = 0x80;
Packit df99a1
        buf_ptr = ASCII85_encode(buf_ptr, rle_out, rle_out_end);
Packit df99a1
        *buf_ptr++='~'; 
Packit df99a1
        *buf_ptr++='>'; 
Packit df99a1
        *buf_ptr++='\n';
Packit df99a1
        str.writall(buffer, buf_ptr-buffer);
Packit df99a1
      }
Packit df99a1
  } 
Packit df99a1
  //restore the scaling
Packit df99a1
  write(str, "grestore\n");
Packit df99a1
}
Packit df99a1
Packit df99a1
void
Packit df99a1
DjVuToPS::
Packit df99a1
print_image_lev1(ByteStream &str, 
Packit df99a1
                 GP<DjVuImage> dimg,
Packit df99a1
                 const GRect &prn_rect)
Packit df99a1
{         
Packit df99a1
  double print_done=0;
Packit df99a1
  GRect all(0,0, dimg->get_width(),dimg->get_height());
Packit df99a1
  GP<GPixmap> pm;
Packit df99a1
  GP<GBitmap> bm;
Packit df99a1
  GRect test(0,0,1,1);
Packit df99a1
  if (options.get_mode() == Options::FORE)
Packit df99a1
    pm = dimg->get_fg_pixmap(test, all);
Packit df99a1
  else if (options.get_mode() == Options::BACK)
Packit df99a1
    pm = dimg->get_bg_pixmap(test, all);
Packit df99a1
  else if (options.get_mode() != Options::BW)
Packit df99a1
    pm = dimg->get_pixmap(test, all);
Packit df99a1
  if (! pm)
Packit df99a1
    bm = dimg->get_bitmap(test,all);
Packit df99a1
  if (! pm && ! bm)
Packit df99a1
    return;
Packit df99a1
  write(str,
Packit df99a1
        "%% --- now doing a level 1 image\n"
Packit df99a1
        "gsave\n");
Packit df99a1
  // Display image
Packit df99a1
  int band_bytes=125000;
Packit df99a1
  int band_height = band_bytes/prn_rect.width();
Packit df99a1
  int buffer_size = band_height*prn_rect.width();
Packit df99a1
  buffer_size = buffer_size*21/10;
Packit df99a1
  bool do_color = false;
Packit df99a1
  bool do_color_or_gray = false;
Packit df99a1
  if (pm && (options.get_mode() != Options::BW))
Packit df99a1
    do_color_or_gray = true;
Packit df99a1
  if (do_color_or_gray && options.get_color())
Packit df99a1
    do_color = true;
Packit df99a1
  if (do_color) 
Packit df99a1
    buffer_size *= 3;
Packit df99a1
  if (do_color)
Packit df99a1
    write(str, "/buffer24 %d string def\n", 3*prn_rect.width());
Packit df99a1
  if (do_color_or_gray)
Packit df99a1
    write(str, "/buffer8 %d string def\n", prn_rect.width());
Packit df99a1
  else
Packit df99a1
    write(str, "/buffer8 %d string def\n", (prn_rect.width()+7)/8);
Packit df99a1
  if (do_color)
Packit df99a1
    {
Packit df99a1
      write(str,
Packit df99a1
            "%d %d 8 [ 1 0 0 1 0 0 ]\n"
Packit df99a1
            "{ ColorProc } false 3 ColorImage\n",
Packit df99a1
            prn_rect.width(), prn_rect.height());
Packit df99a1
    } 
Packit df99a1
  else if (do_color_or_gray)
Packit df99a1
    {
Packit df99a1
      write(str,
Packit df99a1
            "%d %d 8 [ 1 0 0 1 0 0 ]\n"
Packit df99a1
            "{ currentfile buffer8 readhexstring pop } image\n",
Packit df99a1
            prn_rect.width(), prn_rect.height());
Packit df99a1
    } 
Packit df99a1
  else
Packit df99a1
    {
Packit df99a1
      write(str,
Packit df99a1
            "%d %d 1 [ 1 0 0 1 0 0 ]\n"
Packit df99a1
            "{ currentfile buffer8 readhexstring pop } image\n",
Packit df99a1
            prn_rect.width(), prn_rect.height());
Packit df99a1
    }
Packit df99a1
  unsigned char * buffer;
Packit df99a1
  GPBuffer<unsigned char> gbuffer(buffer,buffer_size);
Packit df99a1
    {
Packit df99a1
      // Start storing image in bands
Packit df99a1
      GRect grectBand = prn_rect;
Packit df99a1
      grectBand.ymax = grectBand.ymin;
Packit df99a1
      while(grectBand.ymax < prn_rect.ymax)
Packit df99a1
        {
Packit df99a1
          // Compute next band
Packit df99a1
          grectBand.ymin = grectBand.ymax;
Packit df99a1
          grectBand.ymax = grectBand.ymin+band_bytes/grectBand.width();
Packit df99a1
          if (grectBand.ymax > prn_rect.ymax)
Packit df99a1
            grectBand.ymax = prn_rect.ymax;
Packit df99a1
          GRect all(0,0, dimg->get_width(),dimg->get_height());
Packit df99a1
          pm = 0;
Packit df99a1
          bm = 0;
Packit df99a1
          if (do_color_or_gray)
Packit df99a1
            {
Packit df99a1
              if (options.get_mode() == Options::FORE)
Packit df99a1
                pm = dimg->get_fg_pixmap(grectBand, all);
Packit df99a1
              else if (options.get_mode() == Options::BACK)
Packit df99a1
                pm = dimg->get_bg_pixmap(grectBand, all);
Packit df99a1
              else
Packit df99a1
                pm = dimg->get_pixmap(grectBand, all);
Packit df99a1
            }
Packit df99a1
          else 
Packit df99a1
            {
Packit df99a1
              bm = dimg->get_bitmap(grectBand, all);
Packit df99a1
            }
Packit df99a1
          // Store next band
Packit df99a1
          unsigned char *buf_ptr = buffer;
Packit df99a1
          int symbols=0;
Packit df99a1
          for (int y=0; y
Packit df99a1
            {
Packit df99a1
              if (pm && do_color_or_gray)
Packit df99a1
                {
Packit df99a1
                  GPixel *pix = (*pm)[y];
Packit df99a1
                  for (int x=grectBand.width(); x>0; x--, pix++)
Packit df99a1
                    {
Packit df99a1
                      if (do_color)
Packit df99a1
                        {
Packit df99a1
                          char *data;
Packit df99a1
                          data = bin2hex[ramp[pix->r]];
Packit df99a1
                          *buf_ptr++ = data[0];
Packit df99a1
                          *buf_ptr++ = data[1];
Packit df99a1
                          data = bin2hex[ramp[pix->g]];
Packit df99a1
                          *buf_ptr++ = data[0];
Packit df99a1
                          *buf_ptr++ = data[1];
Packit df99a1
                          data = bin2hex[ramp[pix->b]];
Packit df99a1
                          *buf_ptr++ = data[0];
Packit df99a1
                          *buf_ptr++ = data[1];
Packit df99a1
                          symbols += 6;
Packit df99a1
                        }
Packit df99a1
                      else
Packit df99a1
                        {
Packit df99a1
                          char *data;
Packit df99a1
                          data = bin2hex[ramp[GRAY(pix->r,pix->g,pix->b)]];
Packit df99a1
                          *buf_ptr++ = data[0];
Packit df99a1
                          *buf_ptr++ = data[1];
Packit df99a1
                          symbols += 2;
Packit df99a1
                        }
Packit df99a1
                      if (symbols>70) 
Packit df99a1
                        { 
Packit df99a1
                          *buf_ptr++ = '\n'; 
Packit df99a1
                          symbols=0; 
Packit df99a1
                        }
Packit df99a1
                    }
Packit df99a1
                }
Packit df99a1
              else if (bm)
Packit df99a1
                {
Packit df99a1
                  unsigned char *pix = (*bm)[y];
Packit df99a1
                  unsigned char acc = 0;
Packit df99a1
                  unsigned char mask = 0;
Packit df99a1
                  char *data;
Packit df99a1
                  for (int x=grectBand.width(); x>0; x--, pix++)
Packit df99a1
                    {
Packit df99a1
                      if (mask == 0)
Packit df99a1
                        mask = 0x80;
Packit df99a1
                      if (! *pix)
Packit df99a1
                        acc |= mask;
Packit df99a1
                      mask >>= 1;
Packit df99a1
                      if (mask == 0)
Packit df99a1
                        {
Packit df99a1
                          data = bin2hex[acc];
Packit df99a1
                          acc = 0;
Packit df99a1
                          *buf_ptr++ = data[0];
Packit df99a1
                          *buf_ptr++ = data[1];
Packit df99a1
                          symbols += 2;
Packit df99a1
                          if (symbols>70) 
Packit df99a1
                            { 
Packit df99a1
                              *buf_ptr++ = '\n'; 
Packit df99a1
                              symbols = 0; 
Packit df99a1
                            }
Packit df99a1
                        }
Packit df99a1
                    }
Packit df99a1
                  if (mask != 0) 
Packit df99a1
                    {
Packit df99a1
                      data = bin2hex[acc];
Packit df99a1
                      *buf_ptr++ = data[0];
Packit df99a1
                      *buf_ptr++ = data[1];
Packit df99a1
                      symbols += 2;
Packit df99a1
                    }
Packit df99a1
                }
Packit df99a1
              if (refresh_cb) 
Packit df99a1
                refresh_cb(refresh_cl_data);
Packit df99a1
            }
Packit df99a1
          str.writall(buffer, buf_ptr-buffer);
Packit df99a1
          if (prn_progress_cb)
Packit df99a1
            {
Packit df99a1
              double done=(double) (grectBand.ymax 
Packit df99a1
                                    - prn_rect.ymin)/prn_rect.height();
Packit df99a1
              if ((int) (20*print_done)!=(int) (20*done))
Packit df99a1
                {
Packit df99a1
                  print_done=done;
Packit df99a1
                  prn_progress_cb(done, prn_progress_cl_data);
Packit df99a1
                }
Packit df99a1
            }
Packit df99a1
        }
Packit df99a1
      write(str, "\n");
Packit df99a1
    } 
Packit df99a1
  write(str, "grestore\n");
Packit df99a1
}
Packit df99a1
Packit df99a1
void
Packit df99a1
DjVuToPS::
Packit df99a1
print_image_lev2(ByteStream &str, 
Packit df99a1
                 GP<DjVuImage> dimg,
Packit df99a1
                 const GRect &prn_rect)
Packit df99a1
{         
Packit df99a1
  double print_done=0;
Packit df99a1
  GRect all(0,0, dimg->get_width(),dimg->get_height());
Packit df99a1
  GP<GPixmap> pm;
Packit df99a1
  GRect test(0,0,1,1);
Packit df99a1
  if (options.get_mode() == Options::FORE)
Packit df99a1
    pm = dimg->get_fg_pixmap(test, all);
Packit df99a1
  else if (options.get_mode() == Options::BACK)
Packit df99a1
    pm = dimg->get_bg_pixmap(test, all);
Packit df99a1
  else if (options.get_mode() != Options::BW)
Packit df99a1
    pm = dimg->get_pixmap(test, all);
Packit df99a1
  if (! pm)
Packit df99a1
    return;
Packit df99a1
  write(str,
Packit df99a1
        "%% --- now doing a level 2 image\n"
Packit df99a1
        "gsave\n");
Packit df99a1
  // Display image
Packit df99a1
  int band_bytes=125000;
Packit df99a1
  int band_height = band_bytes/prn_rect.width();
Packit df99a1
  int buffer_size = band_height*prn_rect.width();
Packit df99a1
  int ps_chunk_height = 30960/prn_rect.width()+1;
Packit df99a1
  buffer_size = buffer_size*21/10 + 32;
Packit df99a1
  bool do_color = options.get_color();
Packit df99a1
  if (do_color)
Packit df99a1
    {
Packit df99a1
      buffer_size *= 3;
Packit df99a1
      write(str, 
Packit df99a1
            "/bufferR %d string def\n"
Packit df99a1
            "/bufferG %d string def\n"
Packit df99a1
            "/bufferB %d string def\n"
Packit df99a1
            "DjVuColorSpace setcolorspace\n"
Packit df99a1
            "<< /ImageType 1\n"
Packit df99a1
            "   /Width %d\n"
Packit df99a1
            "   /Height %d\n"
Packit df99a1
            "   /BitsPerComponent 8\n"
Packit df99a1
            "   /Decode [0 1 0 1 0 1]\n"
Packit df99a1
            "   /ImageMatrix [1 0 0 1 0 0]\n"
Packit df99a1
            "   /MultipleDataSources true\n"
Packit df99a1
            "   /DataSource [ { ReadR } { ReadG } { ReadB } ]\n"
Packit df99a1
            "   /Interpolate false >> image\n",
Packit df99a1
            ps_chunk_height*prn_rect.width(),
Packit df99a1
            ps_chunk_height*prn_rect.width(),
Packit df99a1
            ps_chunk_height*prn_rect.width(),
Packit df99a1
            prn_rect.width(), prn_rect.height());
Packit df99a1
    } 
Packit df99a1
  else
Packit df99a1
    {
Packit df99a1
      write(str, 
Packit df99a1
            "DjVuColorSpace setcolorspace\n"
Packit df99a1
            "<< /ImageType 1\n"
Packit df99a1
            "   /Width %d\n"
Packit df99a1
            "   /Height %d\n"
Packit df99a1
            "   /BitsPerComponent 8\n"
Packit df99a1
            "   /Decode [0 1]\n"
Packit df99a1
            "   /ImageMatrix [1 0 0 1 0 0]\n"
Packit df99a1
            "   /DataSource currentfile /ASCII85Decode\n"
Packit df99a1
            "       filter /RunLengthDecode filter\n"
Packit df99a1
            "   /Interpolate false >> image\n",
Packit df99a1
            prn_rect.width(), prn_rect.height());
Packit df99a1
    } 
Packit df99a1
  unsigned char *buffer;
Packit df99a1
  GPBuffer<unsigned char> gbuffer(buffer,buffer_size);
Packit df99a1
  unsigned char *rle_in;
Packit df99a1
  GPBuffer<unsigned char> grle_in(rle_in,ps_chunk_height*prn_rect.width());
Packit df99a1
  unsigned char *rle_out;
Packit df99a1
  GPBuffer<unsigned char> grle_out(rle_out,2*ps_chunk_height*prn_rect.width());
Packit df99a1
    {
Packit df99a1
      // Start storing image in bands
Packit df99a1
      unsigned char * rle_out_end = rle_out;
Packit df99a1
      GRect grectBand = prn_rect;
Packit df99a1
      grectBand.ymax = grectBand.ymin;
Packit df99a1
      while(grectBand.ymax < prn_rect.ymax)
Packit df99a1
        {
Packit df99a1
          // Compute next band
Packit df99a1
          grectBand.ymin = grectBand.ymax;
Packit df99a1
          grectBand.ymax = grectBand.ymin+band_bytes/grectBand.width();
Packit df99a1
          if (grectBand.ymax > prn_rect.ymax)
Packit df99a1
            grectBand.ymax = prn_rect.ymax;
Packit df99a1
          GRect all(0,0, dimg->get_width(),dimg->get_height());
Packit df99a1
          pm = 0;
Packit df99a1
          if (options.get_mode() == Options::FORE)
Packit df99a1
            pm = dimg->get_fg_pixmap(grectBand, all);
Packit df99a1
          else if (options.get_mode() == Options::BACK)
Packit df99a1
            pm = dimg->get_bg_pixmap(grectBand, all);
Packit df99a1
          else
Packit df99a1
            pm = dimg->get_pixmap(grectBand, all);
Packit df99a1
          // Store next band
Packit df99a1
          unsigned char *buf_ptr = buffer;
Packit df99a1
          if (do_color && pm)
Packit df99a1
            {
Packit df99a1
              int y=0;
Packit df99a1
              while(y
Packit df99a1
                {
Packit df99a1
                  int row, y1;
Packit df99a1
                  unsigned char *ptr, *ptr1;
Packit df99a1
                  // Doing R component of current chunk
Packit df99a1
                  for (row=0,ptr=rle_in,y1=y; 
Packit df99a1
                       row
Packit df99a1
                       row++,y1++)
Packit df99a1
                    {
Packit df99a1
                      GPixel *pix = (*pm)[y1];
Packit df99a1
                      for (int x=grectBand.width(); x>0; x--,pix++)
Packit df99a1
                        *ptr++ = ramp[pix->r];
Packit df99a1
                    }
Packit df99a1
                  ptr1 = RLE_encode(rle_out, rle_in, ptr); 
Packit df99a1
                  *ptr1++ = 0x80;
Packit df99a1
                  buf_ptr = ASCII85_encode(buf_ptr, rle_out, ptr1);
Packit df99a1
                  *buf_ptr++ = '~'; *buf_ptr++ = '>'; *buf_ptr++ = '\n';
Packit df99a1
                  // Doing G component of current chunk
Packit df99a1
                  for (row=0,ptr=rle_in,y1=y; 
Packit df99a1
                       row
Packit df99a1
                       row++,y1++)
Packit df99a1
                    {
Packit df99a1
                      GPixel *pix = (*pm)[y1];
Packit df99a1
                      for (int x=grectBand.width(); x>0; x--,pix++)
Packit df99a1
                        *ptr++ = ramp[pix->g];
Packit df99a1
                    }
Packit df99a1
                  ptr1 = RLE_encode(rle_out, rle_in, ptr); 
Packit df99a1
                  *ptr1++ = 0x80;
Packit df99a1
                  buf_ptr = ASCII85_encode(buf_ptr, rle_out, ptr1);
Packit df99a1
                  *buf_ptr++ = '~'; 
Packit df99a1
                  *buf_ptr++ = '>'; 
Packit df99a1
                  *buf_ptr++ = '\n';
Packit df99a1
                  // Doing B component of current chunk
Packit df99a1
                  for (row=0, ptr=rle_in, y1=y;
Packit df99a1
                       row
Packit df99a1
                       row++,y1++)
Packit df99a1
                    {
Packit df99a1
                      GPixel *pix = (*pm)[y1];
Packit df99a1
                      for (int x=grectBand.width(); x>0; x--,pix++)
Packit df99a1
                        *ptr++ = ramp[pix->b];
Packit df99a1
                    }
Packit df99a1
                  ptr1 = RLE_encode(rle_out, rle_in, ptr);
Packit df99a1
                  *ptr1++ = 0x80;
Packit df99a1
                  buf_ptr = ASCII85_encode(buf_ptr, rle_out, ptr1);
Packit df99a1
                  *buf_ptr++ = '~'; 
Packit df99a1
                  *buf_ptr++ = '>'; 
Packit df99a1
                  *buf_ptr++ = '\n';
Packit df99a1
                  y=y1;
Packit df99a1
                  if (refresh_cb) 
Packit df99a1
                    refresh_cb(refresh_cl_data);
Packit df99a1
                } //while (y>=0)
Packit df99a1
            } 
Packit df99a1
          else if (pm)
Packit df99a1
            {
Packit df99a1
              // Don't use color
Packit df99a1
              int y=0;
Packit df99a1
              while(y
Packit df99a1
                {
Packit df99a1
                  unsigned char *ptr = rle_in;
Packit df99a1
                  for(int row=0;
Packit df99a1
                      row
Packit df99a1
                      row++,y++)
Packit df99a1
                    {
Packit df99a1
                      GPixel *pix = (*pm)[y];
Packit df99a1
                      for (int x=grectBand.width(); x>0; x--,pix++)
Packit df99a1
                        *ptr++ = ramp[GRAY(pix->r,pix->g,pix->b)];
Packit df99a1
                    }
Packit df99a1
                  rle_out_end = RLE_encode(rle_out_end, rle_in, ptr);
Packit df99a1
                  unsigned char *encode_to = rle_out 
Packit df99a1
                    + (rle_out_end-rle_out)/4*4;
Packit df99a1
                  int bytes_left = rle_out_end-encode_to;
Packit df99a1
                  buf_ptr = ASCII85_encode(buf_ptr, rle_out, encode_to);
Packit df99a1
                  *buf_ptr++ = '\n';
Packit df99a1
                  memcpy(rle_out, encode_to, bytes_left);
Packit df99a1
                  rle_out_end = rle_out+bytes_left;
Packit df99a1
                  if (refresh_cb) 
Packit df99a1
                    refresh_cb(refresh_cl_data);
Packit df99a1
                }
Packit df99a1
              if (grectBand.ymax >= prn_rect.ymax)
Packit df99a1
                {
Packit df99a1
                  *rle_out_end++ = 0x80; // Add EOF marker
Packit df99a1
                  buf_ptr = ASCII85_encode(buf_ptr, rle_out, rle_out_end);
Packit df99a1
                  *buf_ptr++ = '~'; 
Packit df99a1
                  *buf_ptr++ = '>'; 
Packit df99a1
                  *buf_ptr++ = '\n';
Packit df99a1
                }
Packit df99a1
            }
Packit df99a1
          str.writall(buffer, buf_ptr-buffer);
Packit df99a1
          if (prn_progress_cb)
Packit df99a1
            {
Packit df99a1
              double done=(double) (grectBand.ymax
Packit df99a1
                                    - prn_rect.ymin)/prn_rect.height();
Packit df99a1
              if ((int) (20*print_done)!=(int) (20*done))
Packit df99a1
                {
Packit df99a1
                  print_done=done;
Packit df99a1
                  prn_progress_cb(done, prn_progress_cl_data);
Packit df99a1
                }
Packit df99a1
            }
Packit df99a1
        }
Packit df99a1
      write(str, "\n");
Packit df99a1
    } 
Packit df99a1
  write(str, "grestore\n");
Packit df99a1
}
Packit df99a1
Packit df99a1
static void 
Packit df99a1
get_anno_sub(IFFByteStream &iff, IFFByteStream &out)
Packit df99a1
{
Packit df99a1
  GUTF8String chkid;
Packit df99a1
  while (iff.get_chunk(chkid))
Packit df99a1
    {
Packit df99a1
      if (iff.composite())
Packit df99a1
        get_anno_sub(iff, out);
Packit df99a1
      else if (chkid == "ANTa" || chkid == "ANTz" ||
Packit df99a1
               chkid == "TXTa" || chkid == "TXTz"   )
Packit df99a1
        {
Packit df99a1
          out.put_chunk(chkid);
Packit df99a1
          out.copy(*iff.get_bytestream());
Packit df99a1
          out.close_chunk();
Packit df99a1
        }
Packit df99a1
      iff.close_chunk();
Packit df99a1
    }
Packit df99a1
}
Packit df99a1
Packit df99a1
static GP<ByteStream>
Packit df99a1
get_anno(GP<DjVuFile> f)
Packit df99a1
{
Packit df99a1
  if (! f->anno) 
Packit df99a1
    {
Packit df99a1
      GP<ByteStream> bs = f->get_init_data_pool()->get_stream();
Packit df99a1
      GP<ByteStream> anno = ByteStream::create();
Packit df99a1
      GP<IFFByteStream> in = IFFByteStream::create(bs);
Packit df99a1
      GP<IFFByteStream> out = IFFByteStream::create(anno);
Packit df99a1
      get_anno_sub(*in, *out);
Packit df99a1
      f->anno = anno;
Packit df99a1
    }
Packit df99a1
  f->anno->seek(0);
Packit df99a1
  return f->anno;
Packit df99a1
}
Packit df99a1
Packit df99a1
static GP<DjVuTXT>
Packit df99a1
get_text(GP<DjVuFile> file)
Packit df99a1
{ 
Packit df99a1
  GUTF8String chkid;
Packit df99a1
  GP<IFFByteStream> iff = IFFByteStream::create(get_anno(file));
Packit df99a1
  while (iff->get_chunk(chkid))
Packit df99a1
    {
Packit df99a1
      if (chkid == "TXTa") 
Packit df99a1
        {
Packit df99a1
          GP<DjVuTXT> txt = DjVuTXT::create();
Packit df99a1
          txt->decode(iff->get_bytestream());
Packit df99a1
          return txt;
Packit df99a1
        }
Packit df99a1
      else if (chkid == "TXTz") 
Packit df99a1
        {
Packit df99a1
          GP<DjVuTXT> txt = DjVuTXT::create();
Packit df99a1
          GP<ByteStream> bsiff = BSByteStream::create(iff->get_bytestream());
Packit df99a1
          txt->decode(bsiff);
Packit df99a1
          return txt;
Packit df99a1
        }
Packit df99a1
      iff->close_chunk();
Packit df99a1
    }
Packit df99a1
  return 0;
Packit df99a1
}
Packit df99a1
Packit df99a1
static void
Packit df99a1
print_ps_string(const char *data, int length, ByteStream &out)
Packit df99a1
{
Packit df99a1
  while (*data && length>0) 
Packit df99a1
    {
Packit df99a1
      int span = 0;
Packit df99a1
      while (span<length && data[span]>=0x20 && data[span]<0x7f 
Packit df99a1
             && data[span]!='(' && data[span]!=')' && data[span]!='\\' )
Packit df99a1
        span++;
Packit df99a1
      if (span > 0) 
Packit df99a1
        {
Packit df99a1
          out.write(data, span);
Packit df99a1
          data += span;
Packit df99a1
          length -= span;
Packit df99a1
        }
Packit df99a1
      else
Packit df99a1
        {
Packit df99a1
          char buffer[5];
Packit df99a1
          sprintf(buffer,"\\%03o", *(unsigned char*)data);
Packit df99a1
          out.write(buffer,4);
Packit df99a1
          data += 1;
Packit df99a1
          length -= 1;
Packit df99a1
        }
Packit df99a1
    }
Packit df99a1
}
Packit df99a1
Packit df99a1
static void
Packit df99a1
print_txt_sub(DjVuTXT &txt, DjVuTXT::Zone &zone, 
Packit df99a1
              ByteStream &out,int &lastx,int &lasty)
Packit df99a1
{
Packit df99a1
  // Get separator
Packit df99a1
  char separator = 0;
Packit df99a1
  switch(zone.ztype)
Packit df99a1
    {
Packit df99a1
    case DjVuTXT::COLUMN: 
Packit df99a1
      separator = DjVuTXT::end_of_column; break;
Packit df99a1
    case DjVuTXT::REGION: 
Packit df99a1
      separator = DjVuTXT::end_of_region; break;
Packit df99a1
    case DjVuTXT::PARAGRAPH: 
Packit df99a1
      separator = DjVuTXT::end_of_paragraph; break;
Packit df99a1
    case DjVuTXT::LINE: 
Packit df99a1
      separator = DjVuTXT::end_of_line; break;
Packit df99a1
    case DjVuTXT::WORD: 
Packit df99a1
      separator = ' '; break;
Packit df99a1
    default:
Packit df99a1
      separator = 0; break;
Packit df99a1
    }
Packit df99a1
  // Zone children
Packit df99a1
  if (zone.children.isempty()) 
Packit df99a1
    {
Packit df99a1
      const char *data = (const char*)txt.textUTF8 + zone.text_start;
Packit df99a1
      int length = zone.text_length;
Packit df99a1
      if (data[length-1] == separator)
Packit df99a1
        length -= 1;
Packit df99a1
      out.write("( ",2);
Packit df99a1
      print_ps_string(data,length,out);
Packit df99a1
      out.write(")",1);
Packit df99a1
      GUTF8String message;
Packit df99a1
      int tmpx= zone.rect.xmin-lastx;
Packit df99a1
      int tmpy= zone.rect.ymin-lasty;
Packit df99a1
      message.format(" %d %d S \n", tmpx, tmpy);
Packit df99a1
      lastx=zone.rect.xmin;
Packit df99a1
      lasty=zone.rect.ymin;
Packit df99a1
      out.write((const char*)message, message.length());
Packit df99a1
    }
Packit df99a1
  else
Packit df99a1
    {
Packit df99a1
      if (zone.ztype==DjVuTXT::LINE)
Packit df99a1
        {
Packit df99a1
          GUTF8String message;
Packit df99a1
          message.format("%d F\n",zone.rect.ymax-zone.rect.ymin);
Packit df99a1
          out.write((const char*)message,message.length());
Packit df99a1
        }
Packit df99a1
      for (GPosition pos=zone.children; pos; ++pos)
Packit df99a1
        print_txt_sub(txt, zone.children[pos], out,lastx,lasty);
Packit df99a1
    }
Packit df99a1
}
Packit df99a1
Packit df99a1
static void
Packit df99a1
print_txt(GP<DjVuTXT> txt, 
Packit df99a1
          ByteStream &out )
Packit df99a1
{
Packit df99a1
  if (txt)
Packit df99a1
    {
Packit df99a1
      int lastx=0;
Packit df99a1
      int lasty=0;
Packit df99a1
      GUTF8String message = 
Packit df99a1
        "%% -- now doing hidden text\n"
Packit df99a1
        "gsave -1 -1 0 0 clip 0 0 moveto\n";
Packit df99a1
      out.write((const char*)message,message.length());
Packit df99a1
      print_txt_sub(*txt, txt->page_zone, out,lastx,lasty);
Packit df99a1
      message = 
Packit df99a1
        "grestore \n";
Packit df99a1
      out.write((const char*)message,message.length());
Packit df99a1
    }
Packit df99a1
}
Packit df99a1
Packit df99a1
void
Packit df99a1
DjVuToPS::
Packit df99a1
print_image(ByteStream &str, 
Packit df99a1
            GP<DjVuImage> dimg,
Packit df99a1
            const GRect &prn_rect, 
Packit df99a1
            GP<DjVuTXT> txt)
Packit df99a1
{
Packit df99a1
  /* Just outputs the specified image. The function assumes, that
Packit df99a1
     all add-ons (like {\em document setup}, {\em page setup}) are
Packit df99a1
     already there. It will just output the image. Since
Packit df99a1
     output of this function will generate PostScript errors when
Packit df99a1
     used without output of auxiliary functions, it should be
Packit df99a1
     used carefully. */
Packit df99a1
  DEBUG_MSG("DjVuToPS::print_image(): Printing DjVuImage to a stream\n");
Packit df99a1
  DEBUG_MAKE_INDENT(3);
Packit df99a1
  if (!dimg)
Packit df99a1
    G_THROW(ERR_MSG("DjVuToPS.empty_image"));
Packit df99a1
  if (prn_rect.isempty())
Packit df99a1
    G_THROW(ERR_MSG("DjVuToPS.empty_rect"));
Packit df99a1
  if (prn_progress_cb)
Packit df99a1
    prn_progress_cb(0, prn_progress_cl_data);
Packit df99a1
  // Compute information for chosen display mode
Packit df99a1
  print_txt(txt, str);
Packit df99a1
  make_gamma_ramp(dimg);
Packit df99a1
  if (options.get_level() < 2)
Packit df99a1
    {
Packit df99a1
      print_image_lev1(str, dimg, prn_rect);
Packit df99a1
    }
Packit df99a1
  else if (options.get_level() < 3 && dimg->get_fgpm())
Packit df99a1
    {
Packit df99a1
      switch(options.get_mode())
Packit df99a1
        {
Packit df99a1
        case Options::COLOR:
Packit df99a1
        case Options::FORE:
Packit df99a1
          print_image_lev2(str, dimg, prn_rect);
Packit df99a1
          break;
Packit df99a1
        case Options::BW:
Packit df99a1
          print_fg(str, dimg, prn_rect);
Packit df99a1
          break;
Packit df99a1
        case Options::BACK:
Packit df99a1
          print_bg(str, dimg, prn_rect);
Packit df99a1
          break;
Packit df99a1
        }
Packit df99a1
    }
Packit df99a1
  else 
Packit df99a1
    {
Packit df99a1
      switch(options.get_mode())
Packit df99a1
        {
Packit df99a1
        case Options::COLOR:
Packit df99a1
          print_bg(str, dimg, prn_rect);
Packit df99a1
          print_fg(str, dimg, prn_rect);
Packit df99a1
          break;
Packit df99a1
        case Options::FORE:
Packit df99a1
        case Options::BW:
Packit df99a1
          print_fg(str, dimg, prn_rect);
Packit df99a1
          break;
Packit df99a1
        case Options::BACK:
Packit df99a1
          print_bg(str, dimg, prn_rect);
Packit df99a1
          break;
Packit df99a1
        }
Packit df99a1
    }
Packit df99a1
  if (prn_progress_cb)
Packit df99a1
    prn_progress_cb(1, prn_progress_cl_data);
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
// ***********************************************************************
Packit df99a1
// ******* PUBLIC FUNCTION FOR PRINTING A SINGLE PAGE ********************
Packit df99a1
// ***********************************************************************
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
void
Packit df99a1
DjVuToPS::
Packit df99a1
print(ByteStream &str, 
Packit df99a1
      GP<DjVuImage> dimg,
Packit df99a1
      const GRect &prn_rect_in, 
Packit df99a1
      const GRect &img_rect,
Packit df99a1
      int override_dpi)
Packit df99a1
{
Packit df99a1
  DEBUG_MSG("DjVuToPS::print(): Printing DjVu page to a stream\n");
Packit df99a1
  DEBUG_MAKE_INDENT(3);
Packit df99a1
  GRect prn_rect;
Packit df99a1
  prn_rect.intersect(prn_rect_in, img_rect);
Packit df99a1
  DEBUG_MSG("prn_rect=(" << prn_rect.xmin << ", " << prn_rect.ymin << ", " <<
Packit df99a1
            prn_rect.width() << ", " << prn_rect.height() << ")\n");
Packit df99a1
  DEBUG_MSG("img_rect=(" << img_rect.xmin << ", " << img_rect.ymin << ", " <<
Packit df99a1
            img_rect.width() << ", " << img_rect.height() << ")\n");
Packit df99a1
  if (!dimg)
Packit df99a1
    G_THROW(ERR_MSG("DjVuToPS.empty_image"));
Packit df99a1
  if (prn_rect.isempty())
Packit df99a1
    G_THROW(ERR_MSG("DjVuToPS.empty_rect"));
Packit df99a1
  if (img_rect.isempty())
Packit df99a1
    G_THROW(ERR_MSG("DjVuToPS.bad_scale"));
Packit df99a1
  GRectMapper mapper;
Packit df99a1
  mapper.set_input(img_rect);
Packit df99a1
  GRect full_rect(0, 0, dimg->get_width(), dimg->get_height());
Packit df99a1
  mapper.set_output(full_rect);
Packit df99a1
  mapper.map(prn_rect);
Packit df99a1
  int image_dpi =  dimg->get_dpi();
Packit df99a1
  if (override_dpi>0) 
Packit df99a1
    image_dpi = override_dpi;
Packit df99a1
  if (image_dpi <= 0) 
Packit df99a1
    image_dpi = 300;
Packit df99a1
  store_doc_prolog(str, 1, (int)(image_dpi), &prn_rect);
Packit df99a1
  store_doc_setup(str);
Packit df99a1
  write(str,"%%%%Page: 1 1\n");
Packit df99a1
  store_page_setup(str, (int)(image_dpi), prn_rect);
Packit df99a1
  print_image(str, dimg, prn_rect, 0);
Packit df99a1
  store_page_trailer(str);
Packit df99a1
  write(str,"showpage\n");
Packit df99a1
  store_doc_trailer(str);
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
// ***********************************************************************
Packit df99a1
// *************************** DOCUMENT LEVEL ****************************
Packit df99a1
// ***********************************************************************
Packit df99a1
Packit df99a1
Packit df99a1
void
Packit df99a1
DjVuToPS::
Packit df99a1
parse_range(GP<DjVuDocument> doc, 
Packit df99a1
             GUTF8String page_range, 
Packit df99a1
             GList<int> &pages_todo)
Packit df99a1
{
Packit df99a1
  int doc_pages = doc->get_pages_num();
Packit df99a1
  if (!page_range.length())
Packit df99a1
    page_range.format("1-%d", doc_pages);
Packit df99a1
  DEBUG_MSG("page_range='" << (const char *)page_range << "'\n");
Packit df99a1
  int spec = 0;
Packit df99a1
  int both = 1;
Packit df99a1
  int start_page = 1;
Packit df99a1
  int end_page = doc_pages;
Packit df99a1
  const char *q = (const char*)page_range;
Packit df99a1
  char *p = (char*)q;
Packit df99a1
  while (*p)
Packit df99a1
    {
Packit df99a1
      while (*p==' ')
Packit df99a1
        p += 1;
Packit df99a1
      if (! *p)
Packit df99a1
        break;
Packit df99a1
      if (*p>='0' && *p<='9') 
Packit df99a1
        {
Packit df99a1
          end_page = strtol(p, &p, 10);
Packit df99a1
          spec = 1;
Packit df99a1
        } 
Packit df99a1
      else if (*p=='$') 
Packit df99a1
        {
Packit df99a1
          spec = 1;
Packit df99a1
          end_page = doc_pages;
Packit df99a1
          p += 1;
Packit df99a1
        } 
Packit df99a1
      else if (both) 
Packit df99a1
        {
Packit df99a1
          end_page = 1;
Packit df99a1
        } 
Packit df99a1
      else 
Packit df99a1
        {
Packit df99a1
          end_page = doc_pages;
Packit df99a1
        }
Packit df99a1
      while (*p==' ')
Packit df99a1
        p += 1;
Packit df99a1
      if (both)
Packit df99a1
        {
Packit df99a1
          start_page = end_page;
Packit df99a1
          if (*p == '-') 
Packit df99a1
            {
Packit df99a1
              p += 1;
Packit df99a1
              both = 0;
Packit df99a1
              continue;
Packit df99a1
            }
Packit df99a1
        }
Packit df99a1
      both = 1;
Packit df99a1
      while (*p==' ')
Packit df99a1
        p += 1;
Packit df99a1
      if (*p && *p != ',')
Packit df99a1
        G_THROW(ERR_MSG("DjVuToPS.bad_range") 
Packit df99a1
                + GUTF8String("\t") + GUTF8String(p) );
Packit df99a1
      if (*p == ',')
Packit df99a1
        p += 1;
Packit df99a1
      if (! spec)
Packit df99a1
        G_THROW(ERR_MSG("DjVuToPS.bad_range") 
Packit df99a1
                + GUTF8String("\t") + page_range );
Packit df99a1
      spec = 0;
Packit df99a1
      if (end_page < 0)
Packit df99a1
        end_page = 0;
Packit df99a1
      if (start_page < 0)
Packit df99a1
        start_page = 0;
Packit df99a1
      if (end_page > doc_pages)
Packit df99a1
        end_page = doc_pages;
Packit df99a1
      if (start_page > doc_pages)
Packit df99a1
        start_page = doc_pages;
Packit df99a1
      if (start_page <= end_page)
Packit df99a1
        for(int page_num=start_page; page_num<=end_page; page_num++)
Packit df99a1
          pages_todo.append(page_num-1);
Packit df99a1
      else
Packit df99a1
        for(int page_num=start_page; page_num>=end_page; page_num--)
Packit df99a1
          pages_todo.append(page_num-1);
Packit df99a1
    }
Packit df99a1
}
Packit df99a1
Packit df99a1
class DjVuToPS::DecodePort : public DjVuPort
Packit df99a1
{
Packit df99a1
protected:
Packit df99a1
  DecodePort(void);
Packit df99a1
public:
Packit df99a1
  static GP<DecodePort> create(void);
Packit df99a1
  GEvent decode_event;
Packit df99a1
  bool decode_event_received;
Packit df99a1
  double decode_done;
Packit df99a1
  GURL decode_page_url;
Packit df99a1
  virtual void notify_file_flags_changed(const DjVuFile*,long,long);
Packit df99a1
  virtual void notify_decode_progress(const DjVuPort*,float);
Packit df99a1
};
Packit df99a1
Packit df99a1
DjVuToPS::DecodePort::
Packit df99a1
DecodePort(void)
Packit df99a1
  : decode_event_received(false),
Packit df99a1
    decode_done((double)0) 
Packit df99a1
{
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<DjVuToPS::DecodePort> 
Packit df99a1
DjVuToPS::DecodePort::
Packit df99a1
create(void)
Packit df99a1
{
Packit df99a1
  return new DecodePort;
Packit df99a1
}
Packit df99a1
Packit df99a1
void 
Packit df99a1
DjVuToPS::DecodePort::
Packit df99a1
notify_file_flags_changed(const DjVuFile *source, 
Packit df99a1
                          long set_mask, long clr_mask)
Packit df99a1
{
Packit df99a1
  // WARNING! This function is called from another thread
Packit df99a1
  if (set_mask & (DjVuFile::DECODE_OK | 
Packit df99a1
                  DjVuFile::DECODE_FAILED | 
Packit df99a1
                  DjVuFile::DECODE_STOPPED ))
Packit df99a1
    {
Packit df99a1
      if (source->get_url() == decode_page_url)
Packit df99a1
        {
Packit df99a1
          decode_event_received=true;
Packit df99a1
          decode_event.set();
Packit df99a1
        }
Packit df99a1
    }
Packit df99a1
}
Packit df99a1
Packit df99a1
void 
Packit df99a1
DjVuToPS::DecodePort::
Packit df99a1
notify_decode_progress(const DjVuPort *source, float done)
Packit df99a1
{
Packit df99a1
  // WARNING! This function is called from another thread
Packit df99a1
  if (source->inherits("DjVuFile"))
Packit df99a1
    {
Packit df99a1
      DjVuFile * file=(DjVuFile *) source;
Packit df99a1
      if (file->get_url()==decode_page_url)
Packit df99a1
        if ((int) (decode_done*20)!=(int) (done*20))
Packit df99a1
          {
Packit df99a1
            decode_done=done;
Packit df99a1
            decode_event_received=true;
Packit df99a1
            decode_event.set();
Packit df99a1
          }
Packit df99a1
    }
Packit df99a1
}
Packit df99a1
Packit df99a1
void 
Packit df99a1
DjVuToPS::
Packit df99a1
set_refresh_cb(void (*_refresh_cb)(void*), void *_refresh_cl_data)
Packit df99a1
{
Packit df99a1
  refresh_cb = _refresh_cb;
Packit df99a1
  refresh_cl_data = _refresh_cl_data;
Packit df99a1
}
Packit df99a1
Packit df99a1
void 
Packit df99a1
DjVuToPS::
Packit df99a1
set_prn_progress_cb(void (*_prn_progress_cb)(double, void *),
Packit df99a1
                    void *_prn_progress_cl_data)
Packit df99a1
{
Packit df99a1
  prn_progress_cb=_prn_progress_cb;
Packit df99a1
  prn_progress_cl_data=_prn_progress_cl_data;
Packit df99a1
}
Packit df99a1
Packit df99a1
void 
Packit df99a1
DjVuToPS::
Packit df99a1
set_dec_progress_cb(void (*_dec_progress_cb)(double, void *),
Packit df99a1
                    void *_dec_progress_cl_data)
Packit df99a1
{
Packit df99a1
  dec_progress_cb=_dec_progress_cb;
Packit df99a1
  dec_progress_cl_data=_dec_progress_cl_data;
Packit df99a1
}
Packit df99a1
Packit df99a1
void 
Packit df99a1
DjVuToPS::
Packit df99a1
set_info_cb(void (*_info_cb)(int, int, int, Stage, void*),
Packit df99a1
            void *_info_cl_data)
Packit df99a1
{
Packit df99a1
  info_cb=_info_cb;
Packit df99a1
  info_cl_data=_info_cl_data;
Packit df99a1
}
Packit df99a1
Packit df99a1
GP<DjVuImage>
Packit df99a1
DjVuToPS::
Packit df99a1
decode_page(GP<DjVuDocument> doc, 
Packit df99a1
            int page_num, int cnt, int todo)
Packit df99a1
{
Packit df99a1
  DEBUG_MSG("processing page #" << page_num << "\n");
Packit df99a1
  if (! port)
Packit df99a1
    {
Packit df99a1
      port = DecodePort::create();
Packit df99a1
      DjVuPort::get_portcaster()->add_route((DjVuDocument*)doc, port);
Packit df99a1
    }
Packit df99a1
  port->decode_event_received = false;
Packit df99a1
  port->decode_done = 0;
Packit df99a1
  GP<DjVuFile> djvu_file;
Packit df99a1
  GP<DjVuImage> dimg;
Packit df99a1
  if (page_num >= 0 && page_num < doc->get_pages_num())
Packit df99a1
    djvu_file = doc->get_djvu_file(page_num);
Packit df99a1
  if (! djvu_file )
Packit df99a1
    return 0;
Packit df99a1
  if (djvu_file->is_decode_ok())
Packit df99a1
    return doc->get_page(page_num, false);
Packit df99a1
  // This is the best place to call info_cb(). Note, that
Packit df99a1
  // get_page() will start decoding if necessary, and will not
Packit df99a1
  // return until the decoding is over in a single threaded
Packit df99a1
  // environment. That's why we call get_djvu_file() first.
Packit df99a1
  if (info_cb)
Packit df99a1
    info_cb(page_num, cnt, todo, DECODING, info_cl_data);
Packit df99a1
  // Do NOT decode the page synchronously here!!!
Packit df99a1
  // The plugin will deadlock otherwise.
Packit df99a1
  dimg = doc->get_page(page_num, false);
Packit df99a1
  djvu_file = dimg->get_djvu_file();
Packit df99a1
  port->decode_page_url = djvu_file->get_url();
Packit df99a1
  if (djvu_file->is_decode_ok())
Packit df99a1
    return dimg;
Packit df99a1
  DEBUG_MSG("decoding\n");
Packit df99a1
  if (dec_progress_cb)
Packit df99a1
    dec_progress_cb(0, dec_progress_cl_data);
Packit df99a1
  while(! djvu_file->is_decode_ok())
Packit df99a1
    {
Packit df99a1
      while(!port->decode_event_received && 
Packit df99a1
            !djvu_file->is_decode_ok())
Packit df99a1
        {
Packit df99a1
          port->decode_event.wait(250);
Packit df99a1
          if (refresh_cb) 
Packit df99a1
            refresh_cb(refresh_cl_data);
Packit df99a1
        }
Packit df99a1
      port->decode_event_received = false;
Packit df99a1
      if (djvu_file->is_decode_failed() || 
Packit df99a1
          djvu_file->is_decode_stopped())
Packit df99a1
        G_THROW(ERR_MSG("DjVuToPS.no_image") 
Packit df99a1
                + GUTF8String("\t") 
Packit df99a1
                + GUTF8String(page_num));
Packit df99a1
      if (dec_progress_cb)
Packit df99a1
        dec_progress_cb(port->decode_done, dec_progress_cl_data);
Packit df99a1
    }
Packit df99a1
  if (dec_progress_cb)
Packit df99a1
    dec_progress_cb(1, dec_progress_cl_data);
Packit df99a1
  return dimg;
Packit df99a1
}
Packit df99a1
Packit df99a1
void
Packit df99a1
DjVuToPS::
Packit df99a1
process_single_page(ByteStream &str, 
Packit df99a1
                    GP<DjVuDocument> doc,
Packit df99a1
                    int page_num, int cnt, int todo,
Packit df99a1
                    int magic)
Packit df99a1
{
Packit df99a1
  GP<DjVuTXT> txt;
Packit df99a1
  GP<DjVuImage> dimg;
Packit df99a1
  dimg = decode_page(doc, page_num, cnt, todo);
Packit df99a1
  if (options.get_text())
Packit df99a1
    txt = get_text(dimg->get_djvu_file());
Packit df99a1
  if (info_cb)
Packit df99a1
    info_cb(page_num, cnt, todo, PRINTING, info_cl_data);
Packit df99a1
  if (!magic)
Packit df99a1
    write(str, "%%%%Page: %d %d\n", page_num+1, cnt+1);
Packit df99a1
  if (dimg)
Packit df99a1
    {
Packit df99a1
      int dpi = dimg->get_dpi();
Packit df99a1
      dpi = ((dpi <= 0) ? 300 : dpi);
Packit df99a1
      GRect img_rect(0, 0, dimg->get_width(), dimg->get_height());
Packit df99a1
      store_page_setup(str, dpi, img_rect, magic);
Packit df99a1
      print_image(str, dimg, img_rect,txt);
Packit df99a1
      store_page_trailer(str);
Packit df99a1
    }
Packit df99a1
  if (!magic)
Packit df99a1
    write(str,"showpage\n");
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
struct pdata {
Packit df99a1
  int page1, page2;
Packit df99a1
  int smax, spos;
Packit df99a1
  int offset;
Packit df99a1
};
Packit df99a1
Packit df99a1
void 
Packit df99a1
DjVuToPS::
Packit df99a1
process_double_page(ByteStream &str, 
Packit df99a1
                    GP<DjVuDocument> doc,
Packit df99a1
                    void *v, int cnt, int todo)
Packit df99a1
{
Packit df99a1
  const pdata *inf = (const pdata*)v;
Packit df99a1
  int off = abs(inf->offset);
Packit df99a1
  write(str,
Packit df99a1
        "%%%%Page: (%d,%d) %d\n"
Packit df99a1
        "gsave\n"
Packit df99a1
        "/fold-dict 8 dict dup 3 1 roll def begin\n"
Packit df99a1
        " clippath pathbbox newpath pop pop translate\n"
Packit df99a1
        " clippath pathbbox newpath 4 2 roll pop pop\n"
Packit df99a1
        " /ph exch def\n"
Packit df99a1
        " /pw exch def\n"
Packit df99a1
        " /w ph %d sub 2 div def\n"
Packit df99a1
        " /m1 %d def\n"
Packit df99a1
        " /m2 %d def\n"
Packit df99a1
        "end\n",
Packit df99a1
        inf->page1 + 1, inf->page2 + 1, cnt,
Packit df99a1
        2 * (off + options.get_bookletfold(inf->smax-1)),
Packit df99a1
        inf->offset + options.get_bookletfold(inf->spos),
Packit df99a1
        inf->offset - options.get_bookletfold(inf->spos));
Packit df99a1
  if (options.get_cropmarks())
Packit df99a1
    write(str,
Packit df99a1
          "%% -- folding marks\n"
Packit df99a1
          "fold-dict begin\n"
Packit df99a1
          " 0 setgray 0.5 setlinewidth\n"
Packit df99a1
          " ph m1 m2 add add 2 div dup\n"
Packit df99a1
          " 0 exch moveto 36 0 rlineto stroke\n"
Packit df99a1
          " pw exch moveto -36 0 rlineto stroke\n"
Packit df99a1
          "end\n");
Packit df99a1
  write(str,
Packit df99a1
        "%% -- first page\n"
Packit df99a1
        "gsave fold-dict begin\n"
Packit df99a1
        " 0 ph 2 div w add m1 add translate 270 rotate\n"
Packit df99a1
        " 0 0 w pw rectclip end\n");
Packit df99a1
  if (inf->page1 >= 0)
Packit df99a1
    process_single_page(str, doc, inf->page1, cnt*2, todo*2, +1);
Packit df99a1
  write(str,
Packit df99a1
        "grestore\n"
Packit df99a1
        "%% -- second page\n"
Packit df99a1
        "gsave fold-dict begin\n"
Packit df99a1
        " 0 ph 2 div m2 add translate 270 rotate\n"
Packit df99a1
        " 0 0 w pw rectclip end\n");
Packit df99a1
  if (inf->page2 >= 0)
Packit df99a1
    process_single_page(str, doc, inf->page2, cnt*2+1, todo*2, -1);
Packit df99a1
  write(str,
Packit df99a1
        "grestore\n"
Packit df99a1
        "grestore\n"
Packit df99a1
        "showpage\n");
Packit df99a1
}
Packit df99a1
Packit df99a1
static void
Packit df99a1
booklet_order(GList<int>& pages, int smax)
Packit df99a1
{
Packit df99a1
  // -- make a multiple of four
Packit df99a1
  while (pages.size() & 0x3)
Packit df99a1
    pages.append(-1);
Packit df99a1
  // -- copy to array
Packit df99a1
  int i = 0;
Packit df99a1
  int n = pages.size();
Packit df99a1
  GTArray<int> p(0,n-1);
Packit df99a1
  for (GPosition pos=pages; pos; ++pos)
Packit df99a1
    p[i++] = pages[pos];
Packit df99a1
  // -- rebuild
Packit df99a1
  pages.empty();
Packit df99a1
  for (i=0; i
Packit df99a1
    {
Packit df99a1
      int lo = i;
Packit df99a1
      int hi = i+smax-1;
Packit df99a1
      if (hi >= n)
Packit df99a1
        hi = n-1;
Packit df99a1
      while (lo < hi)
Packit df99a1
        {
Packit df99a1
          pages.append(p[hi--]);
Packit df99a1
          pages.append(p[lo++]);
Packit df99a1
          pages.append(p[lo++]);
Packit df99a1
          pages.append(p[hi--]);
Packit df99a1
        }
Packit df99a1
    }
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
// ***********************************************************************
Packit df99a1
// ******* PUBLIC FUNCTIONS FOR PRINTING MULTIPLE PAGES ******************
Packit df99a1
// ***********************************************************************
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
void
Packit df99a1
DjVuToPS::
Packit df99a1
print(ByteStream &str, 
Packit df99a1
      GP<DjVuDocument> doc, 
Packit df99a1
      GUTF8String page_range)
Packit df99a1
{
Packit df99a1
  DEBUG_MSG("DjVuToPS::print(): Printing DjVu document\n");
Packit df99a1
  DEBUG_MAKE_INDENT(3);
Packit df99a1
  // Get page range
Packit df99a1
  GList<int> pages_todo;
Packit df99a1
  parse_range(doc, page_range, pages_todo);
Packit df99a1
  int todo = pages_todo.size();
Packit df99a1
  if (options.get_format()==Options::EPS)
Packit df99a1
    {
Packit df99a1
      /* Encapsulated Postscript mode */
Packit df99a1
      if (todo != 1)
Packit df99a1
        G_THROW(ERR_MSG("DjVuToPS.only_one_page"));
Packit df99a1
      GPosition pos = pages_todo;
Packit df99a1
      int page_num = pages_todo[pos];
Packit df99a1
      GP<DjVuImage> dimg = decode_page(doc,page_num,0,todo);
Packit df99a1
      if (! dimg)
Packit df99a1
        G_THROW(ERR_MSG("DjVuToPS.no_image") + GUTF8String("\t1"));
Packit df99a1
      GRect bbox(0, 0, dimg->get_width(), dimg->get_height());
Packit df99a1
      store_doc_prolog(str, 1, dimg->get_dpi(), &bbox);
Packit df99a1
      store_doc_setup(str);
Packit df99a1
      process_single_page(str, doc, page_num, 0, todo, 0);
Packit df99a1
    }
Packit df99a1
  else if (options.get_bookletmode()==Options::OFF)
Packit df99a1
    {
Packit df99a1
      /* Normal mode */
Packit df99a1
      int cnt = 0;
Packit df99a1
      store_doc_prolog(str, todo, 0, 0);
Packit df99a1
      store_doc_setup(str);
Packit df99a1
      for(GPosition pos = pages_todo; pos; ++pos)
Packit df99a1
        process_single_page(str,doc,pages_todo[pos],cnt++,todo,0);
Packit df99a1
      store_doc_trailer(str);
Packit df99a1
    }
Packit df99a1
  else
Packit df99a1
    {
Packit df99a1
      /* Booklet mode */
Packit df99a1
      int sheets_left = (todo+3)/4;
Packit df99a1
      int sides_todo = sheets_left;
Packit df99a1
      if (options.get_bookletmode() == Options::RECTOVERSO)
Packit df99a1
        sides_todo *= 2;
Packit df99a1
      int sheets_max = (options.get_bookletmax()+3)/4;
Packit df99a1
      if (! sheets_max)
Packit df99a1
        sheets_max = sheets_left;
Packit df99a1
      // -- reorder pages
Packit df99a1
      booklet_order(pages_todo, sheets_max*4);
Packit df99a1
      // -- print
Packit df99a1
      int sides = 0;
Packit df99a1
      int sheetpos = sheets_max;
Packit df99a1
      store_doc_prolog(str, sides_todo, 0, 0);
Packit df99a1
      store_doc_setup(str);
Packit df99a1
      for (GPosition p=pages_todo; p; ++p)
Packit df99a1
        {
Packit df99a1
          struct pdata inf;
Packit df99a1
          inf.page1 = pages_todo[p]; 
Packit df99a1
          inf.page2 = pages_todo[++p]; 
Packit df99a1
          inf.smax = sheets_max;
Packit df99a1
          inf.spos = --sheetpos;
Packit df99a1
          inf.offset = options.get_bookletalign();
Packit df99a1
          if (options.get_bookletmode() != Options::VERSO)
Packit df99a1
            process_double_page(str,doc,(void*)&inf,sides++,sides_todo);
Packit df99a1
          inf.page1 = pages_todo[++p]; 
Packit df99a1
          inf.page2 = pages_todo[++p]; 
Packit df99a1
          inf.offset = -inf.offset;
Packit df99a1
          if (options.get_bookletmode() != Options::RECTO)
Packit df99a1
            process_double_page(str,doc,(void*)&inf,sides++,sides_todo);
Packit df99a1
          sheets_left -= 1;
Packit df99a1
          if (sheetpos <= 0)
Packit df99a1
            sheetpos = ((sheets_max
Packit df99a1
        }
Packit df99a1
      store_doc_trailer(str);
Packit df99a1
    }
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
void
Packit df99a1
DjVuToPS::
Packit df99a1
print(ByteStream &str, GP<DjVuDocument> doc)
Packit df99a1
{
Packit df99a1
  GUTF8String dummy;
Packit df99a1
  print(str,doc,dummy);
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
#ifdef HAVE_NAMESPACES
Packit df99a1
}
Packit df99a1
# ifndef NOT_USING_DJVU_NAMESPACE
Packit df99a1
using namespace DJVU;
Packit df99a1
# endif
Packit df99a1
#endif
Packit df99a1