void PacketStreamReader::Stream::seekg(std::streampos target)
{
    if (!seekable())
        return;
    cclear();
    Base::seekg(target);
}
Пример #2
0
bool UserFile::seek(int64_t offset, int whence /* = SEEK_SET */) {
  assert(seekable());
  // bool stream_seek($offset, $whence)
  bool invoked = false;
  bool sought  = invoke(
    m_StreamSeek, s_stream_seek, make_packed_array(offset, whence), invoked
  ).toBoolean();
  if (!invoked) {
    always_assert("No seek method? But I found one earlier?");
  }

  // If the userland code failed to update, do it on our buffers instead
  if (!sought) {
    if (whence == SEEK_CUR) {
      m_position += offset;
    } else if (whence == SEEK_SET) {
      m_position = offset;
    }
    return true;
  }

  // int stream_tell()
  Variant ret = invoke(m_StreamTell, s_stream_tell, Array::Create(), invoked);
  if (!invoked) {
    raise_warning("%s::stream_tell is not implemented!", m_cls->name()->data());
    return false;
  }
  m_position = ret.isInteger() ? ret.toInt64() : -1;
  return true;
}
void PacketStreamReader::Stream::seekg(std::streamoff off, std::ios_base::seekdir way)
{
    if (!seekable())
        return;
    cclear();
    Base::seekg(off, way);
}
Пример #4
0
bool vHavokCachedShape::SaveShape(const char *szCachedShapeName, const hkClass& expectedClass, const hkpShape *pShape)
{
  VASSERT(szCachedShapeName!=NULL && pShape!=NULL);

  // make sure it's editable
  VRCSHelper::RCSEditFile(szCachedShapeName);

  // save shape to file
  {
    vHavokStreamWriter writer(szCachedShapeName);
    hkBufferedStreamWriter seekable(&writer);
    hkSerializeUtil::ErrorDetails err;
    hkResult res = hkSerializeUtil::save((const void*)pShape, expectedClass, &seekable); 

    if (res == HK_FAILURE)
    {
      hkvLog::Warning("vHavokCachedShape::Save of %s failed", szCachedShapeName);
      return false;
    }

    // make sure the file write is closed, before trying to add it to P4
  }

  // make sure it's added
  VRCSHelper::RCSAddFile(szCachedShapeName, true /* Binary file */);

  return true;
}
std::streampos PacketStreamReader::Stream::tellg()
{
    if (!seekable())
        return -1;
    if (_tag)
        return Base::tellg() - std::streamoff(TAG_LENGTH);
    return Base::tellg();
}
Пример #6
0
Array File::getMetaData() {
  Array ret = Array::Create();
  ret.set("wrapper_type", o_getClassName());
  ret.set("stream_type",  getStreamType());
  ret.set("mode",         String(m_mode));
  ret.set("unread_bytes", 0);
  ret.set("seekable",     seekable());
  ret.set("uri",          String(m_name));
  ret.set("timed_out",    false);
  ret.set("blocked",      true);
  ret.set("eof",          eof());
  return ret;
}
Пример #7
0
int64 File::write(CStrRef data, int64 length /* = 0 */) {
  if (seekable()) {
    m_readpos = m_writepos = 0; // invalidating read buffer
    seek(m_position, SEEK_SET);
  }
  if (length <= 0 || length > data.size()) {
    length = data.size();
  }
  if (length) {
    int64 written = writeImpl(data.data(), length);
    m_position += written;
    return written;
  }
  return 0;
}
Пример #8
0
bool UserFile::seek(int64_t offset, int whence /* = SEEK_SET */) {
  assert(seekable());

  // Seek within m_buffer if we can, otherwise kill it and call user stream_seek / stream_tell
  if (whence == SEEK_CUR &&
      0 <= getReadPosition() + offset &&
           getReadPosition() + offset < getWritePosition()) {
    setReadPosition(getReadPosition() + offset);
    setPosition(getPosition() + offset);
    return true;
  } else if (whence == SEEK_SET &&
             0 <= offset - getPosition() + getReadPosition() &&
             offset - getPosition() + getReadPosition() < getWritePosition()) {
    setReadPosition(offset - getPosition() + getReadPosition());
    setPosition(offset);
    return true;
  } else {
    if (whence == SEEK_CUR) {
      offset += getReadPosition() - getWritePosition();
    }
    setReadPosition(0);
    setWritePosition(0);
  }

  // bool stream_seek($offset, $whence)
  bool invoked = false;
  bool sought  = invoke(
    m_StreamSeek, s_stream_seek, make_packed_array(offset, whence), invoked
  ).toBoolean();
  if (!invoked) {
    always_assert("No seek method? But I found one earlier?");
  }
  if (!sought) {
    return false;
  }

  // int stream_tell()
  Variant ret = invoke(m_StreamTell, s_stream_tell, Array::Create(), invoked);
  if (!invoked) {
    raise_warning("%s::stream_tell is not implemented!", m_cls->name()->data());
    return false;
  }
  setPosition(ret.isInteger() ? ret.toInt64() : -1);
  return true;
}
Пример #9
0
hkpShape* vHavokCachedShape::LoadShape(const char *szCachedShapeName, const hkClass &expectedClass)
{
  VASSERT(szCachedShapeName != NULL);
  if(!Vision::File.Exists(szCachedShapeName))
    return HK_NULL;

  // load cached shape from file
  hkpShape *pShape = HK_NULL; 
  vHavokStreamReader reader(szCachedShapeName);
 
  hkBufferedStreamReader seekable(&reader);
  hkSerializeUtil::ErrorDetails err;

#if 0 // Enforce only exact version number here if you want to be sure to get all latest compression fixes in shapes
  hkSerializeUtil::FormatDetails formatDetails;
  hkSerializeUtil::detectFormat( &seekable, formatDetails);
  if ( formatDetails.m_version.cString() && (hkString::strCmp( formatDetails.m_version.cString(), HAVOK_SDK_VERSION_NUM_STRING ) != 0 ))
  {
    hkStringBuf fullWarning( "vHavokCachedShape::Load of ", szCachedShapeName, " failed due to non exact Havok SDK version:");
    fullWarning.appendPrintf("(%s in file, %s runtime)",formatDetails.m_version.cString(), HAVOK_SDK_VERSION_NUMBER );
    hkvLog::Warning( fullWarning.cString() );
    return HK_NULL;                    
  }
#endif

  // Note we are on purpose failing on versioning as any issues in bvtreecompressed shape in the compression etc are not patched (also patch may be slower than just create again). So best to fail and cause an implicit resave.
  hkObjectResource* fileContents = hkSerializeUtil::loadOnHeap(&seekable, &err, hkSerializeUtil::LOAD_FAIL_IF_VERSIONING); 
  if (fileContents)
  {
    pShape = (hkpShape*)fileContents->stealContentsPointer(expectedClass.getName(), hkBuiltinTypeRegistry::getInstance().getLoadedObjectRegistry() );
    fileContents->removeReference();
  }
  else
    hkvLog::Warning("vHavokCachedShape::Load of %s failed due to [%s]", szCachedShapeName, err.defaultMessage.cString());
  
  return pShape;
}
Пример #10
0
static int
mime_getheader(Pax_t* pax, Archive_t* ap, register File_t* f)
{
	register Mime_t*	mime = (Mime_t*)ap->data;
	register char*		s;
	register char*		t;
	register char*		v;
	off_t			m;
	off_t			b;
	size_t			n;
	int			loop;

	if (paxread(pax, ap, s = state.tmp.buffer, mime->length + 2, mime->length + 2, 1) <= 0 || memcmp(s, mime->magic, mime->length))
		error(3, "%s: corrupt %s format member header -- separator not found", ap->name, ap->format->name);
	else if (*(s += mime->length) == '-' && *(s + 1) == '-')
	{
		while (paxread(pax, ap, s, 1, 1, 1) > 0 && *s != '\n');
		return 0;
	}
	else if (*s == '\n')
		paxunread(pax, ap, s + 1, 1);
	else if (*s != '\r' && *(s + 1) != '\n')
		error(3, "%s: corrupt %s format member header -- separator line not found", ap->name, ap->format->name);
	f->name = 0;
	for (;;)
	{
		for (t = (s = state.tmp.buffer) + state.buffersize - 1; s < t; s++)
			if (paxread(pax, ap, s, 1, 1, 1) <= 0)
				error(3, "%s: unexpected %s format EOF", ap->name, ap->format->name);
			else if (*s == '\n')
			{
				if (s > state.tmp.buffer && *(s - 1) == '\r')
					s--;
				*s = 0;
				break;
			}
		s = state.tmp.buffer;
		if (!*s)
			break;
		if (strncasecmp(s, "content-", 8))
			error(3, "%s: corrupt %s format member header", ap->name, ap->format->name);
		if (t = strchr(s, ':'))
			s = t + 1;
		while (isspace(*s))
			s++;
		for (;;)
		{
			for (t = s; *s && *s != ';' && *s != '='; s++);
			if (!(n = s - t))
				break;
			if (*s == '=')
			{
				if (*++s == '"')
					for (v = ++s; *s && *s != '"'; s++);
				else
					for (v = s; *s && *s != ';'; s++);
			}
			else
				v = s;
			m = s - v;
			if (*s)
				*s++ = 0;
			for (; *s == ';' || isspace(*s); s++);
			if (!f->name && n == 4 && !strncasecmp(t, "name", 4) || n == 8 && !strncasecmp(t, "filename", 8))
				f->name = paxstash(pax, &ap->stash.head, v, m);
		}
	}
	if (!f->name)
	{
		if (s = strrchr(ap->name, '/'))
			s++;
		else
			s = ap->name;
		f->name = paxstash(pax, &ap->stash.head, s, strlen(s) + 16);
		sfsprintf(f->name, ap->stash.head.size, "%s-%d", s, ap->entries + 1);
	}
	if (!ap->io->seekable)
		seekable(ap);
	f->st->st_size = 0;
	loop = 0;
	b = paxseek(pax, ap, 0, SEEK_CUR, 0);
	while (s = paxget(pax, ap, 0, &m))
	{
		if (m < mime->length)
		{
			if (loop++)
				error(3, "%s: corrupt %s format member header [too short]", ap->name, ap->format->name);
			paxseek(pax, ap, -m, SEEK_CUR, 0);
			paxsync(pax, ap, 0);
			continue;
		}
		v = s;
		for (t = s + m - mime->length; s = memchr(s, '-', t - s); s++)
			if (!memcmp(s, mime->magic, mime->length))
			{
				paxseek(pax, ap, b, SEEK_CUR, 0);
				paxsync(pax, ap, 0);
				if (s > v && *(s - 1) == '\n')
				{
					mime->fill++;
					if (s > (v + 1) && *(s - 2) == '\r')
						mime->fill++;
				}
				f->st->st_size += (s - v) - mime->fill;
				f->st->st_mtime = NOW;
				f->st->st_mode = X_IFREG|X_IRUSR|X_IRGRP|X_IROTH;
				f->st->st_uid = state.uid;
				f->st->st_gid = state.gid;
				f->st->st_dev = 0;
				f->st->st_ino = 0;
				f->st->st_nlink = 1;
				IDEVICE(f->st, 0);
				f->linktype = NOLINK;
				f->linkpath = 0;
				f->uidname = 0;
				f->gidname = 0;
				return 1;
			}
		paxseek(pax, ap, -(off_t)mime->length, SEEK_CUR, 0);
		paxsync(pax, ap, 0);
		f->st->st_size += m;
	}
	return 0;
}
Пример #11
0
void main(int argc, char *argv[])
{
   double scale, rscale;			/* page scale */
   double waste, rwaste;			/* amount wasted */
   double vshift, hshift;			/* page centring shifts */
   int rotate;
   double inwidth = -1;
   double inheight = -1;
   Paper *paper;
   PageSpec *specs;

#ifdef PAPER
   if ( (paper = findpaper(PAPER)) != (Paper *)0 ) {
      inwidth = width = (double)PaperWidth(paper);
      inheight = height = (double)PaperHeight(paper);
   }
#endif

   vshift = hshift = 0;
   rotate = 0;

   infile = stdin;
   outfile = stdout;
   verbose = 1;
   for (program = *argv++; --argc; argv++) {
      if (argv[0][0] == '-') {
	 switch (argv[0][1]) {
	 case 'q':	/* quiet */
	    verbose = 0;
	    break;
	 case 'w':	/* page width */
	    width = singledimen(*argv+2, argerror, usage);
	    break;
	 case 'h':	/* page height */
	    height = singledimen(*argv+2, argerror, usage);
	    break;
	 case 'p':	/* paper type */
	    if ( (paper = findpaper(*argv+2)) != (Paper *)0 ) {
	       width = (double)PaperWidth(paper);
	       height = (double)PaperHeight(paper);
	    } else
	       message(FATAL, "paper size '%s' not recognised\n", *argv+2);
	    break;
	 case 'W':	/* input page width */
	    inwidth = singledimen(*argv+2, argerror, usage);
	    break;
	 case 'H':	/* input page height */
	    inheight = singledimen(*argv+2, argerror, usage);
	    break;
	 case 'P':	/* input paper type */
	    if ( (paper = findpaper(*argv+2)) != (Paper *)0 ) {
	       inwidth = (double)PaperWidth(paper);
	       inheight = (double)PaperHeight(paper);
	    } else
	       message(FATAL, "paper size '%s' not recognised\n", *argv+2);
	    break;
	 case 'v':	/* version */
	 default:
	    usage();
	 }
      } else if (infile == stdin) {
	 if ((infile = fopen(*argv, OPEN_READ)) == NULL)
	    message(FATAL, "can't open input file %s\n", *argv);
      } else if (outfile == stdout) {
	 if ((outfile = fopen(*argv, OPEN_WRITE)) == NULL)
	    message(FATAL, "can't open output file %s\n", *argv);
      } else usage();
   }
#if defined(MSDOS) || defined(WINNT) || defined(WIN32)
   if ( infile == stdin ) {
      int fd = fileno(stdin) ;
      if ( setmode(fd, O_BINARY) < 0 )
         message(FATAL, "can't open input file %s\n", argv[4]);
    }
   if ( outfile == stdout ) {
      int fd = fileno(stdout) ;
      if ( setmode(fd, O_BINARY) < 0 )
         message(FATAL, "can't reset stdout to binary mode\n");
    }
#endif
   if ((infile=seekable(infile))==NULL)
      message(FATAL, "can't seek input\n");

   if (width <= 0 || height <= 0)
      message(FATAL, "output page width and height must be set\n");

   if (inwidth <= 0 || inheight <= 0)
      message(FATAL, "input page width and height must be set\n");

   /* try normal orientation first */
   scale = MIN(width/inwidth, height/inheight);
   waste = (width-scale*inwidth)*(width-scale*inwidth) +
      (height-scale*inheight)*(height-scale*inheight);
   hshift = (width - inwidth*scale)/2;
   vshift = (height - inheight*scale)/2;

   /* try rotated orientation */
   rscale = MIN(height/inwidth, width/inheight);
   rwaste = (height-scale*inwidth)*(height-scale*inwidth) +
      (width-scale*inheight)*(width-scale*inheight);
   if (rwaste < waste) {
      double tmp = width;
      scale = rscale;
      hshift = (width + inheight*scale)/2;
      vshift = (height - inwidth*scale)/2;
      rotate = 1;
      width = height;
      height = tmp;
   }

   width /= scale;
   height /= scale;

   /* now construct specification list and run page rearrangement procedure */
   specs = newspec();

   if (rotate) {
      specs->rotate = 90;
      specs->flags |= ROTATE;
   }
   specs->pageno = 0;
   specs->scale = scale;
   specs->flags |= SCALE;
   specs->xoff = hshift;
   specs->yoff = vshift;
   specs->flags |= OFFSET;
      
   pstops(1, 1, 0, specs, 0.0);		/* do page rearrangement */

   exit(0);
}
Пример #12
0
void main(int argc, char *argv[])
{
   int horiz, vert, rotate, column, flip, leftright, topbottom;
   int nup = 1;
   double draw = 0;				/* draw page borders */
   double scale;				/* page scale */
   double uscale = 0;				/* user supplied scale */
   double ppwid, pphgt;				/* paper dimensions */
   double margin, border;			/* paper & page margins */
   double vshift, hshift;			/* page centring shifts */
   double iwidth, iheight ;			/* input paper size */
   double tolerance = 100000;			/* layout tolerance */
   Paper *paper;

#ifdef PAPER
   if ( (paper = findpaper(PAPER)) != (Paper *)0 ) {
      width = (double)PaperWidth(paper);
      height = (double)PaperHeight(paper);
   }
#endif

   margin = border = vshift = hshift = column = flip = 0;
   leftright = topbottom = 1;
   iwidth = iheight = -1 ;

   infile = stdin;
   outfile = stdout;
   verbose = 1;
   for (program = *argv++; --argc; argv++) {
      if (argv[0][0] == '-') {
	 switch (argv[0][1]) {
	 case 'q':	/* quiet */
	    verbose = 0;
	    break;
	 case 'd':	/* draw borders */
	    if (argv[0][2])
	       draw = singledimen(*argv+2, argerror, usage);
	    else
	       draw = 1;
	    break;
	 case 'l':	/* landscape (rotated left) */
	    column = !column;
	    topbottom = !topbottom;
	    break;
	 case 'r':	/* seascape (rotated right) */
	    column = !column;
	    leftright = !leftright;
	    break;
	 case 'f':	/* flipped */
	    flip = 1;
	    break;
	 case 'c':	/* column major layout */
	    column = !column;
	    break;
	 case 'w':	/* page width */
	    width = singledimen(*argv+2, argerror, usage);
	    break;
	 case 'W':	/* input page width */
	    iwidth = singledimen(*argv+2, argerror, usage);
	    break;
	 case 'h':	/* page height */
	    height = singledimen(*argv+2, argerror, usage);
	    break;
	 case 'H':	/* input page height */
	    iheight = singledimen(*argv+2, argerror, usage);
	    break;
	 case 'm':	/* margins around whole page */
	    margin = singledimen(*argv+2, argerror, usage);
	    break;
	 case 'b':	/* border around individual pages */
	    border = singledimen(*argv+2, argerror, usage);
	    break;
	 case 't':	/* layout tolerance */
	    tolerance = atof(*argv+2);
	    break;
	 case 's':	/* override scale */
	    uscale = atof(*argv+2);
	    break;
	 case 'p':	/* output (and by default input) paper type */
	    if ( (paper = findpaper(*argv+2)) != (Paper *)0 ) {
	       width = (double)PaperWidth(paper);
	       height = (double)PaperHeight(paper);
	    } else
	       message(FATAL, "paper size '%s' not recognised\n", *argv+2);
	    break;
	 case 'P':	/* paper type */
	    if ( (paper = findpaper(*argv+2)) != (Paper *)0 ) {
	       iwidth = (double)PaperWidth(paper);
	       iheight = (double)PaperHeight(paper);
	    } else
	       message(FATAL, "paper size '%s' not recognised\n", *argv+2);
	    break;
	 case 'n':	/* n-up, for compatibility with other psnups */
	    if (argc >= 2) {
	       argv++;
	       argc--;
	       if ((nup = atoi(*argv)) < 1)
		  message(FATAL, "-n %d too small\n", nup);
	    } else
	       message(FATAL, "argument expected for -n\n");
	    break;
	 case '1':
	 case '2':
	 case '3':
	 case '4':
	 case '5':
	 case '6':
	 case '7':
	 case '8':
	 case '9':
	    nup = atoi(*argv+1);
	    break;
	 case 'v':	/* version */
	 default:
	    usage();
	 }
      } else if (infile == stdin) {
	 if ((infile = fopen(*argv, OPEN_READ)) == NULL)
	    message(FATAL, "can't open input file %s\n", *argv);
      } else if (outfile == stdout) {
	 if ((outfile = fopen(*argv, OPEN_WRITE)) == NULL)
	    message(FATAL, "can't open output file %s\n", *argv);
      } else usage();
   }
#if defined(MSDOS) || defined(WINNT)
   if ( infile == stdin ) {
      int fd = fileno(stdin) ;
      if ( setmode(fd, O_BINARY) < 0 )
         message(FATAL, "can't open input file %s\n", argv[4]);
    }
   if ( outfile == stdout ) {
      int fd = fileno(stdout) ;
      if ( setmode(fd, O_BINARY) < 0 )
         message(FATAL, "can't reset stdout to binary mode\n");
    }
#endif
   if ((infile=seekable(infile))==NULL)
      message(FATAL, "can't seek input\n");

   if (width <= 0 || height <= 0)
      message(FATAL, "page width and height must be set\n");

   /* subtract paper margins from height & width */
   ppwid = width - margin*2;
   pphgt = height - margin*2;

   if (ppwid <= 0 || pphgt <= 0)
      message(FATAL, "paper margins are too large\n");

   /* set default values of input height & width */
   if ( iwidth > 0 )
     width = iwidth ;
   if ( iheight > 0 )
     height = iheight ;

   /* Finding the best layout is an optimisation problem. We try all of the
    * combinations of width*height in both normal and rotated form, and
    * minimise the wasted space. */
   {
      double best = tolerance;
      int hor;
      for (hor = 1; hor; hor = nextdiv(hor, nup)) {
	 int ver = nup/hor;
	 /* try normal orientation first */
	 double scl = MIN(pphgt/(height*ver), ppwid/(width*hor));
	 double optim = (ppwid-scl*width*hor)*(ppwid-scl*width*hor) +
	    (pphgt-scl*height*ver)*(pphgt-scl*height*ver);
	 if (optim < best) {
	    best = optim;
	    /* recalculate scale to allow for internal borders */
	    scale = MIN((pphgt-2*border*ver)/(height*ver),
			(ppwid-2*border*hor)/(width*hor));
	    hshift = (ppwid/hor - width*scale)/2;
	    vshift = (pphgt/ver - height*scale)/2;
	    horiz = hor; vert = ver;
	    rotate = flip;
	 }
	 /* try rotated orientation */
	 scl = MIN(pphgt/(width*hor), ppwid/(height*ver));
	 optim = (pphgt-scl*width*hor)*(pphgt-scl*width*hor) +
	    (ppwid-scl*height*ver)*(ppwid-scl*height*ver);
	 if (optim < best) {
	    best = optim;
	    /* recalculate scale to allow for internal borders */
	    scale = MIN((pphgt-2*border*hor)/(width*hor),
			(ppwid-2*border*ver)/(height*ver));
	    hshift = (ppwid/ver - height*scale)/2;
	    vshift = (pphgt/hor - width*scale)/2;
	    horiz = ver; vert = hor;
	    rotate = !flip;
	 }
      }

      /* fail if nothing better than worst tolerance was found */
      if (best == tolerance)
	 message(FATAL, "can't find acceptable layout for %d-up\n", nup);
   }

   if (flip) {	/* swap width & height for clipping */
      double tmp = width;
      width = height;
      height = tmp;
   }

   if (rotate) {	/* rotate leftright and topbottom orders */
      int tmp = topbottom;
      topbottom = !leftright;
      leftright = tmp;
      column = !column;
   }

   /* now construct specification list and run page rearrangement procedure */
   {
      int page = 0;
      PageSpec *specs, *tail;

      tail = specs = newspec();

      while (page < nup) {
	 int up, across;		/* page index */

	 if (column) {
	    if (leftright)		/* left to right */
	       across = page/vert;
	    else			/* right to left */
	       across = horiz-1-page/vert;
	    if (topbottom)		/* top to bottom */
	       up = vert-1-page%vert;
	    else			/* bottom to top */
	       up = page%vert;
	 } else {
	    if (leftright)		/* left to right */
	       across = page%horiz;
	    else			/* right to left */
	       across = horiz-1-page%horiz;
	    if (topbottom)		/* top to bottom */
	       up = vert-1-page/horiz;
	    else			/* bottom to top */
	       up = page/horiz;
	 }
	 if (rotate) {
	    tail->xoff = margin + (across+1)*ppwid/horiz - hshift;
	    tail->rotate = 90;
	    tail->flags |= ROTATE;
	 } else {
	    tail->xoff = margin + across*ppwid/horiz + hshift;
	 }
	 tail->pageno = page;
	 if (uscale > 0)
	    tail->scale = uscale;
	 else
	    tail->scale = scale;
	 tail->flags |= SCALE;
	 tail->yoff = margin + up*pphgt/vert + vshift;
	 tail->flags |= OFFSET;
	 if (++page < nup) {
	    tail->flags |= ADD_NEXT;
	    tail->next = newspec();
	    tail = tail->next;
	 }
      }
      
      pstops(nup, 1, 0, specs, draw);		/* do page rearrangement */
   }

   exit(0);
}
Пример #13
0
int
main(int argc, char *argv[])
{
   double scale, rscale;			/* page scale */
   double waste, rwaste;			/* amount wasted */
   double vshift, hshift;			/* page centring shifts */
   int rotate;
   double inwidth = -1;
   double inheight = -1;
   off_t sizeheaders[20];			/* headers to remove */
   PageSpec *specs;
   int opt;
   const struct paper *paper = NULL;

   set_paper_size(NULL);

   vshift = hshift = 0;
   rotate = 0;

   verbose = 1;

   program = *argv;

   while((opt = getopt(argc, argv,
                       "qw:h:p:W:H:P:")) != EOF) {
     switch(opt) {

     case 'q':	/* quiet */
       verbose = 0;
       break;
     case 'w':	/* page width */
       width = singledimen(optarg);
       break;
     case 'h':	/* page height */
       height = singledimen(optarg);
       break;
     case 'p':	/* paper type */
       if ( (paper = paperinfo(optarg)) != NULL ) {
         width = paperpswidth(paper);
         height = paperpsheight(paper);
       } else
         message(FATAL, "paper size '%s' not recognised\n", optarg);
       break;
     case 'W':	/* input page width */
       inwidth = singledimen(optarg);
       break;
     case 'H':	/* input page height */
       inheight = singledimen(optarg);
       break;
     case 'P':	/* input paper type */
       if ( (paper = paperinfo(optarg)) != NULL ) {
         inwidth = paperpswidth(paper);
         inheight = paperpsheight(paper);
       } else
         message(FATAL, "paper size '%s' not recognised\n", optarg);
       break;
     case 'v':	/* version */
     default:
       usage();
     }
   }

   infile = stdin;
   outfile = stdout;

   /* Be defensive */
   if((argc - optind) < 0 || (argc - optind) > 2) usage();

   if (optind != argc) {
     /* User specified an input file */
     if ((infile = fopen(argv[optind], "rb")) == NULL)
       message(FATAL, "can't open input file %s\n", argv[optind]);
     optind++;
   }

   if (optind != argc) {
     /* User specified an output file */
     if ((outfile = fopen(argv[optind], "wb")) == NULL)
       message(FATAL, "can't open output file %s\n", argv[optind]);
     optind++;
   }

   if (optind != argc) usage();

   if ((infile=seekable(infile))==NULL)
      message(FATAL, "can't seek input\n");

   if (width <= 0 || height <= 0)
      message(FATAL, "output page width and height must be set\n");

   scanpages(sizeheaders);

   if (inwidth <= 0 || inheight <= 0)
      message(FATAL, "input page width and height must be set\n");

   /* try normal orientation first */
   scale = MIN(width/inwidth, height/inheight);
   waste = (width-scale*inwidth)*(width-scale*inwidth) +
      (height-scale*inheight)*(height-scale*inheight);
   hshift = (width - inwidth*scale)/2;
   vshift = (height - inheight*scale)/2;

   /* try rotated orientation */
   rscale = MIN(height/inwidth, width/inheight);
   rwaste = (height-scale*inwidth)*(height-scale*inwidth) +
      (width-scale*inheight)*(width-scale*inheight);
   if (rwaste < waste) {
      double tmp = width;
      scale = rscale;
      hshift = (width + inheight*scale)/2;
      vshift = (height - inwidth*scale)/2;
      rotate = 1;
      width = height;
      height = tmp;
   }

   width /= scale;
   height /= scale;

   /* now construct specification list and run page rearrangement procedure */
   specs = newspec();

   if (rotate) {
      specs->rotate = 90;
      specs->flags |= ROTATE;
   }
   specs->pageno = 0;
   specs->scale = scale;
   specs->flags |= SCALE;
   specs->xoff = hshift;
   specs->yoff = vshift;
   specs->flags |= OFFSET;
      
   pstops_write(1, 1, 0, specs, 0.0, sizeheaders); /* do page rearrangement */

   return 0;
}
Пример #14
0
int
main(int argc, char *argv[])
{
   int signature = 0;
   int currentpg, maxpage;
   int opt;

   verbose = 1;
   program = *argv;

   while((opt = getopt(argc, argv, "vqs:")) != EOF) {
     switch(opt) {
     case 's':	/* signature size */
       signature = atoi(optarg);
       if (signature < 1 || signature % 4) usage();
       break;
     case 'q':	/* quiet */
       verbose = 0;
       break;
     case 'v':	/* version */
     default:
       usage();
       break;
     }
   }

   infile = stdin;
   outfile = stdout;

   /* Be defensive */
   if((argc - optind) < 0 || (argc - optind) > 2) usage();

   if (optind != argc) {
     /* User specified an input file */
     if ((infile = fopen(argv[optind], "rb")) == NULL)
       message(FATAL, "can't open input file %s\n", argv[optind]);
     optind++;
   }

   if (optind != argc) {
     /* User specified an output file */
     if ((outfile = fopen(argv[optind], "wb")) == NULL)
       message(FATAL, "can't open output file %s\n", argv[optind]);
     optind++;
   }

   if(optind != argc) usage();

   if ((infile=seekable(infile))==NULL)
      message(FATAL, "can't seek input\n");

   scanpages(NULL);

   if (!signature)
      signature = maxpage = pages+(4-pages%4)%4;
   else
      maxpage = pages+(signature-pages%signature)%signature;

   /* rearrange pages */
   writeheader(maxpage, NULL);
   writeprolog();
   writesetup();
   for (currentpg = 0; currentpg < maxpage; currentpg++) {
      int actualpg = currentpg - currentpg%signature;
      switch(currentpg%4) {
      case 0:
      case 3:
	 actualpg += signature-1-(currentpg%signature)/2;
	 break;
      case 1:
      case 2:
	 actualpg += (currentpg%signature)/2;
	 break;
      default: /* Avoid a compiler warning */
         break;
      }
      if (actualpg < pages)
	 writepage(actualpg);
      else
	 writeemptypage();
   }
   writetrailer();

   return 0;
}