|
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 "DjVuImage.h"
|
|
Packit |
df99a1 |
#include "GScaler.h"
|
|
Packit |
df99a1 |
#include "DjVuDocument.h"
|
|
Packit |
df99a1 |
#include "DjVuPalette.h"
|
|
Packit |
df99a1 |
#include "GContainer.h"
|
|
Packit |
df99a1 |
#include "GSmartPointer.h"
|
|
Packit |
df99a1 |
#include "JB2Image.h"
|
|
Packit |
df99a1 |
#include "IW44Image.h"
|
|
Packit |
df99a1 |
#include "DataPool.h"
|
|
Packit |
df99a1 |
#include "ByteStream.h"
|
|
Packit |
df99a1 |
#include "GMapAreas.h"
|
|
Packit |
df99a1 |
#include "DjVuText.h"
|
|
Packit |
df99a1 |
#include "IFFByteStream.h"
|
|
Packit |
df99a1 |
#include "BSByteStream.h"
|
|
Packit |
df99a1 |
#include "debug.h"
|
|
Packit |
df99a1 |
#include <stdarg.h>
|
|
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 |
|
|
Packit |
df99a1 |
//// DJVUIMAGE: CONSTRUCTION
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
DjVuImage::DjVuImage(void)
|
|
Packit |
df99a1 |
: rotate_count(-1),relayout_sent(false)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
DjVuImage::connect(const GP<DjVuFile> & xfile)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
file=xfile;
|
|
Packit |
df99a1 |
DjVuPort::get_portcaster()->add_route(file, this);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
//// DJVUIMAGE: DATA COLLECTORS
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GP<DjVuInfo>
|
|
Packit |
df99a1 |
DjVuImage::get_info(const GP<DjVuFile> & file) const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (file->info)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if(rotate_count<0)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
const_cast<DjVuImage *>(this)->init_rotate(*(file->info));
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
return file->info;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
GPList<DjVuFile> list=file->get_included_files();
|
|
Packit |
df99a1 |
for(GPosition pos=list;pos;++pos)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<DjVuInfo> info=get_info(list[pos]);
|
|
Packit |
df99a1 |
if (info)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if(rotate_count<0)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
const_cast<DjVuImage *>(this)->init_rotate(*(file->info));
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
return info;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GP<IW44Image>
|
|
Packit |
df99a1 |
DjVuImage::get_bg44(const GP<DjVuFile> & file) const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (file->bg44)
|
|
Packit |
df99a1 |
return file->bg44;
|
|
Packit |
df99a1 |
GPList<DjVuFile> list=file->get_included_files();
|
|
Packit |
df99a1 |
for(GPosition pos=list;pos;++pos)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<IW44Image> bg44=get_bg44(list[pos]);
|
|
Packit |
df99a1 |
if (bg44)
|
|
Packit |
df99a1 |
return bg44;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GP<GPixmap>
|
|
Packit |
df99a1 |
DjVuImage::get_bgpm(const GP<DjVuFile> & file) const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (file->bgpm)
|
|
Packit |
df99a1 |
return file->bgpm;
|
|
Packit |
df99a1 |
GPList<DjVuFile> list=file->get_included_files();
|
|
Packit |
df99a1 |
for(GPosition pos=list;pos;++pos)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<GPixmap> bgpm=get_bgpm(list[pos]);
|
|
Packit |
df99a1 |
if (bgpm) return bgpm;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GP<JB2Image>
|
|
Packit |
df99a1 |
DjVuImage::get_fgjb(const GP<DjVuFile> & file) const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (file->fgjb)
|
|
Packit |
df99a1 |
return file->fgjb;
|
|
Packit |
df99a1 |
GPList<DjVuFile> list=file->get_included_files();
|
|
Packit |
df99a1 |
for(GPosition pos=list;pos;++pos)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<JB2Image> fgjb=get_fgjb(list[pos]);
|
|
Packit |
df99a1 |
if (fgjb)
|
|
Packit |
df99a1 |
return fgjb;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GP<GPixmap>
|
|
Packit |
df99a1 |
DjVuImage::get_fgpm(const GP<DjVuFile> & file) const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (file->fgpm)
|
|
Packit |
df99a1 |
return file->fgpm;
|
|
Packit |
df99a1 |
GPList<DjVuFile> list=file->get_included_files();
|
|
Packit |
df99a1 |
for(GPosition pos=list;pos;++pos)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<GPixmap> fgpm=get_fgpm(list[pos]);
|
|
Packit |
df99a1 |
if (fgpm)
|
|
Packit |
df99a1 |
return fgpm;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GP<DjVuPalette>
|
|
Packit |
df99a1 |
DjVuImage::get_fgbc(const GP<DjVuFile> & file) const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (file->fgbc)
|
|
Packit |
df99a1 |
return file->fgbc;
|
|
Packit |
df99a1 |
GPList<DjVuFile> list=file->get_included_files();
|
|
Packit |
df99a1 |
for(GPosition pos=list;pos;++pos)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<DjVuPalette> fgbc=get_fgbc(list[pos]);
|
|
Packit |
df99a1 |
if (fgbc) return fgbc;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GP<DjVuInfo>
|
|
Packit |
df99a1 |
DjVuImage::get_info() const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (file)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
return get_info(file);
|
|
Packit |
df99a1 |
}else
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GP<ByteStream>
|
|
Packit |
df99a1 |
DjVuImage::get_anno() const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<ByteStream> out = ByteStream::create();
|
|
Packit |
df99a1 |
ByteStream &mbs = *out;
|
|
Packit |
df99a1 |
if (file)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
file->merge_anno(mbs);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
mbs.seek(0);
|
|
Packit |
df99a1 |
if(!mbs.size())
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
out=0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
return out;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GP<ByteStream>
|
|
Packit |
df99a1 |
DjVuImage::get_text() const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<ByteStream> out = ByteStream::create();
|
|
Packit |
df99a1 |
ByteStream &mbs = *out;
|
|
Packit |
df99a1 |
if (file)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
file->get_text(mbs);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
mbs.seek(0);
|
|
Packit |
df99a1 |
if(!mbs.size())
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
out=0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
return out;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GP<ByteStream>
|
|
Packit |
df99a1 |
DjVuImage::get_meta() const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<ByteStream> out = ByteStream::create();
|
|
Packit |
df99a1 |
ByteStream &mbs = *out;
|
|
Packit |
df99a1 |
if (file)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
file->get_meta(mbs);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
mbs.seek(0);
|
|
Packit |
df99a1 |
if(!mbs.size())
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
out=0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
return out;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GP<IW44Image>
|
|
Packit |
df99a1 |
DjVuImage::get_bg44() const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (file)
|
|
Packit |
df99a1 |
return get_bg44(file);
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GP<GPixmap>
|
|
Packit |
df99a1 |
DjVuImage::get_bgpm() const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (file)
|
|
Packit |
df99a1 |
return get_bgpm(file);
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GP<JB2Image>
|
|
Packit |
df99a1 |
DjVuImage::get_fgjb() const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (file)
|
|
Packit |
df99a1 |
return get_fgjb(file);
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GP<GPixmap>
|
|
Packit |
df99a1 |
DjVuImage::get_fgpm() const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (file)
|
|
Packit |
df99a1 |
return get_fgpm(file);
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GP<DjVuPalette>
|
|
Packit |
df99a1 |
DjVuImage::get_fgbc() const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (file)
|
|
Packit |
df99a1 |
return get_fgbc(file);
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
int
|
|
Packit |
df99a1 |
DjVuImage::get_width() const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<DjVuInfo> info=get_info();
|
|
Packit |
df99a1 |
return info?((rotate_count&1)?(info->height):(info->width)):0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
int
|
|
Packit |
df99a1 |
DjVuImage::get_height() const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<DjVuInfo> info=get_info();
|
|
Packit |
df99a1 |
return info?((rotate_count&1)?(info->width):(info->height)):0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
int
|
|
Packit |
df99a1 |
DjVuImage::get_real_width() const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<DjVuInfo> info=get_info();
|
|
Packit |
df99a1 |
return info ? info->width : 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
int
|
|
Packit |
df99a1 |
DjVuImage::get_real_height() const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<DjVuInfo> info=get_info();
|
|
Packit |
df99a1 |
return info ? info->height : 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
int
|
|
Packit |
df99a1 |
DjVuImage::get_version() const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<DjVuInfo> info=get_info();
|
|
Packit |
df99a1 |
return info ? info->version : DJVUVERSION;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
int
|
|
Packit |
df99a1 |
DjVuImage::get_dpi() const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<DjVuInfo> info=get_info();
|
|
Packit |
df99a1 |
return info ? info->dpi : 300;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
int
|
|
Packit |
df99a1 |
DjVuImage::get_rounded_dpi() const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
return (get_dpi()+5)/10*10;
|
|
Packit |
df99a1 |
#if 0
|
|
Packit |
df99a1 |
/* This code used to round the reported dpi to 25, 50, 75, 100, 150,
|
|
Packit |
df99a1 |
300, and 600. Now we just round the dpi to 10ths and return it */
|
|
Packit |
df99a1 |
int dpi=get_dpi();
|
|
Packit |
df99a1 |
if (dpi>700) return dpi;
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
const int std_dpi[]={ 25, 50, 75, 100, 150, 300, 600 };
|
|
Packit |
df99a1 |
const int std_dpis=sizeof(std_dpi)/sizeof(std_dpi[0]);
|
|
Packit |
df99a1 |
int min_dist=abs(dpi-std_dpi[0]);
|
|
Packit |
df99a1 |
int min_idx=0;
|
|
Packit |
df99a1 |
for(int i=1;i
|
|
Packit |
df99a1 |
if (abs(std_dpi[i]-dpi)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
min_dist=abs(std_dpi[i]-dpi);
|
|
Packit |
df99a1 |
min_idx=i;
|
|
Packit |
df99a1 |
};
|
|
Packit |
df99a1 |
return std_dpi[min_idx];
|
|
Packit |
df99a1 |
#endif
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
double
|
|
Packit |
df99a1 |
DjVuImage::get_gamma() const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<DjVuInfo> info=get_info();
|
|
Packit |
df99a1 |
return info ? info->gamma : 2.2;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GUTF8String
|
|
Packit |
df99a1 |
DjVuImage::get_mimetype() const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
return file ? file->mimetype : GUTF8String();
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
//// DJVUIMAGE: UTILITIES
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GUTF8String
|
|
Packit |
df99a1 |
DjVuImage::get_short_description() const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GUTF8String msg = "Empty";
|
|
Packit |
df99a1 |
int width = get_width();
|
|
Packit |
df99a1 |
int height = get_height();
|
|
Packit |
df99a1 |
if (width && height)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (file && file->file_size>100)
|
|
Packit |
df99a1 |
//msg.format("%dx%d in %0.1f Kb", width, height, file->file_size/1024.0);
|
|
Packit |
df99a1 |
msg.format( ERR_MSG("DjVuImage.short1") "\t%d\t%d\t%0.1f",
|
|
Packit |
df99a1 |
width, height, file->file_size/1024.0 );
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
//msg.format("%dx%d", width, height);
|
|
Packit |
df99a1 |
msg.format( ERR_MSG("DjVuImage.short2") "\t%d\t%d", width, height );
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
return msg;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GUTF8String
|
|
Packit |
df99a1 |
DjVuImage::get_long_description() const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
return file?(file->description):GUTF8String();
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
DjVuImage::notify_chunk_done(const DjVuPort *, const GUTF8String & name)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (!relayout_sent &&
|
|
Packit |
df99a1 |
( !name.cmp("INFO", 4) ||
|
|
Packit |
df99a1 |
!name.cmp("PMxx", 2) ||
|
|
Packit |
df99a1 |
!name.cmp("BMxx", 2) ) )
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
DjVuPort::get_portcaster()->notify_relayout(this);
|
|
Packit |
df99a1 |
relayout_sent=true;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else if (!name.cmp("Sxxx", 1) ||
|
|
Packit |
df99a1 |
!name.cmp("BGxx", 2) ||
|
|
Packit |
df99a1 |
!name.cmp("FGxx", 2) ||
|
|
Packit |
df99a1 |
!name.cmp("BMxx", 2) ||
|
|
Packit |
df99a1 |
!name.cmp("PMxx", 2) )
|
|
Packit |
df99a1 |
DjVuPort::get_portcaster()->notify_redisplay(this);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
//// DJVUIMAGE: OLD-STYLE DECODING
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
DjVuInterface::~DjVuInterface()
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
class DjVuImageNotifier : public DjVuPort
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
friend class DjVuImage;
|
|
Packit |
df99a1 |
DjVuInterface *notifier;
|
|
Packit |
df99a1 |
GP<DataPool> stream_pool;
|
|
Packit |
df99a1 |
GURL stream_url;
|
|
Packit |
df99a1 |
public:
|
|
Packit |
df99a1 |
DjVuImageNotifier(DjVuInterface *notifier);
|
|
Packit |
df99a1 |
GP<DataPool> request_data(const DjVuPort *src, const GURL & url);
|
|
Packit |
df99a1 |
void notify_chunk_done(const DjVuPort *, const GUTF8String &name);
|
|
Packit |
df99a1 |
void notify_redisplay(const class DjVuImage * source);
|
|
Packit |
df99a1 |
void notify_relayout(const class DjVuImage * source);
|
|
Packit |
df99a1 |
};
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
DjVuImageNotifier::DjVuImageNotifier(DjVuInterface *notifier)
|
|
Packit |
df99a1 |
: notifier(notifier)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GP<DataPool>
|
|
Packit |
df99a1 |
DjVuImageNotifier::request_data(const DjVuPort *src, const GURL & url)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (url!=stream_url)
|
|
Packit |
df99a1 |
G_THROW( ERR_MSG("DjVuImage.not_decode") );
|
|
Packit |
df99a1 |
return stream_pool;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
DjVuImageNotifier::notify_redisplay(const class DjVuImage * source)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (notifier)
|
|
Packit |
df99a1 |
notifier->notify_redisplay();
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
DjVuImageNotifier::notify_relayout(const class DjVuImage * source)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (notifier)
|
|
Packit |
df99a1 |
notifier->notify_relayout();
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
DjVuImageNotifier::notify_chunk_done(const DjVuPort *, const GUTF8String &name)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (notifier)
|
|
Packit |
df99a1 |
notifier->notify_chunk(name, "" );
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
DjVuImage::decode(ByteStream & str, DjVuInterface *notifier)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
DEBUG_MSG("DjVuImage::decode(): decoding old way...\n");
|
|
Packit |
df99a1 |
DEBUG_MAKE_INDENT(3);
|
|
Packit |
df99a1 |
if (file)
|
|
Packit |
df99a1 |
G_THROW( ERR_MSG("DjVuImage.bad_call") );
|
|
Packit |
df99a1 |
GP<DjVuImageNotifier> pport = new DjVuImageNotifier(notifier);
|
|
Packit |
df99a1 |
pport->stream_url=GURL::UTF8("internal://fake/fake.djvu");
|
|
Packit |
df99a1 |
pport->stream_pool=DataPool::create();
|
|
Packit |
df99a1 |
// Get all the data first
|
|
Packit |
df99a1 |
int length;
|
|
Packit |
df99a1 |
char buffer[1024];
|
|
Packit |
df99a1 |
while((length=str.read(buffer, 1024)))
|
|
Packit |
df99a1 |
pport->stream_pool->add_data(buffer, length);
|
|
Packit |
df99a1 |
pport->stream_pool->set_eof();
|
|
Packit |
df99a1 |
GP<DjVuDocument> doc = DjVuDocument::create_wait(pport->stream_url, (DjVuImageNotifier*)pport);
|
|
Packit |
df99a1 |
GP<DjVuImage> dimg=doc->get_page(-1, true, (DjVuImageNotifier*)pport);
|
|
Packit |
df99a1 |
file=dimg->get_djvu_file();
|
|
Packit |
df99a1 |
if (file->is_decode_stopped())
|
|
Packit |
df99a1 |
G_THROW( DataPool::Stop );
|
|
Packit |
df99a1 |
if (file->is_decode_failed())
|
|
Packit |
df99a1 |
G_THROW( ByteStream::EndOfFile ); // guess
|
|
Packit |
df99a1 |
if (!file->is_decode_ok())
|
|
Packit |
df99a1 |
G_THROW( ERR_MSG("DjVuImage.mult_error") );
|
|
Packit |
df99a1 |
DEBUG_MSG("decode DONE\n");
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
//// DJVUIMAGE: CHECKING
|
|
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 |
|
|
Packit |
df99a1 |
int
|
|
Packit |
df99a1 |
DjVuImage::is_legal_bilevel() const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
// Components
|
|
Packit |
df99a1 |
GP<DjVuInfo> info = get_info();
|
|
Packit |
df99a1 |
GP<JB2Image> fgjb = get_fgjb();
|
|
Packit |
df99a1 |
GP<IW44Image> bg44 = get_bg44();
|
|
Packit |
df99a1 |
GP<GPixmap> bgpm = get_bgpm();
|
|
Packit |
df99a1 |
GP<GPixmap> fgpm = get_fgpm();
|
|
Packit |
df99a1 |
// Check info
|
|
Packit |
df99a1 |
if (! info)
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
int width = info->width;
|
|
Packit |
df99a1 |
int height = info->height;
|
|
Packit |
df99a1 |
if (! (width>0 && height>0))
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
// Check fgjb
|
|
Packit |
df99a1 |
if (!fgjb)
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
if (fgjb->get_width()!=width || fgjb->get_height()!=height)
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
// Check that color information is not present.
|
|
Packit |
df99a1 |
if (bg44 || bgpm || fgpm)
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
// Ok.
|
|
Packit |
df99a1 |
return 1;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
int
|
|
Packit |
df99a1 |
DjVuImage::is_legal_photo() const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
// Components
|
|
Packit |
df99a1 |
GP<DjVuInfo> info = get_info();
|
|
Packit |
df99a1 |
GP<JB2Image> fgjb = get_fgjb();
|
|
Packit |
df99a1 |
GP<IW44Image> bg44 = get_bg44();
|
|
Packit |
df99a1 |
GP<GPixmap> bgpm = get_bgpm();
|
|
Packit |
df99a1 |
GP<GPixmap> fgpm = get_fgpm();
|
|
Packit |
df99a1 |
// Check info
|
|
Packit |
df99a1 |
if (! info)
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
int width = info->width;
|
|
Packit |
df99a1 |
int height = info->height;
|
|
Packit |
df99a1 |
if (! (width>0 && height>0))
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
// Check that extra information is not present.
|
|
Packit |
df99a1 |
if (fgjb || fgpm)
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
// Check bg44
|
|
Packit |
df99a1 |
if (bg44 && bg44->get_width()==width && bg44->get_height()==height)
|
|
Packit |
df99a1 |
return 1;
|
|
Packit |
df99a1 |
// Check bgpm
|
|
Packit |
df99a1 |
if (bgpm && (int)bgpm->columns()==width && (int)bgpm->rows()==height)
|
|
Packit |
df99a1 |
return 1;
|
|
Packit |
df99a1 |
// Ok.
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
int
|
|
Packit |
df99a1 |
DjVuImage::is_legal_compound() const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
// Components
|
|
Packit |
df99a1 |
GP<DjVuInfo> info = get_info();
|
|
Packit |
df99a1 |
GP<JB2Image> fgjb = get_fgjb();
|
|
Packit |
df99a1 |
GP<IW44Image> bg44 = get_bg44();
|
|
Packit |
df99a1 |
GP<GPixmap> bgpm = get_bgpm();
|
|
Packit |
df99a1 |
GP<GPixmap> fgpm = get_fgpm();
|
|
Packit |
df99a1 |
GP<DjVuPalette> fgbc = get_fgbc();
|
|
Packit |
df99a1 |
// Check size
|
|
Packit |
df99a1 |
if (! info)
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
int width = info->width;
|
|
Packit |
df99a1 |
int height = info->height;
|
|
Packit |
df99a1 |
if (! (width>0 && height>0))
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
// Check fgjb
|
|
Packit |
df99a1 |
if (!fgjb)
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
if (fgjb->get_width()!=width || fgjb->get_height()!=height)
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
// Check background
|
|
Packit |
df99a1 |
int bgred = 0;
|
|
Packit |
df99a1 |
if (bg44)
|
|
Packit |
df99a1 |
bgred = compute_red(width, height, bg44->get_width(), bg44->get_height());
|
|
Packit |
df99a1 |
else if (bgpm)
|
|
Packit |
df99a1 |
bgred = compute_red(width, height, bgpm->columns(), bgpm->rows());
|
|
Packit |
df99a1 |
if (bgred<1 || bgred>12)
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
// Check foreground colors
|
|
Packit |
df99a1 |
int fgred = 0;
|
|
Packit |
df99a1 |
if (fgbc)
|
|
Packit |
df99a1 |
fgred = 1;
|
|
Packit |
df99a1 |
else if (fgpm)
|
|
Packit |
df99a1 |
fgred = compute_red(width, height, fgpm->columns(), fgpm->rows());
|
|
Packit |
df99a1 |
if (fgred<1 || fgred>12)
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
// Check that all components are present
|
|
Packit |
df99a1 |
if (fgjb && bgred && fgred)
|
|
Packit |
df99a1 |
return 1;
|
|
Packit |
df99a1 |
// Unrecognized
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
//// DJVUIMAGE: LOW LEVEL RENDERING
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GP<GBitmap>
|
|
Packit |
df99a1 |
DjVuImage::get_bitmap(const GRect &rect,
|
|
Packit |
df99a1 |
int subsample, int align) const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
// Access image size
|
|
Packit |
df99a1 |
int width = get_real_width();
|
|
Packit |
df99a1 |
int height = get_real_height();
|
|
Packit |
df99a1 |
GP<JB2Image> fgjb = get_fgjb();
|
|
Packit |
df99a1 |
if ( width && height && fgjb &&
|
|
Packit |
df99a1 |
(fgjb->get_width() == width) &&
|
|
Packit |
df99a1 |
(fgjb->get_height() == height) )
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
return fgjb->get_bitmap(rect, subsample, align);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GP<GPixmap>
|
|
Packit |
df99a1 |
DjVuImage::get_bg_pixmap(const GRect &rect,
|
|
Packit |
df99a1 |
int subsample, double gamma, GPixel white) const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<GPixmap> pm = 0;
|
|
Packit |
df99a1 |
// Access image size
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GP<DjVuInfo> info = get_info();
|
|
Packit |
df99a1 |
int width = get_real_width();
|
|
Packit |
df99a1 |
int height = get_real_height();
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
if (width<=0 || height<=0 || !info) return 0;
|
|
Packit |
df99a1 |
// Compute gamma_correction
|
|
Packit |
df99a1 |
double gamma_correction = 1.0;
|
|
Packit |
df99a1 |
if (gamma > 0)
|
|
Packit |
df99a1 |
gamma_correction = gamma / info->gamma;
|
|
Packit |
df99a1 |
if (gamma_correction < 0.1)
|
|
Packit |
df99a1 |
gamma_correction = 0.1;
|
|
Packit |
df99a1 |
else if (gamma_correction > 10)
|
|
Packit |
df99a1 |
gamma_correction = 10;
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// CASE1: Incremental BG IW44Image
|
|
Packit |
df99a1 |
GP<IW44Image> bg44 = 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 |
// Determine how much bg44 is reduced
|
|
Packit |
df99a1 |
int red = compute_red(width,height,w,h);
|
|
Packit |
df99a1 |
if (red<1 || red>12)
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
// Handle pure downsampling cases
|
|
Packit |
df99a1 |
if (subsample == red)
|
|
Packit |
df99a1 |
pm = bg44->get_pixmap(1,rect);
|
|
Packit |
df99a1 |
else if (subsample == 2*red)
|
|
Packit |
df99a1 |
pm = bg44->get_pixmap(2,rect);
|
|
Packit |
df99a1 |
else if (subsample == 4*red)
|
|
Packit |
df99a1 |
pm = bg44->get_pixmap(4,rect);
|
|
Packit |
df99a1 |
else if (subsample == 8*red)
|
|
Packit |
df99a1 |
pm = bg44->get_pixmap(8,rect);
|
|
Packit |
df99a1 |
// Handle fractional downsampling case
|
|
Packit |
df99a1 |
else if (red*4 == subsample*3)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GRect nrect = rect;
|
|
Packit |
df99a1 |
GRect xrect = rect;
|
|
Packit |
df99a1 |
xrect.xmin = (xrect.xmin/3)*4;
|
|
Packit |
df99a1 |
xrect.ymin = (xrect.ymin/3)*4;
|
|
Packit |
df99a1 |
xrect.xmax = ((xrect.xmax+2)/3)*4;
|
|
Packit |
df99a1 |
xrect.ymax = ((xrect.ymax+2)/3)*4;
|
|
Packit |
df99a1 |
nrect.translate(-xrect.xmin*3/4, -xrect.ymin*3/4);
|
|
Packit |
df99a1 |
if (xrect.xmax > w)
|
|
Packit |
df99a1 |
xrect.xmax = w;
|
|
Packit |
df99a1 |
if (xrect.ymax > h)
|
|
Packit |
df99a1 |
xrect.ymax = h;
|
|
Packit |
df99a1 |
GP<GPixmap> ipm = bg44->get_pixmap(1,xrect);
|
|
Packit |
df99a1 |
pm = GPixmap::create();
|
|
Packit |
df99a1 |
pm->downsample43(ipm, &nrect);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
// Handle all other cases with pixmapscaler
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
// find suitable power of two
|
|
Packit |
df99a1 |
int po2 = 16;
|
|
Packit |
df99a1 |
while (po2>1 && subsample
|
|
Packit |
df99a1 |
po2 >>= 1;
|
|
Packit |
df99a1 |
// setup pixmap scaler
|
|
Packit |
df99a1 |
int inw = (w+po2-1)/po2;
|
|
Packit |
df99a1 |
int inh = (h+po2-1)/po2;
|
|
Packit |
df99a1 |
int outw = (width+subsample-1)/subsample;
|
|
Packit |
df99a1 |
int outh = (height+subsample-1)/subsample;
|
|
Packit |
df99a1 |
GP<GPixmapScaler> gps=GPixmapScaler::create(inw, inh, outw, outh);
|
|
Packit |
df99a1 |
GPixmapScaler &ps=*gps;
|
|
Packit |
df99a1 |
ps.set_horz_ratio(red*po2, subsample);
|
|
Packit |
df99a1 |
ps.set_vert_ratio(red*po2, subsample);
|
|
Packit |
df99a1 |
// run pixmap scaler
|
|
Packit |
df99a1 |
GRect xrect;
|
|
Packit |
df99a1 |
ps.get_input_rect(rect,xrect);
|
|
Packit |
df99a1 |
GP<GPixmap> ipm = bg44->get_pixmap(po2,xrect);
|
|
Packit |
df99a1 |
pm = GPixmap::create();
|
|
Packit |
df99a1 |
ps.scale(xrect, *ipm, rect, *pm);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
// Apply gamma correction
|
|
Packit |
df99a1 |
if (pm)
|
|
Packit |
df99a1 |
if (gamma_correction!=1.0 || white != GPixel::WHITE)
|
|
Packit |
df99a1 |
pm->color_correct(gamma_correction, white);
|
|
Packit |
df99a1 |
return pm;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// CASE 2: Raw background pixmap
|
|
Packit |
df99a1 |
GP<GPixmap> bgpm = 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 |
// Determine how much bgpm is reduced
|
|
Packit |
df99a1 |
int red = compute_red(width,height,w,h);
|
|
Packit |
df99a1 |
if (red<1 || red>12)
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
// Handle pure downsampling cases
|
|
Packit |
df99a1 |
int ratio = subsample/red;
|
|
Packit |
df99a1 |
if (subsample==ratio*red && ratio>=1)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
pm = GPixmap::create();
|
|
Packit |
df99a1 |
if (ratio == 1)
|
|
Packit |
df99a1 |
pm->init(*bgpm, rect);
|
|
Packit |
df99a1 |
else if (ratio > 1)
|
|
Packit |
df99a1 |
pm->downsample(bgpm, ratio, &rect);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
// Handle all other cases with pixmapscaler
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
// setup pixmap scaler
|
|
Packit |
df99a1 |
int outw = (width+subsample-1)/subsample;
|
|
Packit |
df99a1 |
int outh = (height+subsample-1)/subsample;
|
|
Packit |
df99a1 |
GP<GPixmapScaler> gps=GPixmapScaler::create(w, h, outw, outh);
|
|
Packit |
df99a1 |
GPixmapScaler &ps=*gps;
|
|
Packit |
df99a1 |
ps.set_horz_ratio(red, subsample);
|
|
Packit |
df99a1 |
ps.set_vert_ratio(red, subsample);
|
|
Packit |
df99a1 |
// run pixmap scaler
|
|
Packit |
df99a1 |
pm = GPixmap::create();
|
|
Packit |
df99a1 |
GRect xrect(0,0,w,h);
|
|
Packit |
df99a1 |
ps.scale(xrect, *bgpm, rect, *pm);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
// Apply gamma correction
|
|
Packit |
df99a1 |
if (pm)
|
|
Packit |
df99a1 |
if (gamma_correction!=1.0 || white != GPixel::WHITE)
|
|
Packit |
df99a1 |
pm->color_correct(gamma_correction, white);
|
|
Packit |
df99a1 |
return pm;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// FAILURE
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GP<GPixmap>
|
|
Packit |
df99a1 |
DjVuImage::get_bg_pixmap(const GRect &rect, int subsample, double gamma) const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
return get_bg_pixmap(rect, subsample, gamma, GPixel::WHITE);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
int
|
|
Packit |
df99a1 |
DjVuImage::stencil(GPixmap *pm, const GRect &rect,
|
|
Packit |
df99a1 |
int subsample, double gamma, GPixel white) const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
// Warping and blending.
|
|
Packit |
df99a1 |
if (!pm)
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
// Access components
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GP<DjVuInfo> info = get_info();
|
|
Packit |
df99a1 |
int width = get_real_width();
|
|
Packit |
df99a1 |
int height = get_real_height();
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
if (width<=0 || height<=0 || !info) return 0;
|
|
Packit |
df99a1 |
GP<JB2Image> fgjb = get_fgjb();
|
|
Packit |
df99a1 |
GP<GPixmap> fgpm = get_fgpm();
|
|
Packit |
df99a1 |
GP<DjVuPalette> fgbc = get_fgbc();
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// Compute gamma_correction
|
|
Packit |
df99a1 |
double gamma_correction = 1.0;
|
|
Packit |
df99a1 |
if (gamma > 0)
|
|
Packit |
df99a1 |
gamma_correction = gamma / info->gamma;
|
|
Packit |
df99a1 |
if (gamma_correction < 0.1)
|
|
Packit |
df99a1 |
gamma_correction = 0.1;
|
|
Packit |
df99a1 |
else if (gamma_correction > 10)
|
|
Packit |
df99a1 |
gamma_correction = 10;
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// Compute alpha map and relevant JB2Image components
|
|
Packit |
df99a1 |
GList<int> components;
|
|
Packit |
df99a1 |
GP<GBitmap> bm;
|
|
Packit |
df99a1 |
if (fgjb)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
JB2Image *jimg = fgjb;
|
|
Packit |
df99a1 |
if (! (width && height &&
|
|
Packit |
df99a1 |
jimg->get_width() == width &&
|
|
Packit |
df99a1 |
jimg->get_height() == height ) )
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
// Decode bitmap
|
|
Packit |
df99a1 |
bm = GBitmap::create(rect.height(), rect.width());
|
|
Packit |
df99a1 |
bm->set_grays(1+subsample*subsample);
|
|
Packit |
df99a1 |
int rxmin = rect.xmin * subsample;
|
|
Packit |
df99a1 |
int rymin = rect.ymin * subsample;
|
|
Packit |
df99a1 |
for (int blitno = 0; blitno < jimg->get_blit_count(); blitno++)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
const JB2Blit *pblit = jimg->get_blit(blitno);
|
|
Packit |
df99a1 |
const JB2Shape &pshape = jimg->get_shape(pblit->shapeno);
|
|
Packit |
df99a1 |
if (pshape.bits &&
|
|
Packit |
df99a1 |
pblit->left <= rect.xmax * subsample &&
|
|
Packit |
df99a1 |
pblit->bottom <= rect.ymax * subsample &&
|
|
Packit |
df99a1 |
pblit->left+(int)pshape.bits->columns() >= rect.xmin*subsample &&
|
|
Packit |
df99a1 |
pblit->bottom+(int)pshape.bits->rows() >= rect.ymin*subsample )
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
// Record component list
|
|
Packit |
df99a1 |
if (fgbc) components.append(blitno);
|
|
Packit |
df99a1 |
// Blit
|
|
Packit |
df99a1 |
bm->blit(pshape.bits,
|
|
Packit |
df99a1 |
pblit->left - rxmin, pblit->bottom - rymin,
|
|
Packit |
df99a1 |
subsample);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// TWO LAYER MODEL
|
|
Packit |
df99a1 |
if (bm && fgbc)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
// Perform attenuation from scratch
|
|
Packit |
df99a1 |
pm->attenuate(bm, 0, 0);
|
|
Packit |
df99a1 |
// Check that fgbc has the correct size
|
|
Packit |
df99a1 |
JB2Image *jimg = fgjb;
|
|
Packit |
df99a1 |
DjVuPalette *fg = fgbc;
|
|
Packit |
df99a1 |
if (jimg->get_blit_count() != fg->colordata.size())
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
// Copy and color correct palette
|
|
Packit |
df99a1 |
int palettesize = fg->size();
|
|
Packit |
df99a1 |
GTArray<GPixel> colors(0,palettesize-1);
|
|
Packit |
df99a1 |
for (int i=0; i
|
|
Packit |
df99a1 |
fg->index_to_color(i, colors[i]);
|
|
Packit |
df99a1 |
GPixmap::color_correct(gamma_correction, white, colors, palettesize);
|
|
Packit |
df99a1 |
// Blit all components (one color at a time)
|
|
Packit |
df99a1 |
while (components.size() > 0)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GPosition nullpos;
|
|
Packit |
df99a1 |
GPosition pos = components;
|
|
Packit |
df99a1 |
int lastx = 0;
|
|
Packit |
df99a1 |
int colorindex = fg->colordata[components[pos]];
|
|
Packit |
df99a1 |
if (colorindex >= palettesize)
|
|
Packit |
df99a1 |
G_THROW( ERR_MSG("DjVuImage.corrupted") );
|
|
Packit |
df99a1 |
// Gather relevant components and relevant rectangle
|
|
Packit |
df99a1 |
GList<int> compset;
|
|
Packit |
df99a1 |
GRect comprect;
|
|
Packit |
df99a1 |
while (pos)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
int blitno = components[pos];
|
|
Packit |
df99a1 |
const JB2Blit *pblit = jimg->get_blit(blitno);
|
|
Packit |
df99a1 |
if (pblit->left < lastx) break;
|
|
Packit |
df99a1 |
lastx = pblit->left;
|
|
Packit |
df99a1 |
if (fg->colordata[blitno] == colorindex)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
const JB2Shape &pshape = jimg->get_shape(pblit->shapeno);
|
|
Packit |
df99a1 |
GRect rect(pblit->left, pblit->bottom,
|
|
Packit |
df99a1 |
pshape.bits->columns(), pshape.bits->rows());
|
|
Packit |
df99a1 |
comprect.recthull(comprect, rect);
|
|
Packit |
df99a1 |
compset.insert_before(nullpos, components, pos);
|
|
Packit |
df99a1 |
continue;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
++pos;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
// Round alpha map rectangle
|
|
Packit |
df99a1 |
comprect.xmin = comprect.xmin / subsample;
|
|
Packit |
df99a1 |
comprect.ymin = comprect.ymin / subsample;
|
|
Packit |
df99a1 |
comprect.xmax = (comprect.xmax+subsample-1) / subsample;
|
|
Packit |
df99a1 |
comprect.ymax = (comprect.ymax+subsample-1) / subsample;
|
|
Packit |
df99a1 |
comprect.intersect(comprect, rect);
|
|
Packit |
df99a1 |
// Compute alpha map for that color
|
|
Packit |
df99a1 |
bm = 0;
|
|
Packit |
df99a1 |
bm = GBitmap::create(comprect.height(), comprect.width());
|
|
Packit |
df99a1 |
bm->set_grays(1+subsample*subsample);
|
|
Packit |
df99a1 |
int rxmin = comprect.xmin * subsample;
|
|
Packit |
df99a1 |
int rymin = comprect.ymin * subsample;
|
|
Packit |
df99a1 |
for (pos=compset; pos; ++pos)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
int blitno = compset[pos];
|
|
Packit |
df99a1 |
const JB2Blit *pblit = jimg->get_blit(blitno);
|
|
Packit |
df99a1 |
const JB2Shape &pshape = jimg->get_shape(pblit->shapeno);
|
|
Packit |
df99a1 |
bm->blit(pshape.bits,
|
|
Packit |
df99a1 |
pblit->left - rxmin, pblit->bottom - rymin,
|
|
Packit |
df99a1 |
subsample);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
// Blend color into background pixmap
|
|
Packit |
df99a1 |
pm->blit(bm, comprect.xmin-rect.xmin, comprect.ymin-rect.ymin,
|
|
Packit |
df99a1 |
&colors[colorindex]);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
return 1;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// THREE LAYER MODEL
|
|
Packit |
df99a1 |
if (bm && fgpm)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
// This follows fig. 4 in Adelson "Layered representations for image
|
|
Packit |
df99a1 |
// coding" (1991) http://www-bcs.mit.edu/people/adelson/papers.html.
|
|
Packit |
df99a1 |
// The properly warped background is already in PM. The properly warped
|
|
Packit |
df99a1 |
// alpha map is already in BM. We just have to warp the foreground and
|
|
Packit |
df99a1 |
// perform alpha blending.
|
|
Packit |
df99a1 |
#ifdef SIMPLE_THREE_LAYER_RENDERING
|
|
Packit |
df99a1 |
int w = fgpm->columns();
|
|
Packit |
df99a1 |
int h = fgpm->rows();
|
|
Packit |
df99a1 |
// Determine foreground reduction
|
|
Packit |
df99a1 |
int red = compute_red(width,height, w, h);
|
|
Packit |
df99a1 |
if (red<1 || red>12)
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
// Warp foreground pixmap
|
|
Packit |
df99a1 |
GPixmapScaler ps(w,h,width/subsample+1,height/subsample+1);
|
|
Packit |
df99a1 |
ps.set_horz_ratio(red,subsample);
|
|
Packit |
df99a1 |
ps.set_vert_ratio(red,subsample);
|
|
Packit |
df99a1 |
GP<GPixmap> nfg = new GPixmap;
|
|
Packit |
df99a1 |
GRect provided(0,0,w,h);
|
|
Packit |
df99a1 |
ps.scale(provided, *fgpm, rect, *nfg);
|
|
Packit |
df99a1 |
// Attenuate background and blit
|
|
Packit |
df99a1 |
nfg->color_correct(gamma_correction, white);
|
|
Packit |
df99a1 |
pm->blend(bm, 0, 0, nfg); // blend == attenuate + blit
|
|
Packit |
df99a1 |
return 1;
|
|
Packit |
df99a1 |
#else
|
|
Packit |
df99a1 |
// Things are now a little bit more complex because the convenient
|
|
Packit |
df99a1 |
// function GPixmap::stencil() simultaneously upsamples the foreground
|
|
Packit |
df99a1 |
// by an integer factor and performs the alpha blending. We have
|
|
Packit |
df99a1 |
// to determine how and when this facility can be used.
|
|
Packit |
df99a1 |
int w = fgpm->columns();
|
|
Packit |
df99a1 |
int h = fgpm->rows();
|
|
Packit |
df99a1 |
// Determine foreground reduction
|
|
Packit |
df99a1 |
int red = compute_red(width,height,w,h);
|
|
Packit |
df99a1 |
if (red<1 || red>12)
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
// Try supersampling foreground pixmap by an integer factor
|
|
Packit |
df99a1 |
int supersample = ( red>subsample ? red/subsample : 1);
|
|
Packit |
df99a1 |
int wantedred = supersample*subsample;
|
|
Packit |
df99a1 |
// Try simple foreground upsampling
|
|
Packit |
df99a1 |
if (red == wantedred)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
// Simple foreground upsampling is enough.
|
|
Packit |
df99a1 |
pm->stencil(bm, fgpm, supersample, &rect, gamma_correction, white);
|
|
Packit |
df99a1 |
return 1;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
// Must pre-warp foreground pixmap
|
|
Packit |
df99a1 |
GP<GPixmap> nfg;
|
|
Packit |
df99a1 |
int desw = (w*red+wantedred-1)/wantedred;
|
|
Packit |
df99a1 |
int desh = (h*red+wantedred-1)/wantedred;
|
|
Packit |
df99a1 |
// Cache rescaled fgpm for speed
|
|
Packit |
df99a1 |
static const DjVuImage *tagimage = 0;
|
|
Packit |
df99a1 |
static const GPixmap *tagfgpm = 0;
|
|
Packit |
df99a1 |
static GP<GPixmap> cachednfg = 0;
|
|
Packit |
df99a1 |
// Check whether cached fgpm applies.
|
|
Packit |
df99a1 |
if ( cachednfg && this==tagimage && fgpm==tagfgpm
|
|
Packit |
df99a1 |
&& desw==(int)cachednfg->columns()
|
|
Packit |
df99a1 |
&& desh==(int)cachednfg->rows() )
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
nfg = cachednfg;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<GPixmapScaler> gps=GPixmapScaler::create(w,h,desw,desh);
|
|
Packit |
df99a1 |
GPixmapScaler &ps=*gps;
|
|
Packit |
df99a1 |
ps.set_horz_ratio(red, wantedred);
|
|
Packit |
df99a1 |
ps.set_vert_ratio(red, wantedred);
|
|
Packit |
df99a1 |
nfg = GPixmap::create();
|
|
Packit |
df99a1 |
GRect provided(0,0,w,h);
|
|
Packit |
df99a1 |
GRect desired(0,0,desw,desh);
|
|
Packit |
df99a1 |
ps.scale(provided, *fgpm, desired, *nfg);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
// Use combined warp+blend function
|
|
Packit |
df99a1 |
pm->stencil(bm, nfg, supersample, &rect, gamma_correction, white);
|
|
Packit |
df99a1 |
// Cache
|
|
Packit |
df99a1 |
tagimage = this;
|
|
Packit |
df99a1 |
tagfgpm = fgpm;
|
|
Packit |
df99a1 |
cachednfg = nfg;
|
|
Packit |
df99a1 |
return 1;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
#endif
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// FAILURE
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GP<GPixmap>
|
|
Packit |
df99a1 |
DjVuImage::get_fg_pixmap(const GRect &rect,
|
|
Packit |
df99a1 |
int subsample, double gamma, GPixel white) const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
// Obtain white background pixmap
|
|
Packit |
df99a1 |
GP<GPixmap> pm;
|
|
Packit |
df99a1 |
// Access components
|
|
Packit |
df99a1 |
const int width = get_real_width();
|
|
Packit |
df99a1 |
const int height = get_real_height();
|
|
Packit |
df99a1 |
if (width && height)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
pm = GPixmap::create(rect.height(),rect.width(), &GPixel::WHITE);
|
|
Packit |
df99a1 |
if (!stencil(pm, rect, subsample, gamma, white))
|
|
Packit |
df99a1 |
pm=0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
return pm;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GP<GPixmap>
|
|
Packit |
df99a1 |
DjVuImage::get_fg_pixmap(const GRect &rect,
|
|
Packit |
df99a1 |
int subsample, double gamma) const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
return get_fg_pixmap(rect, subsample, gamma, GPixel::WHITE);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GP<GPixmap>
|
|
Packit |
df99a1 |
DjVuImage::get_pixmap(const GRect &rect, int subsample,
|
|
Packit |
df99a1 |
double gamma, GPixel white) const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
// Get background
|
|
Packit |
df99a1 |
GP<GPixmap> pm = get_bg_pixmap(rect, subsample, gamma, white);
|
|
Packit |
df99a1 |
// Superpose foreground
|
|
Packit |
df99a1 |
if (! stencil(pm, rect, subsample, gamma, white))
|
|
Packit |
df99a1 |
// Avoid ugly progressive display (hack)
|
|
Packit |
df99a1 |
if (get_fgjb()) return 0;
|
|
Packit |
df99a1 |
// Return
|
|
Packit |
df99a1 |
return pm;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GP<GPixmap>
|
|
Packit |
df99a1 |
DjVuImage::get_pixmap(const GRect &rect, int subsample,
|
|
Packit |
df99a1 |
double gamma) const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
return get_pixmap(rect, subsample, gamma, GPixel::WHITE);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
//// DJVUIMAGE: RENDERING (ARBITRARY SCALE)
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
typedef GP<GBitmap>(DjVuImage::*BImager)(const GRect&,int,int) const;
|
|
Packit |
df99a1 |
typedef GP<GPixmap>(DjVuImage::*PImager)(const GRect&,int,double,GPixel) const;
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
static GP<GBitmap>
|
|
Packit |
df99a1 |
do_bitmap(const DjVuImage &dimg, BImager get,
|
|
Packit |
df99a1 |
const GRect &inrect, const GRect &inall, int align )
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GRect rect=inrect;
|
|
Packit |
df99a1 |
GRect all=inall;
|
|
Packit |
df99a1 |
if (! dimg.get_info())
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
if( dimg.get_rotate() )
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GRectMapper mapper;
|
|
Packit |
df99a1 |
mapper.rotate(-dimg.get_rotate());
|
|
Packit |
df99a1 |
mapper.map(rect);
|
|
Packit |
df99a1 |
mapper.map(all);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
// Sanity
|
|
Packit |
df99a1 |
if (! ( all.contains(rect.xmin, rect.ymin) &&
|
|
Packit |
df99a1 |
all.contains(rect.xmax-1, rect.ymax-1) ))
|
|
Packit |
df99a1 |
G_THROW( ERR_MSG("DjVuImage.bad_rect") );
|
|
Packit |
df99a1 |
// Check for integral reduction
|
|
Packit |
df99a1 |
int red;
|
|
Packit |
df99a1 |
int w = dimg.get_real_width();
|
|
Packit |
df99a1 |
int h = dimg.get_real_height();
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
int rw = all.width();
|
|
Packit |
df99a1 |
int rh = all.height();
|
|
Packit |
df99a1 |
GRect zrect = rect;
|
|
Packit |
df99a1 |
zrect.translate(-all.xmin, -all.ymin);
|
|
Packit |
df99a1 |
for (red=1; red<=15; red++)
|
|
Packit |
df99a1 |
if (rw*red>w-red && rw*red<w+red && rh*red>h-red && rh*red
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<GBitmap> bm=(dimg.*get)(zrect, red, align);
|
|
Packit |
df99a1 |
if(bm)
|
|
Packit |
df99a1 |
return bm->rotate(dimg.get_rotate());
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
return NULL;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
// Find best reduction
|
|
Packit |
df99a1 |
for (red=15; red>1; red--)
|
|
Packit |
df99a1 |
if ( (rw*red < w && rh*red < h) ||
|
|
Packit |
df99a1 |
(rw*red*3 < w || rh*red*3 < h) )
|
|
Packit |
df99a1 |
break;
|
|
Packit |
df99a1 |
// Setup bitmap scaler
|
|
Packit |
df99a1 |
if (w<=0 || h<=0) return 0;
|
|
Packit |
df99a1 |
GP<GBitmapScaler> gbs=GBitmapScaler::create();
|
|
Packit |
df99a1 |
GBitmapScaler &bs=*gbs;
|
|
Packit |
df99a1 |
bs.set_input_size( (w+red-1)/red, (h+red-1)/red );
|
|
Packit |
df99a1 |
bs.set_output_size( rw, rh );
|
|
Packit |
df99a1 |
bs.set_horz_ratio( rw*red, w );
|
|
Packit |
df99a1 |
bs.set_vert_ratio( rh*red, h );
|
|
Packit |
df99a1 |
// Scale
|
|
Packit |
df99a1 |
GRect srect;
|
|
Packit |
df99a1 |
bs.get_input_rect(zrect, srect);
|
|
Packit |
df99a1 |
GP<GBitmap> sbm = (dimg.*get)(srect, red, 1);
|
|
Packit |
df99a1 |
if (!sbm) return 0;
|
|
Packit |
df99a1 |
int border = ((zrect.width() + align - 1) & ~(align - 1)) - zrect.width();
|
|
Packit |
df99a1 |
GP<GBitmap> bm = GBitmap::create(zrect.height(), zrect.width(), border);
|
|
Packit |
df99a1 |
bs.scale(srect, *sbm, zrect, *bm);
|
|
Packit |
df99a1 |
if( bm )
|
|
Packit |
df99a1 |
return bm->rotate(dimg.get_rotate());
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
return NULL;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
static GP<GPixmap>
|
|
Packit |
df99a1 |
do_pixmap(const DjVuImage &dimg, PImager get,
|
|
Packit |
df99a1 |
const GRect &inrect, const GRect &inall,
|
|
Packit |
df99a1 |
double gamma, GPixel white )
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GRect rect=inrect;
|
|
Packit |
df99a1 |
GRect all=inall;
|
|
Packit |
df99a1 |
if (! dimg.get_info())
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
if( dimg.get_rotate()%4 )
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GRectMapper mapper;
|
|
Packit |
df99a1 |
mapper.rotate(-dimg.get_rotate());
|
|
Packit |
df99a1 |
mapper.map(rect);
|
|
Packit |
df99a1 |
mapper.map(all);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// Sanity
|
|
Packit |
df99a1 |
if (! ( all.contains(rect.xmin, rect.ymin) &&
|
|
Packit |
df99a1 |
all.contains(rect.xmax-1, rect.ymax-1) ))
|
|
Packit |
df99a1 |
G_THROW( ERR_MSG("DjVuImage.bad_rect2") );
|
|
Packit |
df99a1 |
// Check for integral reduction
|
|
Packit |
df99a1 |
int red, w=0, h=0, rw=0, rh=0;
|
|
Packit |
df99a1 |
w = dimg.get_real_width();
|
|
Packit |
df99a1 |
h = dimg.get_real_height();
|
|
Packit |
df99a1 |
rw = all.width();
|
|
Packit |
df99a1 |
rh = all.height();
|
|
Packit |
df99a1 |
GRect zrect = rect;
|
|
Packit |
df99a1 |
zrect.translate(-all.xmin, -all.ymin);
|
|
Packit |
df99a1 |
for (red=1; red<=15; red++)
|
|
Packit |
df99a1 |
if (rw*red>w-red && rw*red<w+red && rh*red>h-red && rh*red
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<GPixmap> pm = (dimg.*get)(zrect, red, gamma, white);
|
|
Packit |
df99a1 |
if( pm )
|
|
Packit |
df99a1 |
return pm->rotate(dimg.get_rotate());
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
return NULL;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
// These reductions usually go faster (improve!)
|
|
Packit |
df99a1 |
static int fastred[] = { 12,6,4,3,2,1 };
|
|
Packit |
df99a1 |
// Find best reduction
|
|
Packit |
df99a1 |
for (int i=0; (red=fastred[i])>1; i++)
|
|
Packit |
df99a1 |
if ( (rw*red < w && rh*red < h) ||
|
|
Packit |
df99a1 |
(rw*red*3 < w || rh*red*3 < h) )
|
|
Packit |
df99a1 |
break;
|
|
Packit |
df99a1 |
// Setup pixmap scaler
|
|
Packit |
df99a1 |
if (w<=0 || h<=0) return 0;
|
|
Packit |
df99a1 |
GP<GPixmapScaler> gps=GPixmapScaler::create();
|
|
Packit |
df99a1 |
GPixmapScaler &ps=*gps;
|
|
Packit |
df99a1 |
ps.set_input_size( (w+red-1)/red, (h+red-1)/red );
|
|
Packit |
df99a1 |
ps.set_output_size( rw, rh );
|
|
Packit |
df99a1 |
ps.set_horz_ratio( rw*red, w );
|
|
Packit |
df99a1 |
ps.set_vert_ratio( rh*red, h );
|
|
Packit |
df99a1 |
// Scale
|
|
Packit |
df99a1 |
GRect srect;
|
|
Packit |
df99a1 |
ps.get_input_rect(zrect, srect);
|
|
Packit |
df99a1 |
GP<GPixmap> spm = (dimg.*get)(srect, red, gamma, white);
|
|
Packit |
df99a1 |
if (!spm) return 0;
|
|
Packit |
df99a1 |
GP<GPixmap> pm = GPixmap::create();
|
|
Packit |
df99a1 |
ps.scale(srect, *spm, zrect, *pm);
|
|
Packit |
df99a1 |
if(pm)
|
|
Packit |
df99a1 |
return pm->rotate(dimg.get_rotate());
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
return NULL;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GP<GPixmap>
|
|
Packit |
df99a1 |
DjVuImage::get_pixmap(const GRect &r, const GRect &a, double g, GPixel w) const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
return do_pixmap(*this, &DjVuImage::get_pixmap, r, a, g, w);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GP<GPixmap>
|
|
Packit |
df99a1 |
DjVuImage::get_pixmap(const GRect &r, const GRect &a, double g) const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
return do_pixmap(*this, &DjVuImage::get_pixmap, r, a, g, GPixel::WHITE);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GP<GBitmap>
|
|
Packit |
df99a1 |
DjVuImage::get_bitmap(const GRect &rect, const GRect &all, int align) const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
return do_bitmap(*this, &DjVuImage::get_bitmap, rect, all, align);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GP<GPixmap>
|
|
Packit |
df99a1 |
DjVuImage::get_bg_pixmap(const GRect&r, const GRect&a, double g, GPixel w) const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
return do_pixmap(*this, &DjVuImage::get_bg_pixmap, r, a, g, w);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GP<GPixmap>
|
|
Packit |
df99a1 |
DjVuImage::get_bg_pixmap(const GRect&r, const GRect&a, double g) const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
return do_pixmap(*this, &DjVuImage::get_bg_pixmap, r, a, g, GPixel::WHITE);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GP<GPixmap>
|
|
Packit |
df99a1 |
DjVuImage::get_fg_pixmap(const GRect&r, const GRect&a, double g, GPixel w) const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
return do_pixmap(*this, &DjVuImage::get_fg_pixmap, r, a, g, w);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GP<GPixmap>
|
|
Packit |
df99a1 |
DjVuImage::get_fg_pixmap(const GRect&r, const GRect&a, double g) const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
return do_pixmap(*this, &DjVuImage::get_fg_pixmap, r, a, g, GPixel::WHITE);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
int
|
|
Packit |
df99a1 |
DjVuImage::get_rotate() const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
return (rotate_count<0) ? 0 : rotate_count;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
DjVuImage::init_rotate(const DjVuInfo &info)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
rotate_count = info.orientation;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void DjVuImage::set_rotate(int count)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
rotate_count = count % 4;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GP<DjVuAnno>
|
|
Packit |
df99a1 |
DjVuImage::get_decoded_anno()
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<DjVuInfo> djvuinfo = get_info();
|
|
Packit |
df99a1 |
GP<DjVuAnno> djvuanno = DjVuAnno::create();
|
|
Packit |
df99a1 |
GP<ByteStream> bs=get_anno();
|
|
Packit |
df99a1 |
if( bs )
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
int rotate_count=get_rotate();
|
|
Packit |
df99a1 |
/// Brain damaged adjustment of annotation
|
|
Packit |
df99a1 |
/// coordinates that reflect the orientation
|
|
Packit |
df99a1 |
/// flag in the info chunk....
|
|
Packit |
df99a1 |
if (djvuinfo)
|
|
Packit |
df99a1 |
rotate_count = rotate_count - djvuinfo->orientation;
|
|
Packit |
df99a1 |
///decode
|
|
Packit |
df99a1 |
djvuanno->decode(bs);
|
|
Packit |
df99a1 |
///map hyperlinks correctly for rotation
|
|
Packit |
df99a1 |
if( rotate_count & 3 )
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GRect input, output;
|
|
Packit |
df99a1 |
input = GRect(0,0,get_width(),get_height());
|
|
Packit |
df99a1 |
if (rotate_count & 1)
|
|
Packit |
df99a1 |
output = GRect(0,0,get_height(),get_width());
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
output = GRect(0,0,get_width(),get_height());
|
|
Packit |
df99a1 |
GRectMapper mapper;
|
|
Packit |
df99a1 |
mapper.clear();
|
|
Packit |
df99a1 |
mapper.set_input(input);
|
|
Packit |
df99a1 |
mapper.set_output(output);
|
|
Packit |
df99a1 |
mapper.rotate(-rotate_count);
|
|
Packit |
df99a1 |
GPList<GMapArea> &list=djvuanno->ant->map_areas;
|
|
Packit |
df99a1 |
for(GPosition pos=list;pos;++pos)
|
|
Packit |
df99a1 |
list[pos]->unmap(mapper);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
return djvuanno;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
return NULL;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
DjVuImage::map(GRect &rect) const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GRect input, output;
|
|
Packit |
df99a1 |
const int rotate_count=get_rotate();
|
|
Packit |
df99a1 |
if(rotate_count>0)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
input = GRect(0,0,get_width(), get_height());
|
|
Packit |
df99a1 |
output = GRect(0,0, get_real_width(), get_real_height());
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GRectMapper mapper;
|
|
Packit |
df99a1 |
mapper.clear();
|
|
Packit |
df99a1 |
mapper.set_input(input);
|
|
Packit |
df99a1 |
mapper.set_output(output);
|
|
Packit |
df99a1 |
mapper.rotate(-rotate_count);
|
|
Packit |
df99a1 |
mapper.map(rect);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
DjVuImage::unmap(GRect &rect) const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GRect input, output;
|
|
Packit |
df99a1 |
const int rotate_count=get_rotate();
|
|
Packit |
df99a1 |
if(rotate_count>0)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
input = GRect(0,0,get_width(), get_height());
|
|
Packit |
df99a1 |
output = GRect(0,0, get_real_width(), get_real_height());
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GRectMapper mapper;
|
|
Packit |
df99a1 |
mapper.clear();
|
|
Packit |
df99a1 |
mapper.set_input(input);
|
|
Packit |
df99a1 |
mapper.set_output(output);
|
|
Packit |
df99a1 |
mapper.rotate(-rotate_count);
|
|
Packit |
df99a1 |
mapper.unmap(rect);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
DjVuImage::map(int &x, int &y) const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GRect input, output;
|
|
Packit |
df99a1 |
const int rotate_count=get_rotate();
|
|
Packit |
df99a1 |
if(rotate_count>0)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
input = GRect(0,0,get_width(), get_height());
|
|
Packit |
df99a1 |
output = GRect(0,0, get_real_width(), get_real_height());
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GRectMapper mapper;
|
|
Packit |
df99a1 |
mapper.clear();
|
|
Packit |
df99a1 |
mapper.set_input(input);
|
|
Packit |
df99a1 |
mapper.set_output(output);
|
|
Packit |
df99a1 |
mapper.rotate(-rotate_count);
|
|
Packit |
df99a1 |
mapper.map(x, y);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
DjVuImage::unmap(int &x, int &y) const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GRect input, output;
|
|
Packit |
df99a1 |
const int rotate_count=get_rotate();
|
|
Packit |
df99a1 |
if(rotate_count>0)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
input = GRect(0,0,get_width(), get_height());
|
|
Packit |
df99a1 |
output = GRect(0,0, get_real_width(), get_real_height());
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GRectMapper mapper;
|
|
Packit |
df99a1 |
mapper.clear();
|
|
Packit |
df99a1 |
mapper.set_input(input);
|
|
Packit |
df99a1 |
mapper.set_output(output);
|
|
Packit |
df99a1 |
mapper.rotate(-rotate_count);
|
|
Packit |
df99a1 |
mapper.unmap(x, y);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
bool
|
|
Packit |
df99a1 |
DjVuImage::wait_for_complete_decode(void)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (file)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
file->resume_decode(true);
|
|
Packit |
df99a1 |
return file->is_decode_ok();
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// Write out a DjVuXML object tag and map tag.
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
DjVuImage::writeXML(ByteStream &str_out,const GURL &doc_url,const int flags) const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
const int height=get_height();
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
static const char *Object="
|
|
Packit |
df99a1 |
const GURL url(get_djvu_file()->get_url());
|
|
Packit |
df99a1 |
const GUTF8String pagename(url.fname());
|
|
Packit |
df99a1 |
GUTF8String page_param;
|
|
Packit |
df99a1 |
if(doc_url.is_valid() && !doc_url.is_empty() && (doc_url != url))
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
str_out.writestring(Object+doc_url.get_string());
|
|
Packit |
df99a1 |
page_param="<PARAM name=\"PAGE\" value=\""+pagename+"\" />\n";
|
|
Packit |
df99a1 |
}else
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
str_out.writestring(Object+doc_url.get_string());
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
str_out.writestring("\" type=\""+get_mimetype()+"\" height=\""
|
|
Packit |
df99a1 |
+GUTF8String(height)+"\" width=\""+GUTF8String(get_width())
|
|
Packit |
df99a1 |
+"\" usemap=\""+pagename.toEscaped()+"\" >\n");
|
|
Packit |
df99a1 |
if(!(flags & NOINFO))
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
const GP<DjVuInfo> info(get_info());
|
|
Packit |
df99a1 |
if(info)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
info->writeParam(str_out);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
str_out.writestring(page_param);
|
|
Packit |
df99a1 |
const GP<DjVuAnno> anno(DjVuAnno::create());
|
|
Packit |
df99a1 |
if(!(flags & NOMAP))
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
const GP<ByteStream> anno_str(get_anno());
|
|
Packit |
df99a1 |
if(anno_str)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
anno->decode(anno_str);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
if(!(flags & NOINFO))
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
anno->writeParam(str_out);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
if(!(flags & NOTEXT))
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
const GP<DjVuText> text(DjVuText::create());
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
const GP<ByteStream> text_str(get_text());
|
|
Packit |
df99a1 |
if(text_str)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
text->decode(text_str);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
text->writeText(str_out,height);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
if(!(flags & NOMETA))
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
const GP<ByteStream> meta_str(get_meta());
|
|
Packit |
df99a1 |
if(meta_str)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<IFFByteStream> giff=IFFByteStream::create(meta_str);
|
|
Packit |
df99a1 |
IFFByteStream &iff=*giff;
|
|
Packit |
df99a1 |
GUTF8String chkid;
|
|
Packit |
df99a1 |
while( iff.get_chunk(chkid))
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<ByteStream> gbs(iff.get_bytestream());
|
|
Packit |
df99a1 |
if(chkid == "METa")
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
str_out.copy(*gbs);
|
|
Packit |
df99a1 |
//str_out.writestring(gbs->getAsUTF8());
|
|
Packit |
df99a1 |
}else if(chkid == "METz")
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
gbs=BSByteStream::create(gbs);
|
|
Packit |
df99a1 |
str_out.copy(*gbs);
|
|
Packit |
df99a1 |
//str_out.writestring(gbs->getAsUTF8());
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
iff.close_chunk();
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
str_out.writestring(GUTF8String("</OBJECT>\n"));
|
|
Packit |
df99a1 |
if(!(flags & NOMAP))
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
anno->writeMap(str_out,pagename,height);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// Write out a DjVuXML object tag and map tag.
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
DjVuImage::writeXML(ByteStream &str_out) const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
writeXML(str_out,GURL());
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// Write out a DjVuXML object tag and map tag.
|
|
Packit |
df99a1 |
GUTF8String
|
|
Packit |
df99a1 |
DjVuImage::get_XML(const GURL &doc_url,const int flags) const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<ByteStream> gbs(ByteStream::create());
|
|
Packit |
df99a1 |
ByteStream &bs=*gbs;
|
|
Packit |
df99a1 |
writeXML(bs,doc_url);
|
|
Packit |
df99a1 |
bs.seek(0L);
|
|
Packit |
df99a1 |
return bs.getAsUTF8();
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// Write out a DjVuXML object tag and map tag.
|
|
Packit |
df99a1 |
GUTF8String
|
|
Packit |
df99a1 |
DjVuImage::get_XML(void) const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
return get_XML(GURL());
|
|
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
|