|
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 "ddjvuapi.h"
|
|
Packit |
df99a1 |
#endif
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
#include <stddef.h>
|
|
Packit |
df99a1 |
#include <stdlib.h>
|
|
Packit |
df99a1 |
#include <stdio.h>
|
|
Packit |
df99a1 |
#include <string.h>
|
|
Packit |
df99a1 |
#include <ctype.h>
|
|
Packit |
df99a1 |
#include <locale.h>
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
#ifdef HAVE_NAMESPACES
|
|
Packit |
df99a1 |
namespace DJVU {
|
|
Packit |
df99a1 |
struct ddjvu_context_s;
|
|
Packit |
df99a1 |
struct ddjvu_job_s;
|
|
Packit |
df99a1 |
struct ddjvu_document_s;
|
|
Packit |
df99a1 |
struct ddjvu_page_s;
|
|
Packit |
df99a1 |
struct ddjvu_format_s;
|
|
Packit |
df99a1 |
struct ddjvu_message_p;
|
|
Packit |
df99a1 |
struct ddjvu_thumbnail_p;
|
|
Packit |
df99a1 |
struct ddjvu_runnablejob_s;
|
|
Packit |
df99a1 |
struct ddjvu_printjob_s;
|
|
Packit |
df99a1 |
struct ddjvu_savejob_s;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
using namespace DJVU;
|
|
Packit |
df99a1 |
# define DJVUNS DJVU::
|
|
Packit |
df99a1 |
#else
|
|
Packit |
df99a1 |
# define DJVUNS /**/
|
|
Packit |
df99a1 |
#endif
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
#include "GException.h"
|
|
Packit |
df99a1 |
#include "GSmartPointer.h"
|
|
Packit |
df99a1 |
#include "GThreads.h"
|
|
Packit |
df99a1 |
#include "GContainer.h"
|
|
Packit |
df99a1 |
#include "ByteStream.h"
|
|
Packit |
df99a1 |
#include "IFFByteStream.h"
|
|
Packit |
df99a1 |
#include "BSByteStream.h"
|
|
Packit |
df99a1 |
#include "GString.h"
|
|
Packit |
df99a1 |
#include "GBitmap.h"
|
|
Packit |
df99a1 |
#include "GPixmap.h"
|
|
Packit |
df99a1 |
#include "GScaler.h"
|
|
Packit |
df99a1 |
#include "DjVuPort.h"
|
|
Packit |
df99a1 |
#include "DataPool.h"
|
|
Packit |
df99a1 |
#include "DjVuInfo.h"
|
|
Packit |
df99a1 |
#include "IW44Image.h"
|
|
Packit |
df99a1 |
#include "DjVuImage.h"
|
|
Packit |
df99a1 |
#include "DjVuFileCache.h"
|
|
Packit |
df99a1 |
#include "DjVuDocument.h"
|
|
Packit |
df99a1 |
#include "DjVuDumpHelper.h"
|
|
Packit |
df99a1 |
#include "DjVuMessageLite.h"
|
|
Packit |
df99a1 |
#include "DjVuMessage.h"
|
|
Packit |
df99a1 |
#include "DjVmNav.h"
|
|
Packit |
df99a1 |
#include "DjVuText.h"
|
|
Packit |
df99a1 |
#include "DjVuAnno.h"
|
|
Packit |
df99a1 |
#include "DjVuToPS.h"
|
|
Packit |
df99a1 |
#include "DjVmDir.h"
|
|
Packit |
df99a1 |
#include "DjVmDir0.h"
|
|
Packit |
df99a1 |
#include "DjVuNavDir.h"
|
|
Packit |
df99a1 |
#include "DjVmDoc.h"
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
#include "miniexp.h"
|
|
Packit |
df99a1 |
#include "ddjvuapi.h"
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// ----------------------------------------
|
|
Packit |
df99a1 |
// Private structures
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
struct DJVUNS ddjvu_message_p : public GPEnabled
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GNativeString tmp1;
|
|
Packit |
df99a1 |
GNativeString tmp2;
|
|
Packit |
df99a1 |
ddjvu_message_t p;
|
|
Packit |
df99a1 |
ddjvu_message_p() { memset(&p, 0, sizeof(p)); }
|
|
Packit |
df99a1 |
};
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
struct DJVUNS ddjvu_thumbnail_p : public GPEnabled
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ddjvu_document_t *document;
|
|
Packit |
df99a1 |
int pagenum;
|
|
Packit |
df99a1 |
GTArray<char> data;
|
|
Packit |
df99a1 |
GP<DataPool> pool;
|
|
Packit |
df99a1 |
static void callback(void *);
|
|
Packit |
df99a1 |
};
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// ----------------------------------------
|
|
Packit |
df99a1 |
// Context, Jobs, Document, Pages
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
struct DJVUNS ddjvu_context_s : public GPEnabled
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GMonitor monitor;
|
|
Packit |
df99a1 |
GP<DjVuFileCache> cache;
|
|
Packit |
df99a1 |
GPList<ddjvu_message_p> mlist;
|
|
Packit |
df99a1 |
GP<ddjvu_message_p> mpeeked;
|
|
Packit |
df99a1 |
int uniqueid;
|
|
Packit |
df99a1 |
ddjvu_message_callback_t callbackfun;
|
|
Packit |
df99a1 |
void *callbackarg;
|
|
Packit |
df99a1 |
};
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
struct DJVUNS ddjvu_job_s : public DjVuPort
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GMonitor monitor;
|
|
Packit |
df99a1 |
void *userdata;
|
|
Packit |
df99a1 |
GP<ddjvu_context_s> myctx;
|
|
Packit |
df99a1 |
GP<ddjvu_document_s> mydoc;
|
|
Packit |
df99a1 |
bool released;
|
|
Packit |
df99a1 |
ddjvu_job_s();
|
|
Packit |
df99a1 |
// virtual port functions:
|
|
Packit |
df99a1 |
virtual bool inherits(const GUTF8String&) const;
|
|
Packit |
df99a1 |
virtual bool notify_error(const DjVuPort*, const GUTF8String&);
|
|
Packit |
df99a1 |
virtual bool notify_status(const DjVuPort*, const GUTF8String&);
|
|
Packit |
df99a1 |
// default implementation of virtual job functions:
|
|
Packit |
df99a1 |
virtual ddjvu_status_t status() {return DDJVU_JOB_NOTSTARTED;}
|
|
Packit |
df99a1 |
virtual void release() {}
|
|
Packit |
df99a1 |
virtual void stop() {}
|
|
Packit |
df99a1 |
};
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
struct DJVUNS ddjvu_document_s : public ddjvu_job_s
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<DjVuDocument> doc;
|
|
Packit |
df99a1 |
GPMap<int,DataPool> streams;
|
|
Packit |
df99a1 |
GMap<GUTF8String, int> names;
|
|
Packit |
df99a1 |
GPMap<int,ddjvu_thumbnail_p> thumbnails;
|
|
Packit |
df99a1 |
int streamid;
|
|
Packit |
df99a1 |
bool fileflag;
|
|
Packit |
df99a1 |
bool urlflag;
|
|
Packit |
df99a1 |
bool docinfoflag;
|
|
Packit |
df99a1 |
bool pageinfoflag;
|
|
Packit |
df99a1 |
minivar_t protect;
|
|
Packit |
df99a1 |
// virtual job functions:
|
|
Packit |
df99a1 |
virtual ddjvu_status_t status();
|
|
Packit |
df99a1 |
virtual void release();
|
|
Packit |
df99a1 |
// virtual port functions:
|
|
Packit |
df99a1 |
virtual bool inherits(const GUTF8String&) const;
|
|
Packit |
df99a1 |
virtual bool notify_error(const DjVuPort*, const GUTF8String&);
|
|
Packit |
df99a1 |
virtual bool notify_status(const DjVuPort*, const GUTF8String&);
|
|
Packit |
df99a1 |
virtual void notify_doc_flags_changed(const DjVuDocument*, long, long);
|
|
Packit |
df99a1 |
virtual GP<DataPool> request_data(const DjVuPort*, const GURL&);
|
|
Packit |
df99a1 |
static void callback(void *);
|
|
Packit |
df99a1 |
bool want_pageinfo(void);
|
|
Packit |
df99a1 |
};
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
struct DJVUNS ddjvu_page_s : public ddjvu_job_s
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<DjVuImage> img;
|
|
Packit |
df99a1 |
ddjvu_job_t *job;
|
|
Packit |
df99a1 |
bool pageinfoflag; // was the first m_pageinfo sent?
|
|
Packit |
df99a1 |
bool pagedoneflag; // was the final m_pageinfo sent?
|
|
Packit |
df99a1 |
// virtual job functions:
|
|
Packit |
df99a1 |
virtual ddjvu_status_t status();
|
|
Packit |
df99a1 |
virtual void release();
|
|
Packit |
df99a1 |
// virtual port functions:
|
|
Packit |
df99a1 |
virtual bool inherits(const GUTF8String&) const;
|
|
Packit |
df99a1 |
virtual bool notify_error(const DjVuPort*, const GUTF8String&);
|
|
Packit |
df99a1 |
virtual bool notify_status(const DjVuPort*, const GUTF8String&);
|
|
Packit |
df99a1 |
virtual void notify_file_flags_changed(const DjVuFile*, long, long);
|
|
Packit |
df99a1 |
virtual void notify_relayout(const class DjVuImage*);
|
|
Packit |
df99a1 |
virtual void notify_redisplay(const class DjVuImage*);
|
|
Packit |
df99a1 |
virtual void notify_chunk_done(const DjVuPort*, const GUTF8String &);
|
|
Packit |
df99a1 |
void sendmessages();
|
|
Packit |
df99a1 |
};
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// ----------------------------------------
|
|
Packit |
df99a1 |
// Helpers
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// Hack to increment counter
|
|
Packit |
df99a1 |
static void
|
|
Packit |
df99a1 |
ref(GPEnabled *p)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GPBase n(p);
|
|
Packit |
df99a1 |
char *gn = (char*)&n;
|
|
Packit |
df99a1 |
*(GPEnabled**)gn = 0;
|
|
Packit |
df99a1 |
n.assign(0);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// Hack to decrement counter
|
|
Packit |
df99a1 |
static void
|
|
Packit |
df99a1 |
unref(GPEnabled *p)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GPBase n;
|
|
Packit |
df99a1 |
char *gn = (char*)&n;
|
|
Packit |
df99a1 |
*(GPEnabled**)gn = p;
|
|
Packit |
df99a1 |
n.assign(0);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// Allocate strings
|
|
Packit |
df99a1 |
static char *
|
|
Packit |
df99a1 |
xstr(const char *s)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
int l = strlen(s);
|
|
Packit |
df99a1 |
char *p = (char*)malloc(l + 1);
|
|
Packit |
df99a1 |
if (p)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
strcpy(p, s);
|
|
Packit |
df99a1 |
p[l] = 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
return p;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// Allocate strings
|
|
Packit |
df99a1 |
static char *
|
|
Packit |
df99a1 |
xstr(const GNativeString &n)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
return xstr( (const char*) n );
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// Allocate strings
|
|
Packit |
df99a1 |
static char *
|
|
Packit |
df99a1 |
xstr(const GUTF8String &u)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GNativeString n(u);
|
|
Packit |
df99a1 |
return xstr( n );
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// Fill a message head
|
|
Packit |
df99a1 |
static ddjvu_message_any_t
|
|
Packit |
df99a1 |
xhead(ddjvu_message_tag_t tag,
|
|
Packit |
df99a1 |
ddjvu_context_t *context)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ddjvu_message_any_t any;
|
|
Packit |
df99a1 |
any.tag = tag;
|
|
Packit |
df99a1 |
any.context = context;
|
|
Packit |
df99a1 |
any.document = 0;
|
|
Packit |
df99a1 |
any.page = 0;
|
|
Packit |
df99a1 |
any.job = 0;
|
|
Packit |
df99a1 |
return any;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
static ddjvu_message_any_t
|
|
Packit |
df99a1 |
xhead(ddjvu_message_tag_t tag,
|
|
Packit |
df99a1 |
ddjvu_job_t *job)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ddjvu_message_any_t any;
|
|
Packit |
df99a1 |
any.tag = tag;
|
|
Packit |
df99a1 |
any.context = job->myctx;
|
|
Packit |
df99a1 |
any.document = job->mydoc;
|
|
Packit |
df99a1 |
any.page = 0;
|
|
Packit |
df99a1 |
any.job = job;
|
|
Packit |
df99a1 |
return any;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
static ddjvu_message_any_t
|
|
Packit |
df99a1 |
xhead(ddjvu_message_tag_t tag,
|
|
Packit |
df99a1 |
ddjvu_document_t *document)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ddjvu_message_any_t any;
|
|
Packit |
df99a1 |
any.tag = tag;
|
|
Packit |
df99a1 |
any.context = document->myctx;
|
|
Packit |
df99a1 |
any.document = document;
|
|
Packit |
df99a1 |
any.page = 0;
|
|
Packit |
df99a1 |
any.job = document;
|
|
Packit |
df99a1 |
return any;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
static ddjvu_message_any_t
|
|
Packit |
df99a1 |
xhead(ddjvu_message_tag_t tag,
|
|
Packit |
df99a1 |
ddjvu_page_t *page)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ddjvu_message_any_t any;
|
|
Packit |
df99a1 |
any.tag = tag;
|
|
Packit |
df99a1 |
any.context = page->myctx;
|
|
Packit |
df99a1 |
any.document = page->mydoc;
|
|
Packit |
df99a1 |
any.page = page;
|
|
Packit |
df99a1 |
any.job = page->job;
|
|
Packit |
df99a1 |
return any;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// ----------------------------------------
|
|
Packit |
df99a1 |
// Version
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
const char*
|
|
Packit |
df99a1 |
ddjvu_get_version_string(void)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
#ifdef DJVULIBRE_VERSION
|
|
Packit |
df99a1 |
return "DjVuLibre-" DJVULIBRE_VERSION;
|
|
Packit |
df99a1 |
#else
|
|
Packit |
df99a1 |
return "DjVuLibre";
|
|
Packit |
df99a1 |
#endif
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
int
|
|
Packit |
df99a1 |
ddjvu_code_get_version(void)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
return DJVUVERSION;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// ----------------------------------------
|
|
Packit |
df99a1 |
// Context
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
ddjvu_context_t *
|
|
Packit |
df99a1 |
ddjvu_context_create(const char *programname)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ddjvu_context_t *ctx = 0;
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
#ifdef LC_ALL
|
|
Packit |
df99a1 |
setlocale(LC_ALL,"");
|
|
Packit |
df99a1 |
# ifdef LC_NUMERIC
|
|
Packit |
df99a1 |
setlocale(LC_NUMERIC, "C");
|
|
Packit |
df99a1 |
# endif
|
|
Packit |
df99a1 |
#endif
|
|
Packit |
df99a1 |
if (programname)
|
|
Packit |
df99a1 |
djvu_programname(programname);
|
|
Packit |
df99a1 |
DjVuMessage::use_language();
|
|
Packit |
df99a1 |
DjVuMessageLite::create();
|
|
Packit |
df99a1 |
ctx = new ddjvu_context_s;
|
|
Packit |
df99a1 |
ref(ctx);
|
|
Packit |
df99a1 |
ctx->uniqueid = 0;
|
|
Packit |
df99a1 |
ctx->callbackfun = 0;
|
|
Packit |
df99a1 |
ctx->callbackarg = 0;
|
|
Packit |
df99a1 |
ctx->cache = DjVuFileCache::create();
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH_ALL
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (ctx)
|
|
Packit |
df99a1 |
unref(ctx);
|
|
Packit |
df99a1 |
ctx = 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
return ctx;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
ddjvu_context_release(ddjvu_context_t *ctx)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (ctx)
|
|
Packit |
df99a1 |
unref(ctx);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH_ALL
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// ----------------------------------------
|
|
Packit |
df99a1 |
// Message helpers
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// post a new message
|
|
Packit |
df99a1 |
static void
|
|
Packit |
df99a1 |
msg_push(const ddjvu_message_any_t &head,
|
|
Packit |
df99a1 |
GP<ddjvu_message_p> msg = 0)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ddjvu_context_t *ctx = head.context;
|
|
Packit |
df99a1 |
if (! msg)
|
|
Packit |
df99a1 |
msg = new ddjvu_message_p;
|
|
Packit |
df99a1 |
msg->p.m_any = head;
|
|
Packit |
df99a1 |
GMonitorLock lock(&ctx->monitor);
|
|
Packit |
df99a1 |
if ((head.document && head.document->released) ||
|
|
Packit |
df99a1 |
(head.page && head.page->released) ||
|
|
Packit |
df99a1 |
(head.job && head.job->released) )
|
|
Packit |
df99a1 |
return;
|
|
Packit |
df99a1 |
if (ctx->callbackfun)
|
|
Packit |
df99a1 |
(*ctx->callbackfun)(ctx, ctx->callbackarg);
|
|
Packit |
df99a1 |
ctx->mlist.append(msg);
|
|
Packit |
df99a1 |
ctx->monitor.broadcast();
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
static void
|
|
Packit |
df99a1 |
msg_push_nothrow(const ddjvu_message_any_t &head,
|
|
Packit |
df99a1 |
GP<ddjvu_message_p> msg = 0)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
msg_push(head, msg);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH_ALL
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// prepare error message from string
|
|
Packit |
df99a1 |
static GP<ddjvu_message_p>
|
|
Packit |
df99a1 |
msg_prep_error(GUTF8String message,
|
|
Packit |
df99a1 |
const char *function=0,
|
|
Packit |
df99a1 |
const char *filename=0,
|
|
Packit |
df99a1 |
int lineno=0)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<ddjvu_message_p> p = new ddjvu_message_p;
|
|
Packit |
df99a1 |
p->p.m_error.message = 0;
|
|
Packit |
df99a1 |
p->p.m_error.function = function;
|
|
Packit |
df99a1 |
p->p.m_error.filename = filename;
|
|
Packit |
df99a1 |
p->p.m_error.lineno = lineno;
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
p->tmp1 = DjVuMessageLite::LookUpUTF8(message);
|
|
Packit |
df99a1 |
p->p.m_error.message = (const char*)(p->tmp1);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH_ALL
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
return p;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// prepare error message from exception
|
|
Packit |
df99a1 |
static GP<ddjvu_message_p>
|
|
Packit |
df99a1 |
msg_prep_error(const GException &ex,
|
|
Packit |
df99a1 |
const char *function=0,
|
|
Packit |
df99a1 |
const char *filename=0,
|
|
Packit |
df99a1 |
int lineno=0)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<ddjvu_message_p> p = new ddjvu_message_p;
|
|
Packit |
df99a1 |
p->p.m_error.message = 0;
|
|
Packit |
df99a1 |
p->p.m_error.function = function;
|
|
Packit |
df99a1 |
p->p.m_error.filename = filename;
|
|
Packit |
df99a1 |
p->p.m_error.lineno = lineno;
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
p->tmp1 = DjVuMessageLite::LookUpUTF8(ex.get_cause());
|
|
Packit |
df99a1 |
p->p.m_error.message = (const char*)(p->tmp1);
|
|
Packit |
df99a1 |
p->p.m_error.function = ex.get_function();
|
|
Packit |
df99a1 |
p->p.m_error.filename = ex.get_file();
|
|
Packit |
df99a1 |
p->p.m_error.lineno = ex.get_line();
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH_ALL
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
return p;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// prepare status message
|
|
Packit |
df99a1 |
static GP<ddjvu_message_p>
|
|
Packit |
df99a1 |
msg_prep_info(GUTF8String message)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<ddjvu_message_p> p = new ddjvu_message_p;
|
|
Packit |
df99a1 |
p->tmp1 = DjVuMessageLite::LookUpUTF8(message); // i18n nonsense!
|
|
Packit |
df99a1 |
p->p.m_info.message = (const char*)(p->tmp1);
|
|
Packit |
df99a1 |
return p;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// ----------------------------------------
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
#ifdef __GNUG__
|
|
Packit |
df99a1 |
# define ERROR1(x, m) \
|
|
Packit |
df99a1 |
msg_push_nothrow(xhead(DDJVU_ERROR,x),\
|
|
Packit |
df99a1 |
msg_prep_error(m,__func__,__FILE__,__LINE__))
|
|
Packit |
df99a1 |
#else
|
|
Packit |
df99a1 |
# define ERROR1(x, m) \
|
|
Packit |
df99a1 |
msg_push_nothrow(xhead(DDJVU_ERROR,x),\
|
|
Packit |
df99a1 |
msg_prep_error(m,0,__FILE__,__LINE__))
|
|
Packit |
df99a1 |
#endif
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// ----------------------------------------
|
|
Packit |
df99a1 |
// Cache
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
ddjvu_cache_set_size(ddjvu_context_t *ctx,
|
|
Packit |
df99a1 |
unsigned long cachesize)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GMonitorLock lock(&ctx->monitor);
|
|
Packit |
df99a1 |
if (ctx->cache && cachesize>0)
|
|
Packit |
df99a1 |
ctx->cache->set_max_size(cachesize);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH(ex)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ERROR1(ctx, ex);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
DDJVUAPI unsigned long
|
|
Packit |
df99a1 |
ddjvu_cache_get_size(ddjvu_context_t *ctx)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GMonitorLock lock(&ctx->monitor);
|
|
Packit |
df99a1 |
if (ctx->cache)
|
|
Packit |
df99a1 |
return ctx->cache->get_max_size();
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH(ex)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ERROR1(ctx, ex);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
ddjvu_cache_clear(ddjvu_context_t *ctx)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GMonitorLock lock(&ctx->monitor);
|
|
Packit |
df99a1 |
DataPool::close_all();
|
|
Packit |
df99a1 |
if (ctx->cache)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ctx->cache->clear();
|
|
Packit |
df99a1 |
return;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH(ex)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ERROR1(ctx, ex);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// ----------------------------------------
|
|
Packit |
df99a1 |
// Jobs
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
ddjvu_job_s::ddjvu_job_s()
|
|
Packit |
df99a1 |
: userdata(0), released(false)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
bool
|
|
Packit |
df99a1 |
ddjvu_job_s::inherits(const GUTF8String &classname) const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
return (classname == "ddjvu_job_s")
|
|
Packit |
df99a1 |
|| DjVuPort::inherits(classname);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
bool
|
|
Packit |
df99a1 |
ddjvu_job_s::notify_error(const DjVuPort *, const GUTF8String &m)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
msg_push(xhead(DDJVU_ERROR, this), msg_prep_error(m));
|
|
Packit |
df99a1 |
return true;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
bool
|
|
Packit |
df99a1 |
ddjvu_job_s::notify_status(const DjVuPort *p, const GUTF8String &m)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
msg_push(xhead(DDJVU_INFO, this), msg_prep_info(m));
|
|
Packit |
df99a1 |
return true;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
ddjvu_job_release(ddjvu_job_t *job)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (!job)
|
|
Packit |
df99a1 |
return;
|
|
Packit |
df99a1 |
job->release();
|
|
Packit |
df99a1 |
job->userdata = 0;
|
|
Packit |
df99a1 |
job->released = true;
|
|
Packit |
df99a1 |
// clean all messages
|
|
Packit |
df99a1 |
ddjvu_context_t *ctx = job->myctx;
|
|
Packit |
df99a1 |
if (ctx)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GMonitorLock lock(&ctx->monitor);
|
|
Packit |
df99a1 |
GPosition p = ctx->mlist;
|
|
Packit |
df99a1 |
while (p)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GPosition s = p; ++p;
|
|
Packit |
df99a1 |
if (ctx->mlist[s]->p.m_any.job == job ||
|
|
Packit |
df99a1 |
ctx->mlist[s]->p.m_any.document == job ||
|
|
Packit |
df99a1 |
ctx->mlist[s]->p.m_any.page == job )
|
|
Packit |
df99a1 |
ctx->mlist.del(s);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
// cleanup pointers in current message as well.
|
|
Packit |
df99a1 |
if (ctx->mpeeked)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ddjvu_message_t *m = &ctx->mpeeked->p;
|
|
Packit |
df99a1 |
if (m->m_any.job == job)
|
|
Packit |
df99a1 |
m->m_any.job = 0;
|
|
Packit |
df99a1 |
if (m->m_any.document == job)
|
|
Packit |
df99a1 |
m->m_any.document = 0;
|
|
Packit |
df99a1 |
if (m->m_any.page == job)
|
|
Packit |
df99a1 |
m->m_any.page = 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
// decrement reference counter
|
|
Packit |
df99a1 |
unref(job);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH_ALL
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
ddjvu_status_t
|
|
Packit |
df99a1 |
ddjvu_job_status(ddjvu_job_t *job)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (! job)
|
|
Packit |
df99a1 |
return DDJVU_JOB_NOTSTARTED;
|
|
Packit |
df99a1 |
return job->status();
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH(ex)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ERROR1(job, ex);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
return DDJVU_JOB_FAILED;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
ddjvu_job_stop(ddjvu_job_t *job)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (job)
|
|
Packit |
df99a1 |
job->stop();
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH(ex)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ERROR1(job, ex);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
ddjvu_job_set_user_data(ddjvu_job_t *job, void *userdata)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (job)
|
|
Packit |
df99a1 |
job->userdata = userdata;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void *
|
|
Packit |
df99a1 |
ddjvu_job_get_user_data(ddjvu_job_t *job)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (job)
|
|
Packit |
df99a1 |
return job->userdata;
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// ----------------------------------------
|
|
Packit |
df99a1 |
// Message queue
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
ddjvu_message_t *
|
|
Packit |
df99a1 |
ddjvu_message_peek(ddjvu_context_t *ctx)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GMonitorLock lock(&ctx->monitor);
|
|
Packit |
df99a1 |
if (ctx->mpeeked)
|
|
Packit |
df99a1 |
return &ctx->mpeeked->p;
|
|
Packit |
df99a1 |
if (! ctx->mlist.size())
|
|
Packit |
df99a1 |
ctx->monitor.wait(0);
|
|
Packit |
df99a1 |
GPosition p = ctx->mlist;
|
|
Packit |
df99a1 |
if (! p)
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
ctx->mpeeked = ctx->mlist[p];
|
|
Packit |
df99a1 |
ctx->mlist.del(p);
|
|
Packit |
df99a1 |
return &ctx->mpeeked->p;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH_ALL
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
ddjvu_message_t *
|
|
Packit |
df99a1 |
ddjvu_message_wait(ddjvu_context_t *ctx)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GMonitorLock lock(&ctx->monitor);
|
|
Packit |
df99a1 |
if (ctx->mpeeked)
|
|
Packit |
df99a1 |
return &ctx->mpeeked->p;
|
|
Packit |
df99a1 |
while (! ctx->mlist.size())
|
|
Packit |
df99a1 |
ctx->monitor.wait();
|
|
Packit |
df99a1 |
GPosition p = ctx->mlist;
|
|
Packit |
df99a1 |
if (! p)
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
ctx->mpeeked = ctx->mlist[p];
|
|
Packit |
df99a1 |
ctx->mlist.del(p);
|
|
Packit |
df99a1 |
return &ctx->mpeeked->p;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH_ALL
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
ddjvu_message_pop(ddjvu_context_t *ctx)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GMonitorLock lock(&ctx->monitor);
|
|
Packit |
df99a1 |
ctx->mpeeked = 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH_ALL
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
ddjvu_message_set_callback(ddjvu_context_t *ctx,
|
|
Packit |
df99a1 |
ddjvu_message_callback_t callback,
|
|
Packit |
df99a1 |
void *closure)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GMonitorLock lock(&ctx->monitor);
|
|
Packit |
df99a1 |
ctx->callbackfun = callback;
|
|
Packit |
df99a1 |
ctx->callbackarg = closure;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// ----------------------------------------
|
|
Packit |
df99a1 |
// Document callbacks
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
ddjvu_document_s::release()
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GPosition p;
|
|
Packit |
df99a1 |
GMonitorLock lock(&monitor);
|
|
Packit |
df99a1 |
doc = 0;
|
|
Packit |
df99a1 |
for (p=thumbnails; p; ++p)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ddjvu_thumbnail_p *thumb = thumbnails[p];
|
|
Packit |
df99a1 |
if (thumb->pool)
|
|
Packit |
df99a1 |
thumb->pool->del_trigger(ddjvu_thumbnail_p::callback, (void*)thumb);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
for (p = streams; p; ++p)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<DataPool> pool = streams[p];
|
|
Packit |
df99a1 |
if (pool)
|
|
Packit |
df99a1 |
pool->del_trigger(callback, (void*)this);
|
|
Packit |
df99a1 |
if (pool && !pool->is_eof())
|
|
Packit |
df99a1 |
pool->stop();
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
ddjvu_status_t
|
|
Packit |
df99a1 |
ddjvu_document_s::status()
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (!doc)
|
|
Packit |
df99a1 |
return DDJVU_JOB_NOTSTARTED;
|
|
Packit |
df99a1 |
long flags = doc->get_doc_flags();
|
|
Packit |
df99a1 |
if (flags & DjVuDocument::DOC_INIT_OK)
|
|
Packit |
df99a1 |
return DDJVU_JOB_OK;
|
|
Packit |
df99a1 |
else if (flags & DjVuDocument::DOC_INIT_FAILED)
|
|
Packit |
df99a1 |
return DDJVU_JOB_FAILED;
|
|
Packit |
df99a1 |
return DDJVU_JOB_STARTED;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
bool
|
|
Packit |
df99a1 |
ddjvu_document_s::inherits(const GUTF8String &classname) const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
return (classname == "ddjvu_document_s")
|
|
Packit |
df99a1 |
|| ddjvu_job_s::inherits(classname);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
bool
|
|
Packit |
df99a1 |
ddjvu_document_s::notify_error(const DjVuPort *, const GUTF8String &m)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (!doc) return false;
|
|
Packit |
df99a1 |
msg_push(xhead(DDJVU_ERROR, this), msg_prep_error(m));
|
|
Packit |
df99a1 |
return true;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
bool
|
|
Packit |
df99a1 |
ddjvu_document_s::notify_status(const DjVuPort *p, const GUTF8String &m)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (!doc) return false;
|
|
Packit |
df99a1 |
msg_push(xhead(DDJVU_INFO, this), msg_prep_info(m));
|
|
Packit |
df99a1 |
return true;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
ddjvu_document_s::notify_doc_flags_changed(const DjVuDocument *, long, long)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GMonitorLock lock(&monitor);
|
|
Packit |
df99a1 |
if (docinfoflag || !doc) return;
|
|
Packit |
df99a1 |
long flags = doc->get_doc_flags();
|
|
Packit |
df99a1 |
if ((flags & DjVuDocument::DOC_INIT_OK) ||
|
|
Packit |
df99a1 |
(flags & DjVuDocument::DOC_INIT_FAILED) )
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
msg_push(xhead(DDJVU_DOCINFO, this));
|
|
Packit |
df99a1 |
docinfoflag = true;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
ddjvu_document_s::callback(void *arg)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ddjvu_document_t *doc = (ddjvu_document_t *)arg;
|
|
Packit |
df99a1 |
if (doc && doc->pageinfoflag && !doc->fileflag)
|
|
Packit |
df99a1 |
msg_push(xhead(DDJVU_PAGEINFO, doc));
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GP<DataPool>
|
|
Packit |
df99a1 |
ddjvu_document_s::request_data(const DjVuPort *p, const GURL &url)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
// Note: the following line try to restore
|
|
Packit |
df99a1 |
// the bytes stored in the djvu file
|
|
Packit |
df99a1 |
// despite LT's i18n and gurl classes.
|
|
Packit |
df99a1 |
GUTF8String name = (const char*)url.fname();
|
|
Packit |
df99a1 |
GMonitorLock lock(&monitor);
|
|
Packit |
df99a1 |
GP<DataPool> pool;
|
|
Packit |
df99a1 |
if (names.contains(name))
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
int streamid = names[name];
|
|
Packit |
df99a1 |
return streams[streamid];
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else if (fileflag)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (doc && url.is_local_file_url())
|
|
Packit |
df99a1 |
return DataPool::create(url);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else if (doc)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
// prepare pool
|
|
Packit |
df99a1 |
if (++streamid > 0)
|
|
Packit |
df99a1 |
streams[streamid] = pool = DataPool::create();
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
pool = streams[(streamid = 0)];
|
|
Packit |
df99a1 |
names[name] = streamid;
|
|
Packit |
df99a1 |
pool->add_trigger(-1, callback, (void*)this);
|
|
Packit |
df99a1 |
// build message
|
|
Packit |
df99a1 |
GP<ddjvu_message_p> p = new ddjvu_message_p;
|
|
Packit |
df99a1 |
p->p.m_newstream.streamid = streamid;
|
|
Packit |
df99a1 |
p->tmp1 = name;
|
|
Packit |
df99a1 |
p->p.m_newstream.name = (const char*)(p->tmp1);
|
|
Packit |
df99a1 |
p->p.m_newstream.url = 0;
|
|
Packit |
df99a1 |
if (urlflag)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
// Should be urlencoded.
|
|
Packit |
df99a1 |
p->tmp2 = (const char*)url.get_string();
|
|
Packit |
df99a1 |
p->p.m_newstream.url = (const char*)(p->tmp2);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
msg_push(xhead(DDJVU_NEWSTREAM, this), p);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
return pool;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
bool
|
|
Packit |
df99a1 |
ddjvu_document_s::want_pageinfo()
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (doc && docinfoflag && !pageinfoflag)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
pageinfoflag = true;
|
|
Packit |
df99a1 |
int doctype = doc->get_doc_type();
|
|
Packit |
df99a1 |
if (doctype == DjVuDocument::BUNDLED ||
|
|
Packit |
df99a1 |
doctype == DjVuDocument::OLD_BUNDLED )
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<DataPool> pool;
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GMonitorLock lock(&monitor);
|
|
Packit |
df99a1 |
if (streams.contains(0))
|
|
Packit |
df99a1 |
pool = streams[0];
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
if (pool && doctype == DjVuDocument::BUNDLED)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<DjVmDir> dir = doc->get_djvm_dir();
|
|
Packit |
df99a1 |
if (dir)
|
|
Packit |
df99a1 |
for (int i=0; i<dir->get_files_num(); i++)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<DjVmDir::File> f = dir->pos_to_file(i);
|
|
Packit |
df99a1 |
if (! pool->has_data(f->offset, f->size))
|
|
Packit |
df99a1 |
pool->add_trigger(f->offset, f->size, callback, (void*)this );
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else if (pool && doctype == DjVuDocument::OLD_BUNDLED)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<DjVmDir0> dir = doc->get_djvm_dir0();
|
|
Packit |
df99a1 |
if (dir)
|
|
Packit |
df99a1 |
for (int i=0; i<dir->get_files_num(); i++)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<DjVmDir0::FileRec> f = dir->get_file(i);
|
|
Packit |
df99a1 |
if (! pool->has_data(f->offset, f->size))
|
|
Packit |
df99a1 |
pool->add_trigger(f->offset, f->size, callback, (void*)this );
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
return pageinfoflag;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// ----------------------------------------
|
|
Packit |
df99a1 |
// Documents
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
ddjvu_document_t *
|
|
Packit |
df99a1 |
ddjvu_document_create(ddjvu_context_t *ctx,
|
|
Packit |
df99a1 |
const char *url,
|
|
Packit |
df99a1 |
int cache)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ddjvu_document_t *d = 0;
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
DjVuFileCache *xcache = ctx->cache;
|
|
Packit |
df99a1 |
if (! cache) xcache = 0;
|
|
Packit |
df99a1 |
d = new ddjvu_document_s;
|
|
Packit |
df99a1 |
ref(d);
|
|
Packit |
df99a1 |
GMonitorLock lock(&d->monitor);
|
|
Packit |
df99a1 |
d->streams[0] = DataPool::create();
|
|
Packit |
df99a1 |
d->streamid = -1;
|
|
Packit |
df99a1 |
d->fileflag = false;
|
|
Packit |
df99a1 |
d->docinfoflag = false;
|
|
Packit |
df99a1 |
d->pageinfoflag = false;
|
|
Packit |
df99a1 |
d->myctx = ctx;
|
|
Packit |
df99a1 |
d->mydoc = 0;
|
|
Packit |
df99a1 |
d->doc = DjVuDocument::create_noinit();
|
|
Packit |
df99a1 |
if (url)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GURL gurl = GUTF8String(url);
|
|
Packit |
df99a1 |
gurl.clear_djvu_cgi_arguments();
|
|
Packit |
df99a1 |
d->urlflag = true;
|
|
Packit |
df99a1 |
d->doc->start_init(gurl, d, xcache);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GUTF8String s;
|
|
Packit |
df99a1 |
s.format("ddjvu:///doc%d/index.djvu", ++(ctx->uniqueid));;
|
|
Packit |
df99a1 |
GURL gurl = s;
|
|
Packit |
df99a1 |
d->urlflag = false;
|
|
Packit |
df99a1 |
d->doc->start_init(gurl, d, xcache);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH(ex)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (d)
|
|
Packit |
df99a1 |
unref(d);
|
|
Packit |
df99a1 |
d = 0;
|
|
Packit |
df99a1 |
ERROR1(ctx, ex);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
return d;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
static ddjvu_document_t *
|
|
Packit |
df99a1 |
ddjvu_document_create_by_filename_imp(ddjvu_context_t *ctx,
|
|
Packit |
df99a1 |
const char *filename,
|
|
Packit |
df99a1 |
int cache, int utf8)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ddjvu_document_t *d = 0;
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
DjVuFileCache *xcache = ctx->cache;
|
|
Packit |
df99a1 |
if (! cache) xcache = 0;
|
|
Packit |
df99a1 |
GURL gurl;
|
|
Packit |
df99a1 |
if (utf8)
|
|
Packit |
df99a1 |
gurl = GURL::Filename::UTF8(filename);
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
gurl = GURL::Filename::Native(filename);
|
|
Packit |
df99a1 |
d = new ddjvu_document_s;
|
|
Packit |
df99a1 |
ref(d);
|
|
Packit |
df99a1 |
GMonitorLock lock(&d->monitor);
|
|
Packit |
df99a1 |
d->streamid = -1;
|
|
Packit |
df99a1 |
d->fileflag = true;
|
|
Packit |
df99a1 |
d->pageinfoflag = false;
|
|
Packit |
df99a1 |
d->urlflag = false;
|
|
Packit |
df99a1 |
d->docinfoflag = false;
|
|
Packit |
df99a1 |
d->myctx = ctx;
|
|
Packit |
df99a1 |
d->mydoc = 0;
|
|
Packit |
df99a1 |
d->doc = DjVuDocument::create_noinit();
|
|
Packit |
df99a1 |
d->doc->start_init(gurl, d, xcache);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH(ex)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (d)
|
|
Packit |
df99a1 |
unref(d);
|
|
Packit |
df99a1 |
d = 0;
|
|
Packit |
df99a1 |
ERROR1(ctx, ex);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
return d;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
ddjvu_document_t *
|
|
Packit |
df99a1 |
ddjvu_document_create_by_filename(ddjvu_context_t *ctx,
|
|
Packit |
df99a1 |
const char *filename,
|
|
Packit |
df99a1 |
int cache)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
return ddjvu_document_create_by_filename_imp(ctx,filename,cache,0);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
ddjvu_document_t *
|
|
Packit |
df99a1 |
ddjvu_document_create_by_filename_utf8(ddjvu_context_t *ctx,
|
|
Packit |
df99a1 |
const char *filename,
|
|
Packit |
df99a1 |
int cache)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
return ddjvu_document_create_by_filename_imp(ctx,filename,cache,1);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
ddjvu_job_t *
|
|
Packit |
df99a1 |
ddjvu_document_job(ddjvu_document_t *document)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
return document;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// ----------------------------------------
|
|
Packit |
df99a1 |
// Streams
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
ddjvu_stream_write(ddjvu_document_t *doc,
|
|
Packit |
df99a1 |
int streamid,
|
|
Packit |
df99a1 |
const char *data,
|
|
Packit |
df99a1 |
unsigned long datalen )
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<DataPool> pool;
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GMonitorLock lock(&doc->monitor);
|
|
Packit |
df99a1 |
GPosition p = doc->streams.contains(streamid);
|
|
Packit |
df99a1 |
if (p) pool = doc->streams[p];
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
if (! pool)
|
|
Packit |
df99a1 |
G_THROW("Unknown stream ID");
|
|
Packit |
df99a1 |
if (datalen > 0)
|
|
Packit |
df99a1 |
pool->add_data(data, datalen);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH(ex)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ERROR1(doc,ex);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
ddjvu_stream_close(ddjvu_document_t *doc,
|
|
Packit |
df99a1 |
int streamid,
|
|
Packit |
df99a1 |
int stop )
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<DataPool> pool;
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GMonitorLock lock(&doc->monitor);
|
|
Packit |
df99a1 |
GPosition p = doc->streams.contains(streamid);
|
|
Packit |
df99a1 |
if (p) pool = doc->streams[p];
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
if (! pool)
|
|
Packit |
df99a1 |
G_THROW("Unknown stream ID");
|
|
Packit |
df99a1 |
if (stop)
|
|
Packit |
df99a1 |
pool->stop(true);
|
|
Packit |
df99a1 |
pool->set_eof();
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH(ex)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ERROR1(doc, ex);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// ----------------------------------------
|
|
Packit |
df99a1 |
// Document queries
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
ddjvu_document_type_t
|
|
Packit |
df99a1 |
ddjvu_document_get_type(ddjvu_document_t *document)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
DjVuDocument *doc = document->doc;
|
|
Packit |
df99a1 |
if (doc)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
switch (doc->get_doc_type())
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
case DjVuDocument::OLD_BUNDLED:
|
|
Packit |
df99a1 |
return DDJVU_DOCTYPE_OLD_BUNDLED;
|
|
Packit |
df99a1 |
case DjVuDocument::OLD_INDEXED:
|
|
Packit |
df99a1 |
return DDJVU_DOCTYPE_OLD_INDEXED;
|
|
Packit |
df99a1 |
case DjVuDocument::BUNDLED:
|
|
Packit |
df99a1 |
return DDJVU_DOCTYPE_BUNDLED;
|
|
Packit |
df99a1 |
case DjVuDocument::INDIRECT:
|
|
Packit |
df99a1 |
return DDJVU_DOCTYPE_INDIRECT;
|
|
Packit |
df99a1 |
case DjVuDocument::SINGLE_PAGE:
|
|
Packit |
df99a1 |
return DDJVU_DOCTYPE_SINGLEPAGE;
|
|
Packit |
df99a1 |
default:
|
|
Packit |
df99a1 |
break;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH(ex)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ERROR1(document,ex);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
return DDJVU_DOCTYPE_UNKNOWN;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
int
|
|
Packit |
df99a1 |
ddjvu_document_get_pagenum(ddjvu_document_t *document)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
DjVuDocument *doc = document->doc;
|
|
Packit |
df99a1 |
if (doc)
|
|
Packit |
df99a1 |
return doc->get_pages_num();
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH(ex)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ERROR1(document,ex);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
return 1;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
int
|
|
Packit |
df99a1 |
ddjvu_document_get_filenum(ddjvu_document_t *document)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
DjVuDocument *doc = document->doc;
|
|
Packit |
df99a1 |
if (! (doc && doc->is_init_ok()))
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
int doc_type = doc->get_doc_type();
|
|
Packit |
df99a1 |
if (doc_type == DjVuDocument::BUNDLED ||
|
|
Packit |
df99a1 |
doc_type == DjVuDocument::INDIRECT )
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<DjVmDir> dir = doc->get_djvm_dir();
|
|
Packit |
df99a1 |
return dir->get_files_num();
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else if (doc_type == DjVuDocument::OLD_BUNDLED)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<DjVmDir0> dir0 = doc->get_djvm_dir0();
|
|
Packit |
df99a1 |
return dir0->get_files_num();
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
return doc->get_pages_num();
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH(ex)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ERROR1(document,ex);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
#undef ddjvu_document_get_fileinfo
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
extern "C" DDJVUAPI ddjvu_status_t
|
|
Packit |
df99a1 |
ddjvu_document_get_fileinfo(ddjvu_document_t *d, int f, ddjvu_fileinfo_t *i);
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
ddjvu_status_t
|
|
Packit |
df99a1 |
ddjvu_document_get_fileinfo(ddjvu_document_t *d, int f, ddjvu_fileinfo_t *i)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
// for binary backward compatibility with ddjvuapi=17
|
|
Packit |
df99a1 |
struct info17_s { char t; int p,s; const char *d, *n, *l; };
|
|
Packit |
df99a1 |
return ddjvu_document_get_fileinfo_imp(d,f,i,sizeof(info17_s));
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
ddjvu_status_t
|
|
Packit |
df99a1 |
ddjvu_document_get_fileinfo_imp(ddjvu_document_t *document, int fileno,
|
|
Packit |
df99a1 |
ddjvu_fileinfo_t *info,
|
|
Packit |
df99a1 |
unsigned int infosz )
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ddjvu_fileinfo_t myinfo;
|
|
Packit |
df99a1 |
memset(info, 0, infosz);
|
|
Packit |
df99a1 |
if (infosz > sizeof(myinfo))
|
|
Packit |
df99a1 |
return DDJVU_JOB_FAILED;
|
|
Packit |
df99a1 |
DjVuDocument *doc = document->doc;
|
|
Packit |
df99a1 |
if (! doc)
|
|
Packit |
df99a1 |
return DDJVU_JOB_NOTSTARTED;
|
|
Packit |
df99a1 |
if (! doc->is_init_ok())
|
|
Packit |
df99a1 |
return document->status();
|
|
Packit |
df99a1 |
int type = doc->get_doc_type();
|
|
Packit |
df99a1 |
if ( type == DjVuDocument::BUNDLED ||
|
|
Packit |
df99a1 |
type == DjVuDocument::INDIRECT )
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<DjVmDir> dir = doc->get_djvm_dir();
|
|
Packit |
df99a1 |
GP<DjVmDir::File> file = dir->pos_to_file(fileno, &myinfo.pageno);
|
|
Packit |
df99a1 |
if (! file)
|
|
Packit |
df99a1 |
G_THROW("Illegal file number");
|
|
Packit |
df99a1 |
myinfo.type = 'I';
|
|
Packit |
df99a1 |
if (file->is_page())
|
|
Packit |
df99a1 |
myinfo.type = 'P';
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
myinfo.pageno = -1;
|
|
Packit |
df99a1 |
if (file->is_thumbnails())
|
|
Packit |
df99a1 |
myinfo.type = 'T';
|
|
Packit |
df99a1 |
if (file->is_shared_anno())
|
|
Packit |
df99a1 |
myinfo.type = 'S';
|
|
Packit |
df99a1 |
myinfo.size = file->size;
|
|
Packit |
df99a1 |
myinfo.id = file->get_load_name();
|
|
Packit |
df99a1 |
myinfo.name = file->get_save_name();
|
|
Packit |
df99a1 |
myinfo.title = file->get_title();
|
|
Packit |
df99a1 |
memcpy(info, &myinfo, infosz);
|
|
Packit |
df99a1 |
return DDJVU_JOB_OK;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else if (type == DjVuDocument::OLD_BUNDLED)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<DjVmDir0> dir0 = doc->get_djvm_dir0();
|
|
Packit |
df99a1 |
GP<DjVuNavDir> nav = doc->get_nav_dir();
|
|
Packit |
df99a1 |
GP<DjVmDir0::FileRec> frec = dir0->get_file(fileno);
|
|
Packit |
df99a1 |
if (! frec)
|
|
Packit |
df99a1 |
G_THROW("Illegal file number");
|
|
Packit |
df99a1 |
myinfo.size = frec->size;
|
|
Packit |
df99a1 |
myinfo.id = (const char*) frec->name;
|
|
Packit |
df99a1 |
myinfo.name = myinfo.title = myinfo.id;
|
|
Packit |
df99a1 |
if (! nav)
|
|
Packit |
df99a1 |
return DDJVU_JOB_STARTED;
|
|
Packit |
df99a1 |
else if (nav->name_to_page(frec->name) >= 0)
|
|
Packit |
df99a1 |
myinfo.type = 'P';
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
myinfo.type = 'I';
|
|
Packit |
df99a1 |
memcpy(info, &myinfo, infosz);
|
|
Packit |
df99a1 |
return DDJVU_JOB_OK;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (fileno<0 || fileno>=doc->get_pages_num())
|
|
Packit |
df99a1 |
G_THROW("Illegal file number");
|
|
Packit |
df99a1 |
myinfo.type = 'P';
|
|
Packit |
df99a1 |
myinfo.pageno = fileno;
|
|
Packit |
df99a1 |
myinfo.size = -1;
|
|
Packit |
df99a1 |
GP<DjVuNavDir> nav = doc->get_nav_dir();
|
|
Packit |
df99a1 |
myinfo.id = (nav) ? (const char *) nav->page_to_name(fileno) : 0;
|
|
Packit |
df99a1 |
myinfo.name = myinfo.title = myinfo.id;
|
|
Packit |
df99a1 |
GP<DjVuFile> file = doc->get_djvu_file(fileno, true);
|
|
Packit |
df99a1 |
GP<DataPool> pool;
|
|
Packit |
df99a1 |
if (file)
|
|
Packit |
df99a1 |
pool = file->get_init_data_pool();
|
|
Packit |
df99a1 |
if (pool)
|
|
Packit |
df99a1 |
myinfo.size = pool->get_length();
|
|
Packit |
df99a1 |
memcpy(info, &myinfo, infosz);
|
|
Packit |
df99a1 |
return DDJVU_JOB_OK;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH(ex)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ERROR1(document,ex);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
return DDJVU_JOB_FAILED;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
int
|
|
Packit |
df99a1 |
ddjvu_document_search_pageno(ddjvu_document_t *document, const char *name)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
DjVuDocument *doc = document->doc;
|
|
Packit |
df99a1 |
if (! (doc && doc->is_init_ok()))
|
|
Packit |
df99a1 |
return -1;
|
|
Packit |
df99a1 |
GP<DjVmDir> dir = doc->get_djvm_dir();
|
|
Packit |
df99a1 |
if (! dir)
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
GP<DjVmDir::File> file;
|
|
Packit |
df99a1 |
if (! (file = dir->id_to_file(GUTF8String(name))))
|
|
Packit |
df99a1 |
if (! (file = dir->name_to_file(GUTF8String(name))))
|
|
Packit |
df99a1 |
if (! (file = dir->title_to_file(GUTF8String(name))))
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
char *edata=0;
|
|
Packit |
df99a1 |
long int p = strtol(name, &edata, 10);
|
|
Packit |
df99a1 |
if (edata!=name && !*edata && p>=1)
|
|
Packit |
df99a1 |
file = dir->page_to_file(p-1);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
if (file)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
int pageno = -1;
|
|
Packit |
df99a1 |
int fileno = dir->get_file_pos(file);
|
|
Packit |
df99a1 |
if (dir->pos_to_file(fileno, &pageno))
|
|
Packit |
df99a1 |
return pageno;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH(ex)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ERROR1(document,ex);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
return -1;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
int
|
|
Packit |
df99a1 |
ddjvu_document_check_pagedata(ddjvu_document_t *document, int pageno)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
document->want_pageinfo();
|
|
Packit |
df99a1 |
DjVuDocument *doc = document->doc;
|
|
Packit |
df99a1 |
if (doc && doc->is_init_ok())
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
bool dontcreate = false;
|
|
Packit |
df99a1 |
if (doc->get_doc_type() == DjVuDocument::INDIRECT ||
|
|
Packit |
df99a1 |
doc->get_doc_type() == DjVuDocument::OLD_INDEXED )
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
dontcreate = true;
|
|
Packit |
df99a1 |
GURL url = doc->page_to_url(pageno);
|
|
Packit |
df99a1 |
if (! url.is_empty())
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GUTF8String name = (const char*)url.fname();
|
|
Packit |
df99a1 |
GMonitorLock lock(&document->monitor);
|
|
Packit |
df99a1 |
if (document->names.contains(name))
|
|
Packit |
df99a1 |
dontcreate = false;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
GP<DjVuFile> file = doc->get_djvu_file(pageno, dontcreate);
|
|
Packit |
df99a1 |
if (file && file->is_data_present())
|
|
Packit |
df99a1 |
return 1;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH(ex)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ERROR1(document,ex);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
#undef ddjvu_document_get_pageinfo
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
extern "C" DDJVUAPI ddjvu_status_t
|
|
Packit |
df99a1 |
ddjvu_document_get_pageinfo(ddjvu_document_t *d, int p, ddjvu_pageinfo_t *i);
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
ddjvu_status_t
|
|
Packit |
df99a1 |
ddjvu_document_get_pageinfo(ddjvu_document_t *d, int p, ddjvu_pageinfo_t *i)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
// for binary backward compatibility with ddjvuapi<=17
|
|
Packit |
df99a1 |
struct info17_s { int w; int h; int d; };
|
|
Packit |
df99a1 |
return ddjvu_document_get_pageinfo_imp(d,p,i,sizeof(struct info17_s));
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
ddjvu_status_t
|
|
Packit |
df99a1 |
ddjvu_document_get_pageinfo_imp(ddjvu_document_t *document, int pageno,
|
|
Packit |
df99a1 |
ddjvu_pageinfo_t *pageinfo,
|
|
Packit |
df99a1 |
unsigned int infosz)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ddjvu_pageinfo_t myinfo;
|
|
Packit |
df99a1 |
memset(pageinfo, 0, infosz);
|
|
Packit |
df99a1 |
if (infosz > sizeof(myinfo))
|
|
Packit |
df99a1 |
return DDJVU_JOB_FAILED;
|
|
Packit |
df99a1 |
DjVuDocument *doc = document->doc;
|
|
Packit |
df99a1 |
if (doc)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
document->want_pageinfo();
|
|
Packit |
df99a1 |
GP<DjVuFile> file = doc->get_djvu_file(pageno);
|
|
Packit |
df99a1 |
if (! file || ! file->is_data_present() )
|
|
Packit |
df99a1 |
return DDJVU_JOB_STARTED;
|
|
Packit |
df99a1 |
const GP<ByteStream> pbs(file->get_djvu_bytestream(false, false));
|
|
Packit |
df99a1 |
const GP<IFFByteStream> iff(IFFByteStream::create(pbs));
|
|
Packit |
df99a1 |
GUTF8String chkid;
|
|
Packit |
df99a1 |
if (iff->get_chunk(chkid))
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (chkid == "FORM:DJVU")
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
while (iff->get_chunk(chkid) && chkid!="INFO")
|
|
Packit |
df99a1 |
iff->close_chunk();
|
|
Packit |
df99a1 |
if (chkid == "INFO")
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<ByteStream> gbs = iff->get_bytestream();
|
|
Packit |
df99a1 |
GP<DjVuInfo> info=DjVuInfo::create();
|
|
Packit |
df99a1 |
info->decode(*gbs);
|
|
Packit |
df99a1 |
int rot = info->orientation;
|
|
Packit |
df99a1 |
myinfo.rotation = rot;
|
|
Packit |
df99a1 |
myinfo.width = (rot&1) ? info->height : info->width;
|
|
Packit |
df99a1 |
myinfo.height = (rot&1) ? info->width : info->height;
|
|
Packit |
df99a1 |
myinfo.dpi = info->dpi;
|
|
Packit |
df99a1 |
myinfo.version = info->version;
|
|
Packit |
df99a1 |
memcpy(pageinfo, &myinfo, infosz);
|
|
Packit |
df99a1 |
return DDJVU_JOB_OK;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else if (chkid == "FORM:BM44" || chkid == "FORM:PM44")
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
while (iff->get_chunk(chkid) &&
|
|
Packit |
df99a1 |
chkid!="BM44" && chkid!="PM44")
|
|
Packit |
df99a1 |
iff->close_chunk();
|
|
Packit |
df99a1 |
if (chkid=="BM44" || chkid=="PM44")
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<ByteStream> gbs = iff->get_bytestream();
|
|
Packit |
df99a1 |
if (gbs->read8() == 0)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
gbs->read8();
|
|
Packit |
df99a1 |
unsigned char vhi = gbs->read8();
|
|
Packit |
df99a1 |
unsigned char vlo = gbs->read8();
|
|
Packit |
df99a1 |
unsigned char xhi = gbs->read8();
|
|
Packit |
df99a1 |
unsigned char xlo = gbs->read8();
|
|
Packit |
df99a1 |
unsigned char yhi = gbs->read8();
|
|
Packit |
df99a1 |
unsigned char ylo = gbs->read8();
|
|
Packit |
df99a1 |
myinfo.width = (xhi<<8)+xlo;
|
|
Packit |
df99a1 |
myinfo.height = (yhi<<8)+ylo;
|
|
Packit |
df99a1 |
myinfo.dpi = 100;
|
|
Packit |
df99a1 |
myinfo.rotation = 0;
|
|
Packit |
df99a1 |
myinfo.version = (vhi<<8)+vlo;
|
|
Packit |
df99a1 |
memcpy(pageinfo, &myinfo, infosz);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH(ex)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ERROR1(document, ex);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
return DDJVU_JOB_FAILED;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
static char *
|
|
Packit |
df99a1 |
get_file_dump(DjVuFile *file)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
DjVuDumpHelper dumper;
|
|
Packit |
df99a1 |
GP<DataPool> pool = file->get_init_data_pool();
|
|
Packit |
df99a1 |
GP<ByteStream> str = dumper.dump(pool);
|
|
Packit |
df99a1 |
int size = str->size();
|
|
Packit |
df99a1 |
char *buffer;
|
|
Packit |
df99a1 |
if ((size = str->size()) > 0 && (buffer = (char*)malloc(size+1)))
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
str->seek(0);
|
|
Packit |
df99a1 |
int len = str->readall(buffer, size);
|
|
Packit |
df99a1 |
buffer[len] = 0;
|
|
Packit |
df99a1 |
return buffer;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
char *
|
|
Packit |
df99a1 |
ddjvu_document_get_pagedump(ddjvu_document_t *document, int pageno)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
DjVuDocument *doc = document->doc;
|
|
Packit |
df99a1 |
if (doc)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
document->want_pageinfo();
|
|
Packit |
df99a1 |
GP<DjVuFile> file = doc->get_djvu_file(pageno);
|
|
Packit |
df99a1 |
if (file && file->is_data_present())
|
|
Packit |
df99a1 |
return get_file_dump(file);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH(ex)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ERROR1(document, ex);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
char *
|
|
Packit |
df99a1 |
ddjvu_document_get_filedump(ddjvu_document_t *document, int fileno)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
DjVuDocument *doc = document->doc;
|
|
Packit |
df99a1 |
document->want_pageinfo();
|
|
Packit |
df99a1 |
if (doc)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<DjVuFile> file;
|
|
Packit |
df99a1 |
int type = doc->get_doc_type();
|
|
Packit |
df99a1 |
if ( type != DjVuDocument::BUNDLED &&
|
|
Packit |
df99a1 |
type != DjVuDocument::INDIRECT )
|
|
Packit |
df99a1 |
file = doc->get_djvu_file(fileno);
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<DjVmDir> dir = doc->get_djvm_dir();
|
|
Packit |
df99a1 |
GP<DjVmDir::File> fdesc = dir->pos_to_file(fileno);
|
|
Packit |
df99a1 |
if (fdesc)
|
|
Packit |
df99a1 |
file = doc->get_djvu_file(fdesc->get_load_name());
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
if (file && file->is_data_present())
|
|
Packit |
df99a1 |
return get_file_dump(file);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH(ex)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ERROR1(document, ex);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// ----------------------------------------
|
|
Packit |
df99a1 |
// Page
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
static ddjvu_page_t *
|
|
Packit |
df99a1 |
ddjvu_page_create(ddjvu_document_t *document, ddjvu_job_t *job,
|
|
Packit |
df99a1 |
const char *pageid, int pageno)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ddjvu_page_t *p = 0;
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
DjVuDocument *doc = document->doc;
|
|
Packit |
df99a1 |
if (! doc) return 0;
|
|
Packit |
df99a1 |
p = new ddjvu_page_s;
|
|
Packit |
df99a1 |
ref(p);
|
|
Packit |
df99a1 |
GMonitorLock lock(&p->monitor);
|
|
Packit |
df99a1 |
p->myctx = document->myctx;
|
|
Packit |
df99a1 |
p->mydoc = document;
|
|
Packit |
df99a1 |
p->pageinfoflag = false;
|
|
Packit |
df99a1 |
p->pagedoneflag = false;
|
|
Packit |
df99a1 |
if (! job)
|
|
Packit |
df99a1 |
job = p;
|
|
Packit |
df99a1 |
p->job = job;
|
|
Packit |
df99a1 |
if (pageid)
|
|
Packit |
df99a1 |
p->img = doc->get_page(GNativeString(pageid), false, job);
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
p->img = doc->get_page(pageno, false, job);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH(ex)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (p)
|
|
Packit |
df99a1 |
unref(p);
|
|
Packit |
df99a1 |
p = 0;
|
|
Packit |
df99a1 |
ERROR1(document, ex);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
return p;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
ddjvu_page_t *
|
|
Packit |
df99a1 |
ddjvu_page_create_by_pageno(ddjvu_document_t *document, int pageno)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
return ddjvu_page_create(document, 0, 0, pageno);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
ddjvu_page_t *
|
|
Packit |
df99a1 |
ddjvu_page_create_by_pageid(ddjvu_document_t *document, const char *pageid)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
return ddjvu_page_create(document, 0, pageid, 0);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
ddjvu_job_t *
|
|
Packit |
df99a1 |
ddjvu_page_job(ddjvu_page_t *page)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
return page;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// ----------------------------------------
|
|
Packit |
df99a1 |
// Page callbacks
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
ddjvu_page_s::release()
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
img = 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
ddjvu_status_t
|
|
Packit |
df99a1 |
ddjvu_page_s::status()
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (! img)
|
|
Packit |
df99a1 |
return DDJVU_JOB_NOTSTARTED;
|
|
Packit |
df99a1 |
DjVuFile *file = img->get_djvu_file();
|
|
Packit |
df99a1 |
DjVuInfo *info = img->get_info();
|
|
Packit |
df99a1 |
if (! file)
|
|
Packit |
df99a1 |
return DDJVU_JOB_NOTSTARTED;
|
|
Packit |
df99a1 |
else if (file->is_decode_stopped())
|
|
Packit |
df99a1 |
return DDJVU_JOB_STOPPED;
|
|
Packit |
df99a1 |
else if (file->is_decode_failed())
|
|
Packit |
df99a1 |
return DDJVU_JOB_FAILED;
|
|
Packit |
df99a1 |
else if (file->is_decode_ok())
|
|
Packit |
df99a1 |
return (info) ? DDJVU_JOB_OK : DDJVU_JOB_FAILED;
|
|
Packit |
df99a1 |
else if (file->is_decoding())
|
|
Packit |
df99a1 |
return DDJVU_JOB_STARTED;
|
|
Packit |
df99a1 |
return DDJVU_JOB_NOTSTARTED;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
bool
|
|
Packit |
df99a1 |
ddjvu_page_s::inherits(const GUTF8String &classname) const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
return (classname == "ddjvu_page_s")
|
|
Packit |
df99a1 |
|| ddjvu_job_s::inherits(classname);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
bool
|
|
Packit |
df99a1 |
ddjvu_page_s::notify_error(const DjVuPort *, const GUTF8String &m)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (!img) return false;
|
|
Packit |
df99a1 |
msg_push(xhead(DDJVU_ERROR, this), msg_prep_error(m));
|
|
Packit |
df99a1 |
return true;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
bool
|
|
Packit |
df99a1 |
ddjvu_page_s::notify_status(const DjVuPort *p, const GUTF8String &m)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (!img) return false;
|
|
Packit |
df99a1 |
msg_push(xhead(DDJVU_INFO, this), msg_prep_info(m));
|
|
Packit |
df99a1 |
return true;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
ddjvu_page_s::notify_file_flags_changed(const DjVuFile *sender, long, long)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GMonitorLock lock(&monitor);
|
|
Packit |
df99a1 |
if (!img) return;
|
|
Packit |
df99a1 |
DjVuFile *file = img->get_djvu_file();
|
|
Packit |
df99a1 |
if (file==0 || file!=sender) return;
|
|
Packit |
df99a1 |
long flags = file->get_flags();
|
|
Packit |
df99a1 |
if ((flags & DjVuFile::DECODE_OK) ||
|
|
Packit |
df99a1 |
(flags & DjVuFile::DECODE_FAILED) ||
|
|
Packit |
df99a1 |
(flags & DjVuFile::DECODE_STOPPED) )
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (pagedoneflag) return;
|
|
Packit |
df99a1 |
msg_push(xhead(DDJVU_PAGEINFO, this));
|
|
Packit |
df99a1 |
pageinfoflag = pagedoneflag = true;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
ddjvu_page_s::notify_relayout(const DjVuImage *dimg)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GMonitorLock lock(&monitor);
|
|
Packit |
df99a1 |
if (img && !pageinfoflag)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
msg_push(xhead(DDJVU_PAGEINFO, this));
|
|
Packit |
df99a1 |
msg_push(xhead(DDJVU_RELAYOUT, this));
|
|
Packit |
df99a1 |
pageinfoflag = true;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
ddjvu_page_s::notify_redisplay(const DjVuImage *dimg)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GMonitorLock lock(&monitor);
|
|
Packit |
df99a1 |
if (img && !pageinfoflag)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
msg_push(xhead(DDJVU_PAGEINFO, this));
|
|
Packit |
df99a1 |
msg_push(xhead(DDJVU_RELAYOUT, this));
|
|
Packit |
df99a1 |
pageinfoflag = true;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
if (img && pageinfoflag)
|
|
Packit |
df99a1 |
msg_push(xhead(DDJVU_REDISPLAY, this));
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
ddjvu_page_s::notify_chunk_done(const DjVuPort*, const GUTF8String &name)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GMonitorLock lock(&monitor);
|
|
Packit |
df99a1 |
if (! img) return;
|
|
Packit |
df99a1 |
GP<ddjvu_message_p> p = new ddjvu_message_p;
|
|
Packit |
df99a1 |
p->tmp1 = name;
|
|
Packit |
df99a1 |
p->p.m_chunk.chunkid = (const char*)(p->tmp1);
|
|
Packit |
df99a1 |
msg_push(xhead(DDJVU_CHUNK,this), p);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// ----------------------------------------
|
|
Packit |
df99a1 |
// Page queries
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
int
|
|
Packit |
df99a1 |
ddjvu_page_get_width(ddjvu_page_t *page)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (page && page->img)
|
|
Packit |
df99a1 |
return page->img->get_width();
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH(ex)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ERROR1(page, ex);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
int
|
|
Packit |
df99a1 |
ddjvu_page_get_height(ddjvu_page_t *page)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (page && page->img)
|
|
Packit |
df99a1 |
return page->img->get_height();
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH(ex)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ERROR1(page, ex);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
int
|
|
Packit |
df99a1 |
ddjvu_page_get_resolution(ddjvu_page_t *page)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (page && page->img)
|
|
Packit |
df99a1 |
return page->img->get_dpi();
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH(ex)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ERROR1(page, ex);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
double
|
|
Packit |
df99a1 |
ddjvu_page_get_gamma(ddjvu_page_t *page)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (page && page->img)
|
|
Packit |
df99a1 |
return page->img->get_gamma();
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH(ex)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ERROR1(page, ex);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
return 2.2;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
int
|
|
Packit |
df99a1 |
ddjvu_page_get_version(ddjvu_page_t *page)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (page && page->img)
|
|
Packit |
df99a1 |
return page->img->get_version();
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH(ex)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ERROR1(page, ex);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
return DJVUVERSION;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
ddjvu_page_type_t
|
|
Packit |
df99a1 |
ddjvu_page_get_type(ddjvu_page_t *page)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (! (page && page->img))
|
|
Packit |
df99a1 |
return DDJVU_PAGETYPE_UNKNOWN;
|
|
Packit |
df99a1 |
else if (page->img->is_legal_bilevel())
|
|
Packit |
df99a1 |
return DDJVU_PAGETYPE_BITONAL;
|
|
Packit |
df99a1 |
else if (page->img->is_legal_photo())
|
|
Packit |
df99a1 |
return DDJVU_PAGETYPE_PHOTO;
|
|
Packit |
df99a1 |
else if (page->img->is_legal_compound())
|
|
Packit |
df99a1 |
return DDJVU_PAGETYPE_COMPOUND;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH(ex)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ERROR1(page, ex);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
return DDJVU_PAGETYPE_UNKNOWN;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
char *
|
|
Packit |
df99a1 |
ddjvu_page_get_short_description(ddjvu_page_t *page)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (page && page->img)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
const char *desc = page->img->get_short_description();
|
|
Packit |
df99a1 |
return xstr(DjVuMessageLite::LookUpUTF8(desc));
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH(ex)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ERROR1(page, ex);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
char *
|
|
Packit |
df99a1 |
ddjvu_page_get_long_description(ddjvu_page_t *page)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (page && page->img)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
const char *desc = page->img->get_long_description();
|
|
Packit |
df99a1 |
return xstr(DjVuMessageLite::LookUpUTF8(desc));
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH(ex)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ERROR1(page, ex);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// ----------------------------------------
|
|
Packit |
df99a1 |
// Rotations
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
ddjvu_page_set_rotation(ddjvu_page_t *page,
|
|
Packit |
df99a1 |
ddjvu_page_rotation_t rot)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
switch(rot)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
case DDJVU_ROTATE_0:
|
|
Packit |
df99a1 |
case DDJVU_ROTATE_90:
|
|
Packit |
df99a1 |
case DDJVU_ROTATE_180:
|
|
Packit |
df99a1 |
case DDJVU_ROTATE_270:
|
|
Packit |
df99a1 |
if (page && page->img && page->img->get_info())
|
|
Packit |
df99a1 |
page->img->set_rotate((int)rot);
|
|
Packit |
df99a1 |
break;
|
|
Packit |
df99a1 |
default:
|
|
Packit |
df99a1 |
G_THROW("Illegal ddjvu rotation code");
|
|
Packit |
df99a1 |
break;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH(ex)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ERROR1(page, ex);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
ddjvu_page_rotation_t
|
|
Packit |
df99a1 |
ddjvu_page_get_rotation(ddjvu_page_t *page)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ddjvu_page_rotation_t rot = DDJVU_ROTATE_0;
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (page && page->img)
|
|
Packit |
df99a1 |
rot = (ddjvu_page_rotation_t)(page->img->get_rotate() & 3);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH(ex)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ERROR1(page, ex);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
return rot;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
ddjvu_page_rotation_t
|
|
Packit |
df99a1 |
ddjvu_page_get_initial_rotation(ddjvu_page_t *page)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ddjvu_page_rotation_t rot = DDJVU_ROTATE_0;
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<DjVuInfo> info;
|
|
Packit |
df99a1 |
if (page && page->img)
|
|
Packit |
df99a1 |
info = page->img->get_info();
|
|
Packit |
df99a1 |
if (info)
|
|
Packit |
df99a1 |
rot = (ddjvu_page_rotation_t)(info->orientation & 3);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH(ex)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ERROR1(page, ex);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
return rot;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// ----------------------------------------
|
|
Packit |
df99a1 |
// Rectangles
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
static void
|
|
Packit |
df99a1 |
rect2grect(const ddjvu_rect_t *r, GRect &g)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
g.xmin = r->x;
|
|
Packit |
df99a1 |
g.ymin = r->y;
|
|
Packit |
df99a1 |
g.xmax = r->x + r->w;
|
|
Packit |
df99a1 |
g.ymax = r->y + r->h;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
static void
|
|
Packit |
df99a1 |
grect2rect(const GRect &g, ddjvu_rect_t *r)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (g.isempty())
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
r->x = r->y = 0;
|
|
Packit |
df99a1 |
r->w = r->h = 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
r->x = g.xmin;
|
|
Packit |
df99a1 |
r->y = g.ymin;
|
|
Packit |
df99a1 |
r->w = g.width();
|
|
Packit |
df99a1 |
r->h = g.height();
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
ddjvu_rectmapper_t *
|
|
Packit |
df99a1 |
ddjvu_rectmapper_create(ddjvu_rect_t *input, ddjvu_rect_t *output)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GRect ginput, goutput;
|
|
Packit |
df99a1 |
rect2grect(input, ginput);
|
|
Packit |
df99a1 |
rect2grect(output, goutput);
|
|
Packit |
df99a1 |
GRectMapper *mapper = new GRectMapper;
|
|
Packit |
df99a1 |
if (!ginput.isempty())
|
|
Packit |
df99a1 |
mapper->set_input(ginput);
|
|
Packit |
df99a1 |
if (!goutput.isempty())
|
|
Packit |
df99a1 |
mapper->set_output(goutput);
|
|
Packit |
df99a1 |
return (ddjvu_rectmapper_t*)mapper;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
ddjvu_rectmapper_modify(ddjvu_rectmapper_t *mapper,
|
|
Packit |
df99a1 |
int rotation, int mirrorx, int mirrory)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GRectMapper *gmapper = (GRectMapper*)mapper;
|
|
Packit |
df99a1 |
if (! gmapper) return;
|
|
Packit |
df99a1 |
gmapper->rotate(rotation);
|
|
Packit |
df99a1 |
if (mirrorx & 1)
|
|
Packit |
df99a1 |
gmapper->mirrorx();
|
|
Packit |
df99a1 |
if (mirrory & 1)
|
|
Packit |
df99a1 |
gmapper->mirrory();
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
ddjvu_rectmapper_release(ddjvu_rectmapper_t *mapper)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GRectMapper *gmapper = (GRectMapper*)mapper;
|
|
Packit |
df99a1 |
if (! gmapper) return;
|
|
Packit |
df99a1 |
delete gmapper;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
ddjvu_map_point(ddjvu_rectmapper_t *mapper, int *x, int *y)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GRectMapper *gmapper = (GRectMapper*)mapper;
|
|
Packit |
df99a1 |
if (! gmapper) return;
|
|
Packit |
df99a1 |
gmapper->map(*x,*y);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
ddjvu_map_rect(ddjvu_rectmapper_t *mapper, ddjvu_rect_t *rect)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GRectMapper *gmapper = (GRectMapper*)mapper;
|
|
Packit |
df99a1 |
if (! gmapper) return;
|
|
Packit |
df99a1 |
GRect grect;
|
|
Packit |
df99a1 |
rect2grect(rect,grect);
|
|
Packit |
df99a1 |
gmapper->map(grect);
|
|
Packit |
df99a1 |
grect2rect(grect,rect);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
ddjvu_unmap_point(ddjvu_rectmapper_t *mapper, int *x, int *y)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GRectMapper *gmapper = (GRectMapper*)mapper;
|
|
Packit |
df99a1 |
if (! gmapper) return;
|
|
Packit |
df99a1 |
gmapper->unmap(*x,*y);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
ddjvu_unmap_rect(ddjvu_rectmapper_t *mapper, ddjvu_rect_t *rect)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GRectMapper *gmapper = (GRectMapper*)mapper;
|
|
Packit |
df99a1 |
if (! gmapper) return;
|
|
Packit |
df99a1 |
GRect grect;
|
|
Packit |
df99a1 |
rect2grect(rect,grect);
|
|
Packit |
df99a1 |
gmapper->unmap(grect);
|
|
Packit |
df99a1 |
grect2rect(grect,rect);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// ----------------------------------------
|
|
Packit |
df99a1 |
// Render
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
struct DJVUNS ddjvu_format_s
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ddjvu_format_style_t style;
|
|
Packit |
df99a1 |
uint32_t rgb[3][256];
|
|
Packit |
df99a1 |
uint32_t palette[6*6*6];
|
|
Packit |
df99a1 |
uint32_t xorval;
|
|
Packit |
df99a1 |
double gamma;
|
|
Packit |
df99a1 |
GPixel white;
|
|
Packit |
df99a1 |
char ditherbits;
|
|
Packit |
df99a1 |
bool rtoptobottom;
|
|
Packit |
df99a1 |
bool ytoptobottom;
|
|
Packit |
df99a1 |
};
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
static ddjvu_format_t *
|
|
Packit |
df99a1 |
fmt_error(ddjvu_format_t *fmt)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
delete fmt;
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
ddjvu_format_t *
|
|
Packit |
df99a1 |
ddjvu_format_create(ddjvu_format_style_t style,
|
|
Packit |
df99a1 |
int nargs, unsigned int *args)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ddjvu_format_t *fmt = new ddjvu_format_s;
|
|
Packit |
df99a1 |
memset(fmt, 0, sizeof(ddjvu_format_t));
|
|
Packit |
df99a1 |
fmt->style = style;
|
|
Packit |
df99a1 |
fmt->rtoptobottom = false;
|
|
Packit |
df99a1 |
fmt->ytoptobottom = false;
|
|
Packit |
df99a1 |
fmt->gamma = 2.2;
|
|
Packit |
df99a1 |
fmt->white = GPixel::WHITE;
|
|
Packit |
df99a1 |
// Ditherbits
|
|
Packit |
df99a1 |
fmt->ditherbits = 32;
|
|
Packit |
df99a1 |
if (style==DDJVU_FORMAT_RGBMASK16)
|
|
Packit |
df99a1 |
fmt->ditherbits = 16;
|
|
Packit |
df99a1 |
else if (style==DDJVU_FORMAT_PALETTE8)
|
|
Packit |
df99a1 |
fmt->ditherbits = 8;
|
|
Packit |
df99a1 |
else if (style==DDJVU_FORMAT_MSBTOLSB || style==DDJVU_FORMAT_LSBTOMSB)
|
|
Packit |
df99a1 |
fmt->ditherbits = 1;
|
|
Packit |
df99a1 |
// Args
|
|
Packit |
df99a1 |
switch(style)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
case DDJVU_FORMAT_RGBMASK16:
|
|
Packit |
df99a1 |
case DDJVU_FORMAT_RGBMASK32:
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (sizeof(uint16_t)!=2 || sizeof(uint32_t)!=4)
|
|
Packit |
df99a1 |
return fmt_error(fmt);
|
|
Packit |
df99a1 |
if (!args || nargs<3 || nargs>4)
|
|
Packit |
df99a1 |
return fmt_error(fmt);
|
|
Packit |
df99a1 |
{ // extra nesting for windows
|
|
Packit |
df99a1 |
for (int j=0; j<3; j++)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
int shift = 0;
|
|
Packit |
df99a1 |
uint32_t mask = args[j];
|
|
Packit |
df99a1 |
for (shift=0; shift<32 && !(mask & 1); shift++)
|
|
Packit |
df99a1 |
mask >>= 1;
|
|
Packit |
df99a1 |
if ((shift>=32) || (mask&(mask+1)))
|
|
Packit |
df99a1 |
return fmt_error(fmt);
|
|
Packit |
df99a1 |
for (int i=0; i<256; i++)
|
|
Packit |
df99a1 |
fmt->rgb[j][i] = (mask & ((int)((i*mask+127.0)/255.0)))<
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
if (nargs >= 4)
|
|
Packit |
df99a1 |
fmt->xorval = args[3];
|
|
Packit |
df99a1 |
break;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
case DDJVU_FORMAT_PALETTE8:
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (nargs!=6*6*6 || !args)
|
|
Packit |
df99a1 |
return fmt_error(fmt);
|
|
Packit |
df99a1 |
{ // extra nesting for windows
|
|
Packit |
df99a1 |
for (int k=0; k<6*6*6; k++)
|
|
Packit |
df99a1 |
fmt->palette[k] = args[k];
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
{ // extra nesting for windows
|
|
Packit |
df99a1 |
int j=0;
|
|
Packit |
df99a1 |
for(int i=0; i<6; i++)
|
|
Packit |
df99a1 |
for(; j < (i+1)*0x33 - 0x19 && j<256; j++)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
fmt->rgb[0][j] = i * 6 * 6;
|
|
Packit |
df99a1 |
fmt->rgb[1][j] = i * 6;
|
|
Packit |
df99a1 |
fmt->rgb[2][j] = i;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
break;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
case DDJVU_FORMAT_RGB24:
|
|
Packit |
df99a1 |
case DDJVU_FORMAT_BGR24:
|
|
Packit |
df99a1 |
case DDJVU_FORMAT_GREY8:
|
|
Packit |
df99a1 |
case DDJVU_FORMAT_LSBTOMSB:
|
|
Packit |
df99a1 |
case DDJVU_FORMAT_MSBTOLSB:
|
|
Packit |
df99a1 |
if (!nargs)
|
|
Packit |
df99a1 |
break;
|
|
Packit |
df99a1 |
default:
|
|
Packit |
df99a1 |
return fmt_error(fmt);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
return fmt;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
ddjvu_format_set_row_order(ddjvu_format_t *format, int top_to_bottom)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
format->rtoptobottom = !! top_to_bottom;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
ddjvu_format_set_y_direction(ddjvu_format_t *format, int top_to_bottom)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
format->ytoptobottom = !! top_to_bottom;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
ddjvu_format_set_ditherbits(ddjvu_format_t *format, int bits)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (bits>0 && bits<=64)
|
|
Packit |
df99a1 |
format->ditherbits = bits;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
ddjvu_format_set_gamma(ddjvu_format_t *format, double gamma)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (gamma>=0.5 && gamma<=5.0)
|
|
Packit |
df99a1 |
format->gamma = gamma;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
ddjvu_format_set_white(ddjvu_format_t *format,
|
|
Packit |
df99a1 |
unsigned char b, unsigned char g, unsigned char r)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
format->white.b = b;
|
|
Packit |
df99a1 |
format->white.g = g;
|
|
Packit |
df99a1 |
format->white.r = r;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
ddjvu_format_release(ddjvu_format_t *format)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
delete format;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
static void
|
|
Packit |
df99a1 |
fmt_convert_row(const GPixel *p, int w,
|
|
Packit |
df99a1 |
const ddjvu_format_t *fmt, char *buf)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
const uint32_t (*r)[256] = fmt->rgb;
|
|
Packit |
df99a1 |
const uint32_t xorval = fmt->xorval;
|
|
Packit |
df99a1 |
switch(fmt->style)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
case DDJVU_FORMAT_BGR24: /* truecolor 24 bits in BGR order */
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
memcpy(buf, (const char*)p, 3*w);
|
|
Packit |
df99a1 |
break;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
case DDJVU_FORMAT_RGB24: /* truecolor 24 bits in RGB order */
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
while (--w >= 0) {
|
|
Packit |
df99a1 |
buf[0]=p->r; buf[1]=p->g; buf[2]=p->b;
|
|
Packit |
df99a1 |
buf+=3; p+=1;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
break;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
case DDJVU_FORMAT_RGBMASK16: /* truecolor 16 bits with masks */
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
uint16_t *b = (uint16_t*)buf;
|
|
Packit |
df99a1 |
while (--w >= 0) {
|
|
Packit |
df99a1 |
b[0]=(r[0][p->r]|r[1][p->g]|r[2][p->b])^xorval;
|
|
Packit |
df99a1 |
b+=1; p+=1;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
break;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
case DDJVU_FORMAT_RGBMASK32: /* truecolor 32 bits with masks */
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
uint32_t *b = (uint32_t*)buf;
|
|
Packit |
df99a1 |
while (--w >= 0) {
|
|
Packit |
df99a1 |
b[0]=(r[0][p->r]|r[1][p->g]|r[2][p->b])^xorval;
|
|
Packit |
df99a1 |
b+=1; p+=1;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
break;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
case DDJVU_FORMAT_GREY8: /* greylevel 8 bits */
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
while (--w >= 0) {
|
|
Packit |
df99a1 |
buf[0]=(5*p->r + 9*p->g + 2*p->b)>>4;
|
|
Packit |
df99a1 |
buf+=1; p+=1;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
break;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
case DDJVU_FORMAT_PALETTE8: /* paletized 8 bits (6x6x6 color cube) */
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
const uint32_t *u = fmt->palette;
|
|
Packit |
df99a1 |
while (--w >= 0) {
|
|
Packit |
df99a1 |
buf[0] = u[r[0][p->r]+r[1][p->g]+r[2][p->b]];
|
|
Packit |
df99a1 |
buf+=1; p+=1;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
break;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
case DDJVU_FORMAT_MSBTOLSB: /* packed bits, msb on the left */
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
int t = (5*fmt->white.r + 9*fmt->white.g + 2*fmt->white.b + 16);
|
|
Packit |
df99a1 |
t = t * 0xc / 0x10;
|
|
Packit |
df99a1 |
unsigned char s=0, m=0x80;
|
|
Packit |
df99a1 |
while (--w >= 0) {
|
|
Packit |
df99a1 |
if ( 5*p->r + 9*p->g + 2*p->b < t ) { s |= m; }
|
|
Packit |
df99a1 |
if (! (m >>= 1)) { *buf++ = s; s=0; m=0x80; }
|
|
Packit |
df99a1 |
p += 1;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
if (m < 0x80) { *buf++ = s; }
|
|
Packit |
df99a1 |
break;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
case DDJVU_FORMAT_LSBTOMSB: /* packed bits, lsb on the left */
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
int t = 5*fmt->white.r + 9*fmt->white.g + 2*fmt->white.b + 16;
|
|
Packit |
df99a1 |
t = t * 0xc / 0x10;
|
|
Packit |
df99a1 |
unsigned char s=0, m=0x1;
|
|
Packit |
df99a1 |
while (--w >= 0) {
|
|
Packit |
df99a1 |
if ( 5*p->r + 9*p->g + 2*p->b < t ) { s |= m; }
|
|
Packit |
df99a1 |
if (! (m <<= 1)) { *buf++ = s; s=0; m=0x1; }
|
|
Packit |
df99a1 |
p += 1;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
if (m > 0x1) { *buf++ = s; }
|
|
Packit |
df99a1 |
break;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
static void
|
|
Packit |
df99a1 |
fmt_convert(GPixmap *pm, const ddjvu_format_t *fmt, char *buffer, int rowsize)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
int w = pm->columns();
|
|
Packit |
df99a1 |
int h = pm->rows();
|
|
Packit |
df99a1 |
// Loop on rows
|
|
Packit |
df99a1 |
if (fmt->rtoptobottom)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
for(int r=h-1; r>=0; r--, buffer+=rowsize)
|
|
Packit |
df99a1 |
fmt_convert_row((*pm)[r], w, fmt, buffer);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
for(int r=0; r
|
|
Packit |
df99a1 |
fmt_convert_row((*pm)[r], w, fmt, buffer);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
static void
|
|
Packit |
df99a1 |
fmt_convert_row(unsigned char *p, unsigned char g[256][4], int w,
|
|
Packit |
df99a1 |
const ddjvu_format_t *fmt, char *buf)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
const uint32_t (*r)[256] = fmt->rgb;
|
|
Packit |
df99a1 |
const uint32_t xorval = fmt->xorval;
|
|
Packit |
df99a1 |
switch(fmt->style)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
case DDJVU_FORMAT_BGR24: /* truecolor 24 bits in BGR order */
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
while (--w >= 0) {
|
|
Packit |
df99a1 |
buf[0]=g[*p][0];
|
|
Packit |
df99a1 |
buf[1]=g[*p][1];
|
|
Packit |
df99a1 |
buf[2]=g[*p][2];
|
|
Packit |
df99a1 |
buf+=3; p+=1;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
break;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
case DDJVU_FORMAT_RGB24: /* truecolor 24 bits in RGB order */
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
while (--w >= 0) {
|
|
Packit |
df99a1 |
buf[0]=g[*p][2];
|
|
Packit |
df99a1 |
buf[1]=g[*p][1];
|
|
Packit |
df99a1 |
buf[2]=g[*p][0];
|
|
Packit |
df99a1 |
buf+=3; p+=1;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
break;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
case DDJVU_FORMAT_RGBMASK16: /* truecolor 16 bits with masks */
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
uint16_t *b = (uint16_t*)buf;
|
|
Packit |
df99a1 |
while (--w >= 0) {
|
|
Packit |
df99a1 |
unsigned char x = *p;
|
|
Packit |
df99a1 |
b[0]=(r[0][g[x][2]]|r[1][g[x][1]]|r[2][g[x][0]])^xorval;
|
|
Packit |
df99a1 |
b+=1; p+=1;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
break;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
case DDJVU_FORMAT_RGBMASK32: /* truecolor 32 bits with masks */
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
uint32_t *b = (uint32_t*)buf;
|
|
Packit |
df99a1 |
while (--w >= 0) {
|
|
Packit |
df99a1 |
unsigned char x = *p;
|
|
Packit |
df99a1 |
b[0]=(r[0][g[x][2]]|r[1][g[x][1]]|r[2][g[x][0]])^xorval;
|
|
Packit |
df99a1 |
b+=1; p+=1;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
break;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
case DDJVU_FORMAT_GREY8: /* greylevel 8 bits */
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
while (--w >= 0) {
|
|
Packit |
df99a1 |
buf[0]=g[*p][3];
|
|
Packit |
df99a1 |
buf+=1; p+=1;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
break;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
case DDJVU_FORMAT_PALETTE8: /* paletized 8 bits (6x6x6 color cube) */
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
const uint32_t *u = fmt->palette;
|
|
Packit |
df99a1 |
while (--w >= 0) {
|
|
Packit |
df99a1 |
unsigned char x = *p;
|
|
Packit |
df99a1 |
buf[0] = u[r[0][g[x][0]]+r[1][g[x][1]]+r[2][g[x][2]]];
|
|
Packit |
df99a1 |
buf+=1; p+=1;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
break;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
case DDJVU_FORMAT_MSBTOLSB: /* packed bits, msb on the left */
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
int t = 5*fmt->white.r + 9*fmt->white.g + 2*fmt->white.b + 16;
|
|
Packit |
df99a1 |
t = t * 0xc / 0x100;
|
|
Packit |
df99a1 |
unsigned char s=0, m=0x80;
|
|
Packit |
df99a1 |
while (--w >= 0) {
|
|
Packit |
df99a1 |
unsigned char x = *p;
|
|
Packit |
df99a1 |
if ( g[x][3] < t ) { s |= m; }
|
|
Packit |
df99a1 |
if (! (m >>= 1)) { *buf++ = s; s=0; m=0x80; }
|
|
Packit |
df99a1 |
p += 1;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
if (m < 0x80) { *buf++ = s; }
|
|
Packit |
df99a1 |
break;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
case DDJVU_FORMAT_LSBTOMSB: /* packed bits, lsb on the left */
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
int t = 5*fmt->white.r + 9*fmt->white.g + 2*fmt->white.b + 16;
|
|
Packit |
df99a1 |
t = t * 0xc / 0x100;
|
|
Packit |
df99a1 |
unsigned char s=0, m=0x1;
|
|
Packit |
df99a1 |
while (--w >= 0) {
|
|
Packit |
df99a1 |
unsigned char x = *p;
|
|
Packit |
df99a1 |
if ( g[x][3] < t ) { s |= m; }
|
|
Packit |
df99a1 |
if (! (m <<= 1)) { *buf++ = s; s=0; m=0x1; }
|
|
Packit |
df99a1 |
p += 1;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
if (m > 0x1) { *buf++ = s; }
|
|
Packit |
df99a1 |
break;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
static void
|
|
Packit |
df99a1 |
fmt_convert(GBitmap *bm, const ddjvu_format_t *fmt, char *buffer, int rowsize)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
int w = bm->columns();
|
|
Packit |
df99a1 |
int h = bm->rows();
|
|
Packit |
df99a1 |
int m = bm->get_grays();
|
|
Packit |
df99a1 |
// Gray levels
|
|
Packit |
df99a1 |
int i;
|
|
Packit |
df99a1 |
unsigned char g[256][4];
|
|
Packit |
df99a1 |
const GPixel &wh = fmt->white;
|
|
Packit |
df99a1 |
for (i=0; i
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
g[i][0] = wh.b - ( i * wh.b + (m - 1)/2 ) / (m - 1);
|
|
Packit |
df99a1 |
g[i][1] = wh.g - ( i * wh.g + (m - 1)/2 ) / (m - 1);
|
|
Packit |
df99a1 |
g[i][2] = wh.r - ( i * wh.r + (m - 1)/2 ) / (m - 1);
|
|
Packit |
df99a1 |
g[i][3] = (5*g[i][2] + 9*g[i][1] + 2*g[i][0])>>4;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
for (i=m; i<256; i++)
|
|
Packit |
df99a1 |
g[i][0] = g[i][1] = g[i][2] = g[i][3] = 0;
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// Loop on rows
|
|
Packit |
df99a1 |
if (fmt->rtoptobottom)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
for(int r=h-1; r>=0; r--, buffer+=rowsize)
|
|
Packit |
df99a1 |
fmt_convert_row((*bm)[r], g, w, fmt, buffer);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
for(int r=0; r
|
|
Packit |
df99a1 |
fmt_convert_row((*bm)[r], g, w, fmt, buffer);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
static void
|
|
Packit |
df99a1 |
fmt_dither(GPixmap *pm, const ddjvu_format_t *fmt, int x, int y)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (fmt->ditherbits < 8)
|
|
Packit |
df99a1 |
return;
|
|
Packit |
df99a1 |
else if (fmt->ditherbits < 15)
|
|
Packit |
df99a1 |
pm->ordered_666_dither(x, y);
|
|
Packit |
df99a1 |
else if (fmt->ditherbits < 24)
|
|
Packit |
df99a1 |
pm->ordered_32k_dither(x, y);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// ----------------------------------------
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
int
|
|
Packit |
df99a1 |
ddjvu_page_render(ddjvu_page_t *page,
|
|
Packit |
df99a1 |
const ddjvu_render_mode_t mode,
|
|
Packit |
df99a1 |
const ddjvu_rect_t *pagerect,
|
|
Packit |
df99a1 |
const ddjvu_rect_t *renderrect,
|
|
Packit |
df99a1 |
const ddjvu_format_t *format,
|
|
Packit |
df99a1 |
unsigned long rowsize,
|
|
Packit |
df99a1 |
char *imagebuffer )
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<GPixmap> pm;
|
|
Packit |
df99a1 |
GP<GBitmap> bm;
|
|
Packit |
df99a1 |
GRect prect, rrect;
|
|
Packit |
df99a1 |
rect2grect(pagerect, prect);
|
|
Packit |
df99a1 |
rect2grect(renderrect, rrect);
|
|
Packit |
df99a1 |
if (format && format->ytoptobottom)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
prect.ymin = renderrect->y + renderrect->h;
|
|
Packit |
df99a1 |
prect.ymax = prect.ymin + pagerect->h;
|
|
Packit |
df99a1 |
rrect.ymin = pagerect->y + pagerect->h;
|
|
Packit |
df99a1 |
rrect.ymax = rrect.ymin + renderrect->h;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
DjVuImage *img = page->img;
|
|
Packit |
df99a1 |
if (img)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
switch (mode)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
case DDJVU_RENDER_COLOR:
|
|
Packit |
df99a1 |
pm = img->get_pixmap(rrect,prect, format->gamma,format->white);
|
|
Packit |
df99a1 |
if (! pm)
|
|
Packit |
df99a1 |
bm = img->get_bitmap(rrect,prect);
|
|
Packit |
df99a1 |
break;
|
|
Packit |
df99a1 |
case DDJVU_RENDER_BLACK:
|
|
Packit |
df99a1 |
bm = img->get_bitmap(rrect,prect);
|
|
Packit |
df99a1 |
if (! bm)
|
|
Packit |
df99a1 |
pm = img->get_pixmap(rrect,prect, format->gamma,format->white);
|
|
Packit |
df99a1 |
break;
|
|
Packit |
df99a1 |
case DDJVU_RENDER_MASKONLY:
|
|
Packit |
df99a1 |
bm = img->get_bitmap(rrect,prect);
|
|
Packit |
df99a1 |
break;
|
|
Packit |
df99a1 |
case DDJVU_RENDER_COLORONLY:
|
|
Packit |
df99a1 |
pm = img->get_pixmap(rrect,prect, format->gamma,format->white);
|
|
Packit |
df99a1 |
break;
|
|
Packit |
df99a1 |
case DDJVU_RENDER_BACKGROUND:
|
|
Packit |
df99a1 |
pm = img->get_bg_pixmap(rrect,prect, format->gamma,format->white);
|
|
Packit |
df99a1 |
break;
|
|
Packit |
df99a1 |
case DDJVU_RENDER_FOREGROUND:
|
|
Packit |
df99a1 |
pm = img->get_fg_pixmap(rrect,prect, format->gamma,format->white);
|
|
Packit |
df99a1 |
if (! pm)
|
|
Packit |
df99a1 |
bm = img->get_bitmap(rrect,prect);
|
|
Packit |
df99a1 |
break;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
if (pm)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
int dx = rrect.xmin - prect.xmin;
|
|
Packit |
df99a1 |
int dy = rrect.ymin - prect.xmin;
|
|
Packit |
df99a1 |
fmt_dither(pm, format, dx, dy);
|
|
Packit |
df99a1 |
fmt_convert(pm, format, imagebuffer, rowsize);
|
|
Packit |
df99a1 |
return 2;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else if (bm)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
fmt_convert(bm, format, imagebuffer, rowsize);
|
|
Packit |
df99a1 |
return 1;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH(ex)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ERROR1(page, ex);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// ----------------------------------------
|
|
Packit |
df99a1 |
// Thumbnails
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
ddjvu_thumbnail_p::callback(void *cldata)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ddjvu_thumbnail_p *thumb = (ddjvu_thumbnail_p*)cldata;
|
|
Packit |
df99a1 |
if (thumb->document)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GMonitorLock lock(&thumb->document->monitor);
|
|
Packit |
df99a1 |
if (thumb->pool && thumb->pool->is_eof())
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<DataPool> pool = thumb->pool;
|
|
Packit |
df99a1 |
int size = pool->get_size();
|
|
Packit |
df99a1 |
thumb->pool = 0;
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
thumb->data.resize(0,size-1);
|
|
Packit |
df99a1 |
pool->get_data( (void*)(char*)thumb->data, 0, size);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH_ALL
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
thumb->data.empty();
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
if (thumb->document->doc)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<ddjvu_message_p> p = new ddjvu_message_p;
|
|
Packit |
df99a1 |
p->p.m_thumbnail.pagenum = thumb->pagenum;
|
|
Packit |
df99a1 |
msg_push(xhead(DDJVU_THUMBNAIL, thumb->document), p);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
ddjvu_status_t
|
|
Packit |
df99a1 |
ddjvu_thumbnail_status(ddjvu_document_t *document, int pagenum, int start)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<ddjvu_thumbnail_p> thumb;
|
|
Packit |
df99a1 |
DjVuDocument* doc = document->doc;
|
|
Packit |
df99a1 |
if (doc)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GMonitorLock lock(&document->monitor);
|
|
Packit |
df99a1 |
GPosition p = document->thumbnails.contains(pagenum);
|
|
Packit |
df99a1 |
if (p)
|
|
Packit |
df99a1 |
thumb = document->thumbnails[p];
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
if (!thumb && doc)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<DataPool> pool = doc->get_thumbnail(pagenum, !start);
|
|
Packit |
df99a1 |
if (pool)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GMonitorLock lock(&document->monitor);
|
|
Packit |
df99a1 |
thumb = new ddjvu_thumbnail_p;
|
|
Packit |
df99a1 |
thumb->document = document;
|
|
Packit |
df99a1 |
thumb->pagenum = pagenum;
|
|
Packit |
df99a1 |
thumb->pool = pool;
|
|
Packit |
df99a1 |
document->thumbnails[pagenum] = thumb;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
if (thumb)
|
|
Packit |
df99a1 |
pool->add_trigger(-1, ddjvu_thumbnail_p::callback,
|
|
Packit |
df99a1 |
(void*)(ddjvu_thumbnail_p*)thumb);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
if (! thumb)
|
|
Packit |
df99a1 |
return DDJVU_JOB_NOTSTARTED;
|
|
Packit |
df99a1 |
else if (thumb->pool)
|
|
Packit |
df99a1 |
return DDJVU_JOB_STARTED;
|
|
Packit |
df99a1 |
else if (thumb->data.size() > 0)
|
|
Packit |
df99a1 |
return DDJVU_JOB_OK;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH(ex)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ERROR1(document, ex);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
return DDJVU_JOB_FAILED;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
int
|
|
Packit |
df99a1 |
ddjvu_thumbnail_render(ddjvu_document_t *document, int pagenum,
|
|
Packit |
df99a1 |
int *wptr, int *hptr,
|
|
Packit |
df99a1 |
const ddjvu_format_t *format,
|
|
Packit |
df99a1 |
unsigned long rowsize,
|
|
Packit |
df99a1 |
char *imagebuffer)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<ddjvu_thumbnail_p> thumb;
|
|
Packit |
df99a1 |
ddjvu_status_t status = ddjvu_thumbnail_status(document,pagenum,FALSE);
|
|
Packit |
df99a1 |
if (status == DDJVU_JOB_OK)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GMonitorLock lock(&document->monitor);
|
|
Packit |
df99a1 |
thumb = document->thumbnails[pagenum];
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
if (! (thumb && wptr && hptr))
|
|
Packit |
df99a1 |
return FALSE;
|
|
Packit |
df99a1 |
if (! (thumb->data.size() > 0))
|
|
Packit |
df99a1 |
return FALSE;
|
|
Packit |
df99a1 |
/* Decode wavelet data */
|
|
Packit |
df99a1 |
int size = thumb->data.size();
|
|
Packit |
df99a1 |
char *data = (char*)thumb->data;
|
|
Packit |
df99a1 |
GP<IW44Image> iw = IW44Image::create_decode();
|
|
Packit |
df99a1 |
iw->decode_chunk(ByteStream::create_static((void*)data, size));
|
|
Packit |
df99a1 |
int w = iw->get_width();
|
|
Packit |
df99a1 |
int h = iw->get_height();
|
|
Packit |
df99a1 |
/* Restore aspect ratio */
|
|
Packit |
df99a1 |
double dw = (double)w / *wptr;
|
|
Packit |
df99a1 |
double dh = (double)h / *hptr;
|
|
Packit |
df99a1 |
if (dw > dh)
|
|
Packit |
df99a1 |
*hptr = (int)(h / dw);
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
*wptr = (int)(w / dh);
|
|
Packit |
df99a1 |
if (! imagebuffer)
|
|
Packit |
df99a1 |
return TRUE;
|
|
Packit |
df99a1 |
/* Render and scale image */
|
|
Packit |
df99a1 |
GP<GPixmap> pm = iw->get_pixmap();
|
|
Packit |
df99a1 |
double thumbgamma = document->doc->get_thumbnails_gamma();
|
|
Packit |
df99a1 |
pm->color_correct(format->gamma/thumbgamma, format->white);
|
|
Packit |
df99a1 |
GP<GPixmapScaler> scaler = GPixmapScaler::create(w, h, *wptr, *hptr);
|
|
Packit |
df99a1 |
GP<GPixmap> scaledpm = GPixmap::create();
|
|
Packit |
df99a1 |
GRect scaledrect(0, 0, *wptr, *hptr);
|
|
Packit |
df99a1 |
scaler->scale(GRect(0, 0, w, h), *pm, scaledrect, *scaledpm);
|
|
Packit |
df99a1 |
/* Convert */
|
|
Packit |
df99a1 |
fmt_dither(scaledpm, format, 0, 0);
|
|
Packit |
df99a1 |
fmt_convert(scaledpm, format, imagebuffer, rowsize);
|
|
Packit |
df99a1 |
return TRUE;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH(ex)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ERROR1(document, ex);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
return FALSE;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// ----------------------------------------
|
|
Packit |
df99a1 |
// Threaded jobs
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
struct DJVUNS ddjvu_runnablejob_s : public ddjvu_job_s
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
bool mystop;
|
|
Packit |
df99a1 |
int myprogress;
|
|
Packit |
df99a1 |
ddjvu_status_t mystatus;
|
|
Packit |
df99a1 |
// methods
|
|
Packit |
df99a1 |
ddjvu_runnablejob_s();
|
|
Packit |
df99a1 |
ddjvu_status_t start();
|
|
Packit |
df99a1 |
void progress(int p);
|
|
Packit |
df99a1 |
// thread function
|
|
Packit |
df99a1 |
virtual ddjvu_status_t run() = 0;
|
|
Packit |
df99a1 |
// virtual port functions:
|
|
Packit |
df99a1 |
virtual bool inherits(const GUTF8String&) const;
|
|
Packit |
df99a1 |
virtual ddjvu_status_t status();
|
|
Packit |
df99a1 |
virtual void stop();
|
|
Packit |
df99a1 |
private:
|
|
Packit |
df99a1 |
static void cbstart(void*);
|
|
Packit |
df99a1 |
};
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
ddjvu_runnablejob_s::ddjvu_runnablejob_s()
|
|
Packit |
df99a1 |
: mystop(false), myprogress(-1),
|
|
Packit |
df99a1 |
mystatus(DDJVU_JOB_NOTSTARTED)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
ddjvu_runnablejob_s::progress(int x)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if ((mystatus>=DDJVU_JOB_OK) || (x>myprogress && x<100))
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GMonitorLock lock(&monitor);
|
|
Packit |
df99a1 |
GP<ddjvu_message_p> p = new ddjvu_message_p;
|
|
Packit |
df99a1 |
p->p.m_progress.status = mystatus;
|
|
Packit |
df99a1 |
p->p.m_progress.percent = myprogress = x;
|
|
Packit |
df99a1 |
msg_push(xhead(DDJVU_PROGRESS,this),p);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
ddjvu_status_t
|
|
Packit |
df99a1 |
ddjvu_runnablejob_s::start()
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GMonitorLock lock(&monitor);
|
|
Packit |
df99a1 |
if (mystatus==DDJVU_JOB_NOTSTARTED && myctx)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GThread thr;
|
|
Packit |
df99a1 |
thr.create(cbstart, (void*)this);
|
|
Packit |
df99a1 |
monitor.wait();
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
return mystatus;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
ddjvu_runnablejob_s::cbstart(void *arg)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<ddjvu_runnablejob_s> self = (ddjvu_runnablejob_s*)arg;
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GMonitorLock lock(&self->monitor);
|
|
Packit |
df99a1 |
self->mystatus = DDJVU_JOB_STARTED;
|
|
Packit |
df99a1 |
self->monitor.signal();
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
ddjvu_status_t r;
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
self->progress(0);
|
|
Packit |
df99a1 |
r = self->run();
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH(ex)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ERROR1(self, ex);
|
|
Packit |
df99a1 |
G_RETHROW;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH_ALL
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
r = DDJVU_JOB_FAILED;
|
|
Packit |
df99a1 |
if (self && self->mystop)
|
|
Packit |
df99a1 |
r = DDJVU_JOB_STOPPED;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GMonitorLock lock(&self->monitor);
|
|
Packit |
df99a1 |
self->mystatus = r;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
if (self && self->mystatus> DDJVU_JOB_OK)
|
|
Packit |
df99a1 |
self->progress(self->myprogress);
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
self->progress(100);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
bool
|
|
Packit |
df99a1 |
ddjvu_runnablejob_s::inherits(const GUTF8String &classname) const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
return (classname == "ddjvu_runnablejob_s")
|
|
Packit |
df99a1 |
|| ddjvu_job_s::inherits(classname);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
ddjvu_status_t
|
|
Packit |
df99a1 |
ddjvu_runnablejob_s::status()
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
return mystatus;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
ddjvu_runnablejob_s::stop()
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
mystop = true;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// ----------------------------------------
|
|
Packit |
df99a1 |
// Printing
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
struct DJVUNS ddjvu_printjob_s : public ddjvu_runnablejob_s
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
DjVuToPS printer;
|
|
Packit |
df99a1 |
GUTF8String pages;
|
|
Packit |
df99a1 |
GP<ByteStream> obs;
|
|
Packit |
df99a1 |
virtual ddjvu_status_t run();
|
|
Packit |
df99a1 |
// virtual port functions:
|
|
Packit |
df99a1 |
virtual bool inherits(const GUTF8String&) const;
|
|
Packit |
df99a1 |
// progress
|
|
Packit |
df99a1 |
static void cbrefresh(void*);
|
|
Packit |
df99a1 |
static void cbprogress(double, void*);
|
|
Packit |
df99a1 |
static void cbinfo(int, int, int, DjVuToPS::Stage, void*);
|
|
Packit |
df99a1 |
double progress_low;
|
|
Packit |
df99a1 |
double progress_high;
|
|
Packit |
df99a1 |
};
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
bool
|
|
Packit |
df99a1 |
ddjvu_printjob_s::inherits(const GUTF8String &classname) const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
return (classname == "ddjvu_printjob_s")
|
|
Packit |
df99a1 |
|| ddjvu_runnablejob_s::inherits(classname);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
ddjvu_status_t
|
|
Packit |
df99a1 |
ddjvu_printjob_s::run()
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
mydoc->doc->wait_for_complete_init();
|
|
Packit |
df99a1 |
progress_low = 0;
|
|
Packit |
df99a1 |
progress_high = 1;
|
|
Packit |
df99a1 |
printer.set_refresh_cb(cbrefresh, (void*)this);
|
|
Packit |
df99a1 |
printer.set_dec_progress_cb(cbprogress, (void*)this);
|
|
Packit |
df99a1 |
printer.set_prn_progress_cb(cbprogress, (void*)this);
|
|
Packit |
df99a1 |
printer.set_info_cb(cbinfo, (void*)this);
|
|
Packit |
df99a1 |
printer.print(*obs, mydoc->doc, pages);
|
|
Packit |
df99a1 |
return DDJVU_JOB_OK;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
ddjvu_printjob_s::cbrefresh(void *data)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ddjvu_printjob_s *self = (ddjvu_printjob_s*)data;
|
|
Packit |
df99a1 |
if (self->mystop)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
msg_push(xhead(DDJVU_INFO,self), msg_prep_info("Print job stopped"));
|
|
Packit |
df99a1 |
G_THROW(DataPool::Stop);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
ddjvu_printjob_s::cbprogress(double done, void *data)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ddjvu_printjob_s *self = (ddjvu_printjob_s*)data;
|
|
Packit |
df99a1 |
double &low = self->progress_low;
|
|
Packit |
df99a1 |
double &high = self->progress_high;
|
|
Packit |
df99a1 |
double progress = low;
|
|
Packit |
df99a1 |
if (done >= 1)
|
|
Packit |
df99a1 |
progress = high;
|
|
Packit |
df99a1 |
else if (done >= 0)
|
|
Packit |
df99a1 |
progress = low + done * (high-low);
|
|
Packit |
df99a1 |
self->progress((int)(progress * 100));
|
|
Packit |
df99a1 |
ddjvu_printjob_s::cbrefresh(data);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
ddjvu_printjob_s::cbinfo(int pnum, int pcnt, int ptot,
|
|
Packit |
df99a1 |
DjVuToPS::Stage stage, void *data)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ddjvu_printjob_s *self = (ddjvu_printjob_s*)data;
|
|
Packit |
df99a1 |
double &low = self->progress_low;
|
|
Packit |
df99a1 |
double &high = self->progress_high;
|
|
Packit |
df99a1 |
low = 0;
|
|
Packit |
df99a1 |
high = 1;
|
|
Packit |
df99a1 |
if (ptot > 0)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
double step = 1.0 / (double)ptot;
|
|
Packit |
df99a1 |
low = (double)pcnt * step;
|
|
Packit |
df99a1 |
if (stage != DjVuToPS::DECODING)
|
|
Packit |
df99a1 |
low += step / 2.0;
|
|
Packit |
df99a1 |
high = low + step / 2.0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
if (low < 0)
|
|
Packit |
df99a1 |
low = 0;
|
|
Packit |
df99a1 |
if (low > 1)
|
|
Packit |
df99a1 |
low = 1;
|
|
Packit |
df99a1 |
if (high < low)
|
|
Packit |
df99a1 |
high = low;
|
|
Packit |
df99a1 |
if (high > 1)
|
|
Packit |
df99a1 |
high = 1;
|
|
Packit |
df99a1 |
self->progress((int)(low * 100));
|
|
Packit |
df99a1 |
ddjvu_printjob_s::cbrefresh(data);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
static void
|
|
Packit |
df99a1 |
complain(GUTF8String opt, const char *msg)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GUTF8String message;
|
|
Packit |
df99a1 |
if (opt.length() > 0)
|
|
Packit |
df99a1 |
message = "Parsing \"" + opt + "\": " + msg;
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
message = msg;
|
|
Packit |
df99a1 |
G_RETHROW(GException((const char*)message));
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
ddjvu_job_t *
|
|
Packit |
df99a1 |
ddjvu_document_print(ddjvu_document_t *document, FILE *output,
|
|
Packit |
df99a1 |
int optc, const char * const * optv)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ddjvu_printjob_s *job = 0;
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
job = new ddjvu_printjob_s;
|
|
Packit |
df99a1 |
ref(job);
|
|
Packit |
df99a1 |
job->myctx = document->myctx;
|
|
Packit |
df99a1 |
job->mydoc = document;
|
|
Packit |
df99a1 |
// parse options (see djvups(1))
|
|
Packit |
df99a1 |
DjVuToPS::Options &options = job->printer.options;
|
|
Packit |
df99a1 |
GUTF8String &pages = job->pages;
|
|
Packit |
df99a1 |
while (optc>0)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
// normalize
|
|
Packit |
df99a1 |
GNativeString narg(optv[0]);
|
|
Packit |
df99a1 |
GUTF8String uarg = narg;
|
|
Packit |
df99a1 |
const char *s1 = (const char*)narg;
|
|
Packit |
df99a1 |
if (s1[0] == '-') s1++;
|
|
Packit |
df99a1 |
if (s1[0] == '-') s1++;
|
|
Packit |
df99a1 |
// separate arguments
|
|
Packit |
df99a1 |
const char *s2 = s1;
|
|
Packit |
df99a1 |
while (*s2 && *s2 != '=') s2++;
|
|
Packit |
df99a1 |
GUTF8String s( s1, s2-s1 );
|
|
Packit |
df99a1 |
GUTF8String arg( s2[0] && s2[1] ? s2+1 : "" );
|
|
Packit |
df99a1 |
// rumble!
|
|
Packit |
df99a1 |
if (s == "page" || s == "pages")
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (pages.length())
|
|
Packit |
df99a1 |
pages = pages + ",";
|
|
Packit |
df99a1 |
pages = pages + arg;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else if (s == "format")
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (arg == "ps")
|
|
Packit |
df99a1 |
options.set_format(DjVuToPS::Options::PS);
|
|
Packit |
df99a1 |
else if (arg == "eps")
|
|
Packit |
df99a1 |
options.set_format(DjVuToPS::Options::EPS);
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
complain(uarg,"Invalid format. Use \"ps\" or \"eps\".");
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else if (s == "level")
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
int endpos;
|
|
Packit |
df99a1 |
int lvl = arg.toLong(0, endpos);
|
|
Packit |
df99a1 |
if (endpos != (int)arg.length() || lvl < 1 || lvl > 4)
|
|
Packit |
df99a1 |
complain(uarg,"Invalid Postscript language level.");
|
|
Packit |
df99a1 |
options.set_level(lvl);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else if (s == "orient" || s == "orientation")
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (arg == "a" || arg == "auto" )
|
|
Packit |
df99a1 |
options.set_orientation(DjVuToPS::Options::AUTO);
|
|
Packit |
df99a1 |
else if (arg == "l" || arg == "landscape" )
|
|
Packit |
df99a1 |
options.set_orientation(DjVuToPS::Options::LANDSCAPE);
|
|
Packit |
df99a1 |
else if (arg == "p" || arg == "portrait" )
|
|
Packit |
df99a1 |
options.set_orientation(DjVuToPS::Options::PORTRAIT);
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
complain(uarg,"Invalid orientation. Use \"auto\", "
|
|
Packit |
df99a1 |
"\"landscape\" or \"portrait\".");
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else if (s == "mode")
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (arg == "c" || arg == "color" )
|
|
Packit |
df99a1 |
options.set_mode(DjVuToPS::Options::COLOR);
|
|
Packit |
df99a1 |
else if (arg == "black" || arg == "bw")
|
|
Packit |
df99a1 |
options.set_mode(DjVuToPS::Options::BW);
|
|
Packit |
df99a1 |
else if (arg == "fore" || arg == "foreground")
|
|
Packit |
df99a1 |
options.set_mode(DjVuToPS::Options::FORE);
|
|
Packit |
df99a1 |
else if (arg == "back" || arg == "background" )
|
|
Packit |
df99a1 |
options.set_mode(DjVuToPS::Options::BACK);
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
complain(uarg,"Invalid mode. Use \"color\", \"bw\", "
|
|
Packit |
df99a1 |
"\"foreground\", or \"background\".");
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else if (s == "zoom")
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (arg == "auto" || arg == "fit" || arg == "fit_page")
|
|
Packit |
df99a1 |
options.set_zoom(0);
|
|
Packit |
df99a1 |
else if (arg == "1to1" || arg == "onetoone")
|
|
Packit |
df99a1 |
options.set_zoom(100);
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
int endpos;
|
|
Packit |
df99a1 |
int z = arg.toLong(0,endpos);
|
|
Packit |
df99a1 |
if (endpos != (int)arg.length() || z < 25 || z > 2400)
|
|
Packit |
df99a1 |
complain(uarg,"Invalid zoom factor.");
|
|
Packit |
df99a1 |
options.set_zoom(z);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else if (s == "color")
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (arg == "yes" || arg == "")
|
|
Packit |
df99a1 |
options.set_color(true);
|
|
Packit |
df99a1 |
else if (arg == "no")
|
|
Packit |
df99a1 |
options.set_color(false);
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
complain(uarg,"Invalid argument. Use \"yes\" or \"no\".");
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else if (s == "gray" || s == "grayscale")
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (arg.length())
|
|
Packit |
df99a1 |
complain(uarg,"No argument was expected.");
|
|
Packit |
df99a1 |
options.set_color(false);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else if (s == "srgb" || s == "colormatch")
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (arg == "yes" || arg == "")
|
|
Packit |
df99a1 |
options.set_sRGB(true);
|
|
Packit |
df99a1 |
else if (arg == "no")
|
|
Packit |
df99a1 |
options.set_sRGB(false);
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
complain(uarg,"Invalid argument. Use \"yes\" or \"no\".");
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else if (s == "gamma")
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
int endpos;
|
|
Packit |
df99a1 |
double g = arg.toDouble(0,endpos);
|
|
Packit |
df99a1 |
if (endpos != (int)arg.length() || g < 0.3 || g > 5.0)
|
|
Packit |
df99a1 |
complain(uarg,"Invalid gamma factor. "
|
|
Packit |
df99a1 |
"Use a number in range 0.3 ... 5.0.");
|
|
Packit |
df99a1 |
options.set_gamma(g);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else if (s == "copies")
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
int endpos;
|
|
Packit |
df99a1 |
int n = arg.toLong(0, endpos);
|
|
Packit |
df99a1 |
if (endpos != (int)arg.length() || n < 1 || n > 999999)
|
|
Packit |
df99a1 |
complain(uarg,"Invalid number of copies.");
|
|
Packit |
df99a1 |
options.set_copies(n);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else if (s == "frame")
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (arg == "yes" || arg == "")
|
|
Packit |
df99a1 |
options.set_frame(true);
|
|
Packit |
df99a1 |
else if (arg == "no")
|
|
Packit |
df99a1 |
options.set_frame(false);
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
complain(uarg,"Invalid argument. Use \"yes\" or \"no\".");
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else if (s == "cropmarks")
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (arg == "yes" || arg == "")
|
|
Packit |
df99a1 |
options.set_cropmarks(true);
|
|
Packit |
df99a1 |
else if (arg == "no")
|
|
Packit |
df99a1 |
options.set_cropmarks(false);
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
complain(uarg,"Invalid argument. Use \"yes\" or \"no\".");
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else if (s == "text")
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (arg == "yes" || arg == "")
|
|
Packit |
df99a1 |
options.set_text(true);
|
|
Packit |
df99a1 |
else if (arg == "no")
|
|
Packit |
df99a1 |
options.set_text(false);
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
complain(uarg,"Invalid argument. Use \"yes\" or \"no\".");
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else if (s == "booklet")
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (arg == "no")
|
|
Packit |
df99a1 |
options.set_bookletmode(DjVuToPS::Options::OFF);
|
|
Packit |
df99a1 |
else if (arg == "recto")
|
|
Packit |
df99a1 |
options.set_bookletmode(DjVuToPS::Options::RECTO);
|
|
Packit |
df99a1 |
else if (arg == "verso")
|
|
Packit |
df99a1 |
options.set_bookletmode(DjVuToPS::Options::VERSO);
|
|
Packit |
df99a1 |
else if (arg == "rectoverso" || arg=="yes" || arg=="")
|
|
Packit |
df99a1 |
options.set_bookletmode(DjVuToPS::Options::RECTOVERSO);
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
complain(uarg,"Invalid argument."
|
|
Packit |
df99a1 |
"Use \"no\", \"yes\", \"recto\", or \"verso\".");
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else if (s == "bookletmax")
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
int endpos;
|
|
Packit |
df99a1 |
int n = arg.toLong(0, endpos);
|
|
Packit |
df99a1 |
if (endpos != (int)arg.length() || n < 0 || n > 999999)
|
|
Packit |
df99a1 |
complain(uarg,"Invalid argument.");
|
|
Packit |
df99a1 |
options.set_bookletmax(n);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else if (s == "bookletalign")
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
int endpos;
|
|
Packit |
df99a1 |
int n = arg.toLong(0, endpos);
|
|
Packit |
df99a1 |
if (endpos != (int)arg.length() || n < -720 || n > +720)
|
|
Packit |
df99a1 |
complain(uarg,"Invalid argument.");
|
|
Packit |
df99a1 |
options.set_bookletalign(n);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else if (s == "bookletfold")
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
int endpos = 0;
|
|
Packit |
df99a1 |
int m = 250;
|
|
Packit |
df99a1 |
int n = arg.toLong(0, endpos);
|
|
Packit |
df99a1 |
if (endpos>0 && endpos<(int)arg.length() && arg[endpos]=='+')
|
|
Packit |
df99a1 |
m = arg.toLong(endpos+1, endpos);
|
|
Packit |
df99a1 |
if (endpos != (int)arg.length() || m<0 || m>720 || n<0 || n>9999 )
|
|
Packit |
df99a1 |
complain(uarg,"Invalid argument.");
|
|
Packit |
df99a1 |
options.set_bookletfold(n,m);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
complain(uarg, "Unrecognized option.");
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
// Next option
|
|
Packit |
df99a1 |
optc -= 1;
|
|
Packit |
df99a1 |
optv += 1;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
// go
|
|
Packit |
df99a1 |
job->obs = ByteStream::create(output, "wb", false);
|
|
Packit |
df99a1 |
job->start();
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH(ex)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (job)
|
|
Packit |
df99a1 |
unref(job);
|
|
Packit |
df99a1 |
job = 0;
|
|
Packit |
df99a1 |
ERROR1(document, ex);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
return job;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// ----------------------------------------
|
|
Packit |
df99a1 |
// Saving
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
struct DJVUNS ddjvu_savejob_s : public ddjvu_runnablejob_s
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<ByteStream> obs;
|
|
Packit |
df99a1 |
GURL odir;
|
|
Packit |
df99a1 |
GUTF8String oname;
|
|
Packit |
df99a1 |
GUTF8String pages;
|
|
Packit |
df99a1 |
GTArray<char> comp_flags;
|
|
Packit |
df99a1 |
GArray<GUTF8String> comp_ids;
|
|
Packit |
df99a1 |
GPArray<DjVuFile> comp_files;
|
|
Packit |
df99a1 |
GMonitor monitor;
|
|
Packit |
df99a1 |
// thread routine
|
|
Packit |
df99a1 |
virtual ddjvu_status_t run();
|
|
Packit |
df99a1 |
// virtual port functions:
|
|
Packit |
df99a1 |
virtual bool inherits(const GUTF8String&) const;
|
|
Packit |
df99a1 |
virtual void notify_file_flags_changed(const DjVuFile*, long, long);
|
|
Packit |
df99a1 |
// helpers
|
|
Packit |
df99a1 |
bool parse_pagespec(const char *s, int npages, bool *flags);
|
|
Packit |
df99a1 |
void mark_included_files(DjVuFile *file);
|
|
Packit |
df99a1 |
};
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
bool
|
|
Packit |
df99a1 |
ddjvu_savejob_s::inherits(const GUTF8String &classname) const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
return (classname == "ddjvu_savejob_s")
|
|
Packit |
df99a1 |
|| ddjvu_runnablejob_s::inherits(classname);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
ddjvu_savejob_s::notify_file_flags_changed(const DjVuFile *file,
|
|
Packit |
df99a1 |
long mask, long)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (mask & (DjVuFile::ALL_DATA_PRESENT | DjVuFile::DATA_PRESENT |
|
|
Packit |
df99a1 |
DjVuFile::DECODE_FAILED | DjVuFile::DECODE_STOPPED |
|
|
Packit |
df99a1 |
DjVuFile::STOPPED ))
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GMonitorLock lock(&monitor);
|
|
Packit |
df99a1 |
monitor.signal();
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
bool
|
|
Packit |
df99a1 |
ddjvu_savejob_s::parse_pagespec(const char *s, int npages, bool *flags)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
int spec = 0;
|
|
Packit |
df99a1 |
int both = 1;
|
|
Packit |
df99a1 |
int start_page = 1;
|
|
Packit |
df99a1 |
int end_page = npages;
|
|
Packit |
df99a1 |
int pageno;
|
|
Packit |
df99a1 |
char *p = (char*)s;
|
|
Packit |
df99a1 |
while (*p)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
spec = 0;
|
|
Packit |
df99a1 |
while (*p==' ')
|
|
Packit |
df99a1 |
p += 1;
|
|
Packit |
df99a1 |
if (! *p)
|
|
Packit |
df99a1 |
break;
|
|
Packit |
df99a1 |
if (*p>='0' && *p<='9') {
|
|
Packit |
df99a1 |
end_page = strtol(p, &p, 10);
|
|
Packit |
df99a1 |
spec = 1;
|
|
Packit |
df99a1 |
} else if (*p=='$') {
|
|
Packit |
df99a1 |
spec = 1;
|
|
Packit |
df99a1 |
end_page = npages;
|
|
Packit |
df99a1 |
p += 1;
|
|
Packit |
df99a1 |
} else if (both) {
|
|
Packit |
df99a1 |
end_page = 1;
|
|
Packit |
df99a1 |
} else {
|
|
Packit |
df99a1 |
end_page = npages;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
while (*p==' ')
|
|
Packit |
df99a1 |
p += 1;
|
|
Packit |
df99a1 |
if (both) {
|
|
Packit |
df99a1 |
start_page = end_page;
|
|
Packit |
df99a1 |
if (*p == '-') {
|
|
Packit |
df99a1 |
p += 1;
|
|
Packit |
df99a1 |
both = 0;
|
|
Packit |
df99a1 |
continue;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
both = 1;
|
|
Packit |
df99a1 |
while (*p==' ')
|
|
Packit |
df99a1 |
p += 1;
|
|
Packit |
df99a1 |
if (*p && *p != ',')
|
|
Packit |
df99a1 |
return false;
|
|
Packit |
df99a1 |
if (*p == ',')
|
|
Packit |
df99a1 |
p += 1;
|
|
Packit |
df99a1 |
if (! spec)
|
|
Packit |
df99a1 |
return false;
|
|
Packit |
df99a1 |
if (end_page <= 0)
|
|
Packit |
df99a1 |
end_page = 1;
|
|
Packit |
df99a1 |
if (start_page <= 0)
|
|
Packit |
df99a1 |
start_page = 1;
|
|
Packit |
df99a1 |
if (end_page > npages)
|
|
Packit |
df99a1 |
end_page = npages;
|
|
Packit |
df99a1 |
if (start_page > npages)
|
|
Packit |
df99a1 |
start_page = npages;
|
|
Packit |
df99a1 |
if (start_page <= end_page)
|
|
Packit |
df99a1 |
for(pageno=start_page; pageno<=end_page; pageno++)
|
|
Packit |
df99a1 |
flags[pageno-1] = true;
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
for(pageno=start_page; pageno>=end_page; pageno--)
|
|
Packit |
df99a1 |
flags[pageno-1] = true;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
if (!spec)
|
|
Packit |
df99a1 |
return false;
|
|
Packit |
df99a1 |
return true;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
ddjvu_savejob_s::mark_included_files(DjVuFile *file)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<DataPool> pool = file->get_init_data_pool();
|
|
Packit |
df99a1 |
GP<ByteStream> str(pool->get_stream());
|
|
Packit |
df99a1 |
GP<IFFByteStream> iff(IFFByteStream::create(str));
|
|
Packit |
df99a1 |
GUTF8String chkid;
|
|
Packit |
df99a1 |
if (!iff->get_chunk(chkid))
|
|
Packit |
df99a1 |
return;
|
|
Packit |
df99a1 |
while (iff->get_chunk(chkid))
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (chkid == "INCL")
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<ByteStream> incl = iff->get_bytestream();
|
|
Packit |
df99a1 |
GUTF8String fileid;
|
|
Packit |
df99a1 |
char buffer[1024];
|
|
Packit |
df99a1 |
int length;
|
|
Packit |
df99a1 |
while((length=incl->read(buffer, 1024)))
|
|
Packit |
df99a1 |
fileid += GUTF8String(buffer, length);
|
|
Packit |
df99a1 |
for (int i=0; i
|
|
Packit |
df99a1 |
if (fileid == comp_ids[i] && !comp_flags[i])
|
|
Packit |
df99a1 |
comp_flags[i] = 1;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
iff->close_chunk();
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
iff->close_chunk();
|
|
Packit |
df99a1 |
pool->clear_stream();
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
ddjvu_status_t
|
|
Packit |
df99a1 |
ddjvu_savejob_s::run()
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
DjVuDocument *doc = mydoc->doc;
|
|
Packit |
df99a1 |
doc->wait_for_complete_init();
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// Determine which pages to save
|
|
Packit |
df99a1 |
int npages = doc->get_pages_num();
|
|
Packit |
df99a1 |
GTArray<bool> page_flags(0, npages-1);
|
|
Packit |
df99a1 |
if (!pages)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
for (int pageno=0; pageno
|
|
Packit |
df99a1 |
page_flags[pageno] = true;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
const char *s = pages;
|
|
Packit |
df99a1 |
while (*s && *s!='=')
|
|
Packit |
df99a1 |
s += 1;
|
|
Packit |
df99a1 |
for (int pageno=0; pageno
|
|
Packit |
df99a1 |
page_flags[pageno] = false;
|
|
Packit |
df99a1 |
if ((*s != '=') || !parse_pagespec(s+1, npages, (bool*)page_flags))
|
|
Packit |
df99a1 |
complain(pages,"Illegal page specification");
|
|
Packit |
df99a1 |
if (doc->get_doc_type()==DjVuDocument::OLD_BUNDLED ||
|
|
Packit |
df99a1 |
doc->get_doc_type()==DjVuDocument::OLD_INDEXED )
|
|
Packit |
df99a1 |
complain(pages,"Saving subsets of obsolete formats is not supported");
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// Determine which component files to save
|
|
Packit |
df99a1 |
int ncomps;
|
|
Packit |
df99a1 |
if (doc->get_doc_type()==DjVuDocument::BUNDLED ||
|
|
Packit |
df99a1 |
doc->get_doc_type()==DjVuDocument::INDIRECT)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<DjVmDir> dir = doc->get_djvm_dir();
|
|
Packit |
df99a1 |
ncomps = dir->get_files_num();
|
|
Packit |
df99a1 |
comp_ids.resize(ncomps - 1);
|
|
Packit |
df99a1 |
comp_flags.resize(ncomps - 1);
|
|
Packit |
df99a1 |
comp_files.resize(ncomps - 1);
|
|
Packit |
df99a1 |
int pageno = 0;
|
|
Packit |
df99a1 |
GPList<DjVmDir::File> flist = dir->get_files_list();
|
|
Packit |
df99a1 |
GPosition pos=flist;
|
|
Packit |
df99a1 |
for (int comp=0; comp
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
DjVmDir::File *file = flist[pos];
|
|
Packit |
df99a1 |
comp_ids[comp] = file->get_load_name();
|
|
Packit |
df99a1 |
comp_flags[comp] = 0;
|
|
Packit |
df99a1 |
if (file->is_page() && page_flags[pageno++])
|
|
Packit |
df99a1 |
comp_flags[comp] = 1;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ncomps = npages;
|
|
Packit |
df99a1 |
comp_flags.resize(ncomps - 1);
|
|
Packit |
df99a1 |
comp_files.resize(ncomps - 1);
|
|
Packit |
df99a1 |
for (int comp=0; comp
|
|
Packit |
df99a1 |
comp_flags[comp] = page_flags[comp];
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// Download
|
|
Packit |
df99a1 |
get_portcaster()->add_route(doc, this);
|
|
Packit |
df99a1 |
while (!mystop)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
int comp;
|
|
Packit |
df99a1 |
int wanted = 0;
|
|
Packit |
df99a1 |
int loaded = 0;
|
|
Packit |
df99a1 |
int asked = 0;
|
|
Packit |
df99a1 |
for (comp=0; comp
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
int flags = comp_flags[comp];
|
|
Packit |
df99a1 |
if (flags > 2)
|
|
Packit |
df99a1 |
loaded += 1;
|
|
Packit |
df99a1 |
else if (flags < 2)
|
|
Packit |
df99a1 |
continue;
|
|
Packit |
df99a1 |
else if (!comp_files[comp]->is_data_present())
|
|
Packit |
df99a1 |
asked += 1;
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
comp_flags[comp] += 1;
|
|
Packit |
df99a1 |
mark_included_files(comp_files[comp]);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
for (comp=0; comp
|
|
Packit |
df99a1 |
if (comp_flags[comp] > 0)
|
|
Packit |
df99a1 |
wanted += 1;
|
|
Packit |
df99a1 |
progress(loaded * 100 / wanted);
|
|
Packit |
df99a1 |
if (wanted == loaded)
|
|
Packit |
df99a1 |
break;
|
|
Packit |
df99a1 |
for (comp=0; comp
|
|
Packit |
df99a1 |
if (comp_flags[comp] == 1)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (comp_ids.size() > 0)
|
|
Packit |
df99a1 |
comp_files[comp] = doc->get_djvu_file(comp_ids[comp]);
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
comp_files[comp] = doc->get_djvu_file(comp);
|
|
Packit |
df99a1 |
comp_flags[comp] += 1;
|
|
Packit |
df99a1 |
if (!comp_files[comp]->is_data_present())
|
|
Packit |
df99a1 |
asked += 1;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
GMonitorLock lock(&monitor);
|
|
Packit |
df99a1 |
for (comp=0; comp
|
|
Packit |
df99a1 |
if (comp_flags[comp] == 2)
|
|
Packit |
df99a1 |
if (! comp_files[comp]->is_data_present())
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
monitor.wait();
|
|
Packit |
df99a1 |
break;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
if (mystop)
|
|
Packit |
df99a1 |
G_THROW(DataPool::Stop);
|
|
Packit |
df99a1 |
// Saving!
|
|
Packit |
df99a1 |
GP<DjVmDoc> djvm;
|
|
Packit |
df99a1 |
if (! pages)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
djvm = doc->get_djvm_doc();
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
djvm = DjVmDoc::create();
|
|
Packit |
df99a1 |
GP<DjVmDir> dir = doc->get_djvm_dir();
|
|
Packit |
df99a1 |
GPList<DjVmDir::File> flist = dir->get_files_list();
|
|
Packit |
df99a1 |
GPosition pos=flist;
|
|
Packit |
df99a1 |
int pageno = 0;
|
|
Packit |
df99a1 |
for (int comp=0; comp
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (flist[pos]->is_page())
|
|
Packit |
df99a1 |
pageno += 1;
|
|
Packit |
df99a1 |
if (comp_flags[comp])
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<DjVmDir::File> f = new DjVmDir::File(*flist[pos]);
|
|
Packit |
df99a1 |
if (f->is_page() && f->get_save_name()==f->get_title())
|
|
Packit |
df99a1 |
f->set_title(GUTF8String(pageno));
|
|
Packit |
df99a1 |
GP<DjVuFile> file = comp_files[comp];
|
|
Packit |
df99a1 |
GP<DataPool> data = file->get_init_data_pool();
|
|
Packit |
df99a1 |
djvm->insert_file(f, data);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
if (obs)
|
|
Packit |
df99a1 |
djvm->write(obs);
|
|
Packit |
df99a1 |
else if (odir.is_valid() && oname.length() > 0)
|
|
Packit |
df99a1 |
djvm->expand(odir, oname);
|
|
Packit |
df99a1 |
return DDJVU_JOB_OK;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
ddjvu_job_t *
|
|
Packit |
df99a1 |
ddjvu_document_save(ddjvu_document_t *document, FILE *output,
|
|
Packit |
df99a1 |
int optc, const char * const * optv)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ddjvu_savejob_s *job = 0;
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
job = new ddjvu_savejob_s;
|
|
Packit |
df99a1 |
ref(job);
|
|
Packit |
df99a1 |
job->myctx = document->myctx;
|
|
Packit |
df99a1 |
job->mydoc = document;
|
|
Packit |
df99a1 |
bool indirect = false;
|
|
Packit |
df99a1 |
// parse options
|
|
Packit |
df99a1 |
while (optc>0)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GNativeString narg(optv[0]);
|
|
Packit |
df99a1 |
GUTF8String uarg = narg;
|
|
Packit |
df99a1 |
const char *s1 = (const char*)narg;
|
|
Packit |
df99a1 |
if (s1[0] == '-') s1++;
|
|
Packit |
df99a1 |
if (s1[0] == '-') s1++;
|
|
Packit |
df99a1 |
// separate arguments
|
|
Packit |
df99a1 |
if (!strncmp(s1, "page=", 5) ||
|
|
Packit |
df99a1 |
!strncmp(s1, "pages=", 6) )
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (job->pages.length())
|
|
Packit |
df99a1 |
complain(uarg,"multiple page specifications");
|
|
Packit |
df99a1 |
job->pages = uarg;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else if (!strncmp(s1, "indirect=", 9))
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GURL oname = GURL::Filename::UTF8(s1 + 9);
|
|
Packit |
df99a1 |
job->odir = oname.base();
|
|
Packit |
df99a1 |
job->oname = oname.fname();
|
|
Packit |
df99a1 |
indirect = true;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
complain(uarg, "Unrecognized option.");
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
// next option
|
|
Packit |
df99a1 |
optc -= 1;
|
|
Packit |
df99a1 |
optv += 1;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
// go
|
|
Packit |
df99a1 |
if (!indirect)
|
|
Packit |
df99a1 |
job->obs = ByteStream::create(output, "wb", false);
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
job->obs = 0;
|
|
Packit |
df99a1 |
job->start();
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH(ex)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (job)
|
|
Packit |
df99a1 |
unref(job);
|
|
Packit |
df99a1 |
job = 0;
|
|
Packit |
df99a1 |
ERROR1(document, ex);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
return job;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// ----------------------------------------
|
|
Packit |
df99a1 |
// S-Expressions (generic)
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
static miniexp_t
|
|
Packit |
df99a1 |
miniexp_status(ddjvu_status_t status)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (status < DDJVU_JOB_OK)
|
|
Packit |
df99a1 |
return miniexp_dummy;
|
|
Packit |
df99a1 |
else if (status == DDJVU_JOB_STOPPED)
|
|
Packit |
df99a1 |
return miniexp_symbol("stopped");
|
|
Packit |
df99a1 |
else if (status > DDJVU_JOB_OK)
|
|
Packit |
df99a1 |
return miniexp_symbol("failed");
|
|
Packit |
df99a1 |
return miniexp_nil;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
static void
|
|
Packit |
df99a1 |
miniexp_protect(ddjvu_document_t *document, miniexp_t expr)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GMonitorLock lock(&document->myctx->monitor);
|
|
Packit |
df99a1 |
for(miniexp_t p=document->protect; miniexp_consp(p); p=miniexp_cdr(p))
|
|
Packit |
df99a1 |
if (miniexp_car(p) == expr)
|
|
Packit |
df99a1 |
return;
|
|
Packit |
df99a1 |
if (miniexp_consp(expr) || miniexp_objectp(expr))
|
|
Packit |
df99a1 |
document->protect = miniexp_cons(expr, document->protect);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
ddjvu_miniexp_release(ddjvu_document_t *document, miniexp_t expr)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GMonitorLock lock(&document->myctx->monitor);
|
|
Packit |
df99a1 |
miniexp_t q = miniexp_nil;
|
|
Packit |
df99a1 |
miniexp_t p = document->protect;
|
|
Packit |
df99a1 |
while (miniexp_consp(p))
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (miniexp_car(p) != expr)
|
|
Packit |
df99a1 |
q = p;
|
|
Packit |
df99a1 |
else if (q)
|
|
Packit |
df99a1 |
miniexp_rplacd(q, miniexp_cdr(p));
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
document->protect = miniexp_cdr(p);
|
|
Packit |
df99a1 |
p = miniexp_cdr(p);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// ----------------------------------------
|
|
Packit |
df99a1 |
// S-Expressions (outline)
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
static miniexp_t
|
|
Packit |
df99a1 |
outline_sub(const GP<DjVmNav> &nav, int &pos, int count)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<DjVmNav::DjVuBookMark> entry;
|
|
Packit |
df99a1 |
minivar_t p,q,s;
|
|
Packit |
df99a1 |
while (count > 0 && pos < nav->getBookMarkCount())
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
nav->getBookMark(entry, pos++);
|
|
Packit |
df99a1 |
q = outline_sub(nav, pos, entry->count);
|
|
Packit |
df99a1 |
s = miniexp_string((const char*)(entry->url));
|
|
Packit |
df99a1 |
q = miniexp_cons(s, q);
|
|
Packit |
df99a1 |
s = miniexp_string((const char*)(entry->displayname));
|
|
Packit |
df99a1 |
q = miniexp_cons(s, q);
|
|
Packit |
df99a1 |
p = miniexp_cons(q, p);
|
|
Packit |
df99a1 |
count--;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
return miniexp_reverse(p);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
miniexp_t
|
|
Packit |
df99a1 |
ddjvu_document_get_outline(ddjvu_document_t *document)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ddjvu_status_t status = document->status();
|
|
Packit |
df99a1 |
if (status != DDJVU_JOB_OK)
|
|
Packit |
df99a1 |
return miniexp_status(status);
|
|
Packit |
df99a1 |
DjVuDocument *doc = document->doc;
|
|
Packit |
df99a1 |
if (doc)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<DjVmNav> nav = doc->get_djvm_nav();
|
|
Packit |
df99a1 |
if (! nav)
|
|
Packit |
df99a1 |
return miniexp_nil;
|
|
Packit |
df99a1 |
minivar_t result;
|
|
Packit |
df99a1 |
int pos = 0;
|
|
Packit |
df99a1 |
result = outline_sub(nav, pos, nav->getBookMarkCount());
|
|
Packit |
df99a1 |
result = miniexp_cons(miniexp_symbol("bookmarks"), result);
|
|
Packit |
df99a1 |
miniexp_protect(document, result);
|
|
Packit |
df99a1 |
return result;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH(ex)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ERROR1(document, ex);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
return miniexp_status(DDJVU_JOB_FAILED);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// ----------------------------------------
|
|
Packit |
df99a1 |
// S-Expressions (text)
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
static struct zone_names_s {
|
|
Packit |
df99a1 |
const char *name;
|
|
Packit |
df99a1 |
DjVuTXT::ZoneType ztype;
|
|
Packit |
df99a1 |
char separator;
|
|
Packit |
df99a1 |
} zone_names[] = {
|
|
Packit |
df99a1 |
{ "page", DjVuTXT::PAGE, 0 },
|
|
Packit |
df99a1 |
{ "column", DjVuTXT::COLUMN, DjVuTXT::end_of_column },
|
|
Packit |
df99a1 |
{ "region", DjVuTXT::REGION, DjVuTXT::end_of_region },
|
|
Packit |
df99a1 |
{ "para", DjVuTXT::PARAGRAPH, DjVuTXT::end_of_paragraph },
|
|
Packit |
df99a1 |
{ "line", DjVuTXT::LINE, DjVuTXT::end_of_line },
|
|
Packit |
df99a1 |
{ "word", DjVuTXT::WORD, ' ' },
|
|
Packit |
df99a1 |
{ "char", DjVuTXT::CHARACTER, 0 },
|
|
Packit |
df99a1 |
{ 0, (DjVuTXT::ZoneType)0 ,0 }
|
|
Packit |
df99a1 |
};
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
static miniexp_t
|
|
Packit |
df99a1 |
pagetext_sub(const GP<DjVuTXT> &txt, DjVuTXT::Zone &zone,
|
|
Packit |
df99a1 |
DjVuTXT::ZoneType detail)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
int zinfo;
|
|
Packit |
df99a1 |
for (zinfo=0; zone_names[zinfo].name; zinfo++)
|
|
Packit |
df99a1 |
if (zone.ztype == zone_names[zinfo].ztype)
|
|
Packit |
df99a1 |
break;
|
|
Packit |
df99a1 |
minivar_t p;
|
|
Packit |
df99a1 |
minivar_t a;
|
|
Packit |
df99a1 |
bool gather = zone.children.isempty();
|
|
Packit |
df99a1 |
{ // extra nesting for windows
|
|
Packit |
df99a1 |
for (GPosition pos=zone.children; pos; ++pos)
|
|
Packit |
df99a1 |
if (zone.children[pos].ztype > detail)
|
|
Packit |
df99a1 |
gather = true;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
if (gather)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
const char *data = (const char*)(txt->textUTF8) + zone.text_start;
|
|
Packit |
df99a1 |
int length = zone.text_length;
|
|
Packit |
df99a1 |
if (length>0 && data[length-1]==zone_names[zinfo].separator)
|
|
Packit |
df99a1 |
length -= 1;
|
|
Packit |
df99a1 |
a = miniexp_substring(data, length);
|
|
Packit |
df99a1 |
p = miniexp_cons(a, p);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
for (GPosition pos=zone.children; pos; ++pos)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
a = pagetext_sub(txt, zone.children[pos], detail);
|
|
Packit |
df99a1 |
p = miniexp_cons(a, p);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
p = miniexp_reverse(p);
|
|
Packit |
df99a1 |
const char *s = zone_names[zinfo].name;
|
|
Packit |
df99a1 |
if (s)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
p = miniexp_cons(miniexp_number(zone.rect.ymax), p);
|
|
Packit |
df99a1 |
p = miniexp_cons(miniexp_number(zone.rect.xmax), p);
|
|
Packit |
df99a1 |
p = miniexp_cons(miniexp_number(zone.rect.ymin), p);
|
|
Packit |
df99a1 |
p = miniexp_cons(miniexp_number(zone.rect.xmin), p);
|
|
Packit |
df99a1 |
p = miniexp_cons(miniexp_symbol(s), p);
|
|
Packit |
df99a1 |
return p;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
return miniexp_nil;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
miniexp_t
|
|
Packit |
df99a1 |
ddjvu_document_get_pagetext(ddjvu_document_t *document, int pageno,
|
|
Packit |
df99a1 |
const char *maxdetail)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ddjvu_status_t status = document->status();
|
|
Packit |
df99a1 |
if (status != DDJVU_JOB_OK)
|
|
Packit |
df99a1 |
return miniexp_status(status);
|
|
Packit |
df99a1 |
DjVuDocument *doc = document->doc;
|
|
Packit |
df99a1 |
if (doc)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
document->pageinfoflag = true;
|
|
Packit |
df99a1 |
GP<DjVuFile> file = doc->get_djvu_file(pageno);
|
|
Packit |
df99a1 |
if (! file || ! file->is_data_present() )
|
|
Packit |
df99a1 |
return miniexp_dummy;
|
|
Packit |
df99a1 |
GP<ByteStream> bs = file->get_text();
|
|
Packit |
df99a1 |
if (! bs)
|
|
Packit |
df99a1 |
return miniexp_nil;
|
|
Packit |
df99a1 |
GP<DjVuText> text = DjVuText::create();
|
|
Packit |
df99a1 |
text->decode(bs);
|
|
Packit |
df99a1 |
GP<DjVuTXT> txt = text->txt;
|
|
Packit |
df99a1 |
if (! txt)
|
|
Packit |
df99a1 |
return miniexp_nil;
|
|
Packit |
df99a1 |
minivar_t result;
|
|
Packit |
df99a1 |
DjVuTXT::ZoneType detail = DjVuTXT::CHARACTER;
|
|
Packit |
df99a1 |
{ // extra nesting for windows
|
|
Packit |
df99a1 |
for (int i=0; zone_names[i].name; i++)
|
|
Packit |
df99a1 |
if (maxdetail && !strcmp(maxdetail, zone_names[i].name))
|
|
Packit |
df99a1 |
detail = zone_names[i].ztype;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
result = pagetext_sub(txt, txt->page_zone, detail);
|
|
Packit |
df99a1 |
miniexp_protect(document, result);
|
|
Packit |
df99a1 |
return result;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH(ex)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ERROR1(document, ex);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
return miniexp_status(DDJVU_JOB_FAILED);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// ----------------------------------------
|
|
Packit |
df99a1 |
// S-Expressions (annotations)
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// The difficulty here lies with the syntax of strings in annotation chunks.
|
|
Packit |
df99a1 |
// - Early versions of djvu only had one possible escape
|
|
Packit |
df99a1 |
// sequence (\") in annotation strings. All other characters
|
|
Packit |
df99a1 |
// are accepted literally until reaching the closing double quote.
|
|
Packit |
df99a1 |
// - Current versions of djvu understand the usual backslash escapes.
|
|
Packit |
df99a1 |
// All non printable ascii characters must however be escaped.
|
|
Packit |
df99a1 |
// This is a subset of the miniexp syntax.
|
|
Packit |
df99a1 |
// We first check if strings in the annotation chunk obey the modern syntax.
|
|
Packit |
df99a1 |
// The compatibility mode is turned on if they contain non printable ascii
|
|
Packit |
df99a1 |
// characters or illegal backslash sequences. Function <anno_getc()> then
|
|
Packit |
df99a1 |
// creates the proper escapes on the fly.
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
struct anno_dat_s {
|
|
Packit |
df99a1 |
const char *s;
|
|
Packit |
df99a1 |
char buf[8];
|
|
Packit |
df99a1 |
int blen;
|
|
Packit |
df99a1 |
int state;
|
|
Packit |
df99a1 |
bool compat;
|
|
Packit |
df99a1 |
bool eof;
|
|
Packit |
df99a1 |
};
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
static bool
|
|
Packit |
df99a1 |
anno_compat(const char *s)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
int state = 0;
|
|
Packit |
df99a1 |
bool compat = false;
|
|
Packit |
df99a1 |
while (s && *s && !compat)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
int i = (int)(unsigned char)*s++;
|
|
Packit |
df99a1 |
switch(state)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
case 0:
|
|
Packit |
df99a1 |
if (i == '\"')
|
|
Packit |
df99a1 |
state = '\"';
|
|
Packit |
df99a1 |
break;
|
|
Packit |
df99a1 |
case '\"':
|
|
Packit |
df99a1 |
if (i == '\"')
|
|
Packit |
df99a1 |
state = 0;
|
|
Packit |
df99a1 |
else if (i == '\\')
|
|
Packit |
df99a1 |
state = '\\';
|
|
Packit |
df99a1 |
else if (isascii(i) && !isprint(i))
|
|
Packit |
df99a1 |
compat = true;
|
|
Packit |
df99a1 |
break;
|
|
Packit |
df99a1 |
case '\\':
|
|
Packit |
df99a1 |
if (!strchr("01234567abtnvfr\"\\",i))
|
|
Packit |
df99a1 |
compat = true;
|
|
Packit |
df99a1 |
state = '\"';
|
|
Packit |
df99a1 |
break;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
return compat;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
static int
|
|
Packit |
df99a1 |
anno_fgetc(miniexp_io_t *io)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
struct anno_dat_s *anno_dat_p = (struct anno_dat_s*)(io->data[0]);
|
|
Packit |
df99a1 |
struct anno_dat_s &anno_dat = *anno_dat_p;
|
|
Packit |
df99a1 |
if (anno_dat.blen>0)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
anno_dat.blen--;
|
|
Packit |
df99a1 |
char c = anno_dat.buf[0];
|
|
Packit |
df99a1 |
for (int i=0; i
|
|
Packit |
df99a1 |
anno_dat.buf[i] = anno_dat.buf[i+1];
|
|
Packit |
df99a1 |
return c;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
if (! *anno_dat.s)
|
|
Packit |
df99a1 |
return EOF;
|
|
Packit |
df99a1 |
int c = (int)(unsigned char)*anno_dat.s++;
|
|
Packit |
df99a1 |
if (anno_dat.compat)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
switch (anno_dat.state)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
case 0:
|
|
Packit |
df99a1 |
if (c == '\"')
|
|
Packit |
df99a1 |
anno_dat.state = '\"';
|
|
Packit |
df99a1 |
break;
|
|
Packit |
df99a1 |
case '\"':
|
|
Packit |
df99a1 |
if (c == '\"')
|
|
Packit |
df99a1 |
anno_dat.state = 0;
|
|
Packit |
df99a1 |
else if (c == '\\')
|
|
Packit |
df99a1 |
anno_dat.state = '\\';
|
|
Packit |
df99a1 |
else if (isascii(c) && !isprint(c))
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
sprintf(anno_dat.buf,"%03o", c);
|
|
Packit |
df99a1 |
anno_dat.blen = strlen(anno_dat.buf);
|
|
Packit |
df99a1 |
c = '\\';
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
break;
|
|
Packit |
df99a1 |
case '\\':
|
|
Packit |
df99a1 |
anno_dat.state = '\"';
|
|
Packit |
df99a1 |
if (c != '\"')
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
sprintf(anno_dat.buf,"\\%03o", c);
|
|
Packit |
df99a1 |
anno_dat.blen = strlen(anno_dat.buf);
|
|
Packit |
df99a1 |
c = '\\';
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
break;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
return c;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
static int
|
|
Packit |
df99a1 |
anno_ungetc(miniexp_io_t *io, int c)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (c == EOF)
|
|
Packit |
df99a1 |
return EOF;
|
|
Packit |
df99a1 |
struct anno_dat_s *anno_dat_p = (struct anno_dat_s*)(io->data[0]);
|
|
Packit |
df99a1 |
struct anno_dat_s &anno_dat = *anno_dat_p;
|
|
Packit |
df99a1 |
if (anno_dat.blen>=(int)sizeof(anno_dat.buf))
|
|
Packit |
df99a1 |
return EOF;
|
|
Packit |
df99a1 |
for (int i=anno_dat.blen; i>0; i--)
|
|
Packit |
df99a1 |
anno_dat.buf[i] = anno_dat.buf[i-1];
|
|
Packit |
df99a1 |
anno_dat.blen += 1;
|
|
Packit |
df99a1 |
anno_dat.buf[0] = c;
|
|
Packit |
df99a1 |
return c;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
static void
|
|
Packit |
df99a1 |
anno_sub(ByteStream *bs, miniexp_t &result)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
// Read bs
|
|
Packit |
df99a1 |
GUTF8String raw;
|
|
Packit |
df99a1 |
char buffer[1024];
|
|
Packit |
df99a1 |
int length;
|
|
Packit |
df99a1 |
while ((length=bs->read(buffer, sizeof(buffer))))
|
|
Packit |
df99a1 |
raw += GUTF8String(buffer, length);
|
|
Packit |
df99a1 |
// Prepare
|
|
Packit |
df99a1 |
miniexp_t a;
|
|
Packit |
df99a1 |
struct anno_dat_s anno_dat;
|
|
Packit |
df99a1 |
anno_dat.s = (const char*)raw;
|
|
Packit |
df99a1 |
anno_dat.compat = anno_compat(anno_dat.s);
|
|
Packit |
df99a1 |
anno_dat.blen = 0;
|
|
Packit |
df99a1 |
anno_dat.state = 0;
|
|
Packit |
df99a1 |
anno_dat.eof = false;
|
|
Packit |
df99a1 |
miniexp_io_t io;
|
|
Packit |
df99a1 |
miniexp_io_init(&io);
|
|
Packit |
df99a1 |
io.data[0] = (void*)&anno_dat;
|
|
Packit |
df99a1 |
io.fgetc = anno_fgetc;
|
|
Packit |
df99a1 |
io.ungetc = anno_ungetc;
|
|
Packit |
df99a1 |
io.p_macrochar = 0;
|
|
Packit |
df99a1 |
io.p_diezechar = 0;
|
|
Packit |
df99a1 |
io.p_macroqueue = 0;
|
|
Packit |
df99a1 |
// Read
|
|
Packit |
df99a1 |
while (* anno_dat.s )
|
|
Packit |
df99a1 |
if ((a = miniexp_read_r(&io)) != miniexp_dummy)
|
|
Packit |
df99a1 |
result = miniexp_cons(a, result);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
static miniexp_t
|
|
Packit |
df99a1 |
get_bytestream_anno(GP<ByteStream> annobs)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (! (annobs && annobs->size()))
|
|
Packit |
df99a1 |
return miniexp_nil;
|
|
Packit |
df99a1 |
GP<IFFByteStream> iff = IFFByteStream::create(annobs);
|
|
Packit |
df99a1 |
GUTF8String chkid;
|
|
Packit |
df99a1 |
minivar_t result;
|
|
Packit |
df99a1 |
while (iff->get_chunk(chkid))
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<ByteStream> bs;
|
|
Packit |
df99a1 |
if (chkid == "ANTa")
|
|
Packit |
df99a1 |
bs = iff->get_bytestream();
|
|
Packit |
df99a1 |
else if (chkid == "ANTz")
|
|
Packit |
df99a1 |
bs = BSByteStream::create(iff->get_bytestream());
|
|
Packit |
df99a1 |
if (bs)
|
|
Packit |
df99a1 |
anno_sub(bs, result);
|
|
Packit |
df99a1 |
iff->close_chunk();
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
return miniexp_reverse(result);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
static miniexp_t
|
|
Packit |
df99a1 |
get_file_anno(GP<DjVuFile> file)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
// Make sure all data is present
|
|
Packit |
df99a1 |
if (! file || ! file->is_all_data_present())
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (file && file->is_data_present())
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (! file->are_incl_files_created())
|
|
Packit |
df99a1 |
file->process_incl_chunks();
|
|
Packit |
df99a1 |
if (! file->are_incl_files_created())
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (file->get_flags() & DjVuFile::STOPPED)
|
|
Packit |
df99a1 |
return miniexp_status(DDJVU_JOB_STOPPED);
|
|
Packit |
df99a1 |
return miniexp_status(DDJVU_JOB_FAILED);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
return miniexp_dummy;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
// Access annotation data
|
|
Packit |
df99a1 |
return get_bytestream_anno(file->get_merged_anno());
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
miniexp_t
|
|
Packit |
df99a1 |
ddjvu_document_get_pageanno(ddjvu_document_t *document, int pageno)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ddjvu_status_t status = document->status();
|
|
Packit |
df99a1 |
if (status != DDJVU_JOB_OK)
|
|
Packit |
df99a1 |
return miniexp_status(status);
|
|
Packit |
df99a1 |
DjVuDocument *doc = document->doc;
|
|
Packit |
df99a1 |
if (doc)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
document->pageinfoflag = true;
|
|
Packit |
df99a1 |
minivar_t result = get_file_anno( doc->get_djvu_file(pageno) );
|
|
Packit |
df99a1 |
if (miniexp_consp(result))
|
|
Packit |
df99a1 |
miniexp_protect(document, result);
|
|
Packit |
df99a1 |
return result;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH(ex)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ERROR1(document, ex);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
return miniexp_status(DDJVU_JOB_FAILED);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
miniexp_t
|
|
Packit |
df99a1 |
ddjvu_document_get_anno(ddjvu_document_t *document, int compat)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ddjvu_status_t status = document->status();
|
|
Packit |
df99a1 |
if (status != DDJVU_JOB_OK)
|
|
Packit |
df99a1 |
return miniexp_status(status);
|
|
Packit |
df99a1 |
DjVuDocument *doc = document->doc;
|
|
Packit |
df99a1 |
if (doc)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
#if EXPERIMENTAL_DOCUMENT_ANNOTATIONS
|
|
Packit |
df99a1 |
// not yet implemented
|
|
Packit |
df99a1 |
GP<ByteStream> anno = doc->get_document_anno();
|
|
Packit |
df99a1 |
if (anno)
|
|
Packit |
df99a1 |
return get_bytestream_anno(anno);
|
|
Packit |
df99a1 |
#endif
|
|
Packit |
df99a1 |
if (compat)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
// look for shared annotations
|
|
Packit |
df99a1 |
int doc_type = doc->get_doc_type();
|
|
Packit |
df99a1 |
if (doc_type != DjVuDocument::BUNDLED &&
|
|
Packit |
df99a1 |
doc_type != DjVuDocument::INDIRECT )
|
|
Packit |
df99a1 |
return miniexp_nil;
|
|
Packit |
df99a1 |
GP<DjVmDir> dir = doc->get_djvm_dir();
|
|
Packit |
df99a1 |
int filenum = dir->get_files_num();
|
|
Packit |
df99a1 |
GP<DjVmDir::File> fdesc;
|
|
Packit |
df99a1 |
for (int i=0; i
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<DjVmDir::File> f = dir->pos_to_file(i);
|
|
Packit |
df99a1 |
if (!f->is_shared_anno())
|
|
Packit |
df99a1 |
continue;
|
|
Packit |
df99a1 |
if (fdesc)
|
|
Packit |
df99a1 |
return miniexp_nil;
|
|
Packit |
df99a1 |
fdesc = f;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
if (fdesc)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GUTF8String id = fdesc->get_load_name();
|
|
Packit |
df99a1 |
return get_file_anno(doc->get_djvu_file(id));
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
return miniexp_nil;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH(ex)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
ERROR1(document, ex);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
return miniexp_status(DDJVU_JOB_FAILED);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
/* ------ helpers for annotations ---- */
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
static const char *
|
|
Packit |
df99a1 |
simple_anno_sub(miniexp_t p, miniexp_t s, int i)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
const char *result = 0;
|
|
Packit |
df99a1 |
while (miniexp_consp(p))
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
miniexp_t a = miniexp_car(p);
|
|
Packit |
df99a1 |
p = miniexp_cdr(p);
|
|
Packit |
df99a1 |
if (miniexp_car(a) == s)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
miniexp_t q = miniexp_nth(i, a);
|
|
Packit |
df99a1 |
if (miniexp_symbolp(q))
|
|
Packit |
df99a1 |
result = miniexp_to_name(q);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
return result;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
const char *
|
|
Packit |
df99a1 |
ddjvu_anno_get_bgcolor(miniexp_t p)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
return simple_anno_sub(p, miniexp_symbol("background"), 1);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
const char *
|
|
Packit |
df99a1 |
ddjvu_anno_get_zoom(miniexp_t p)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
return simple_anno_sub(p, miniexp_symbol("zoom"), 1);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
const char *
|
|
Packit |
df99a1 |
ddjvu_anno_get_mode(miniexp_t p)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
return simple_anno_sub(p, miniexp_symbol("mode"), 1);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
const char *
|
|
Packit |
df99a1 |
ddjvu_anno_get_horizalign(miniexp_t p)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
return simple_anno_sub(p, miniexp_symbol("align"), 1);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
const char *
|
|
Packit |
df99a1 |
ddjvu_anno_get_vertalign(miniexp_t p)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
return simple_anno_sub(p, miniexp_symbol("align"), 2);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
miniexp_t *
|
|
Packit |
df99a1 |
ddjvu_anno_get_hyperlinks(miniexp_t annotations)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
miniexp_t p;
|
|
Packit |
df99a1 |
miniexp_t s_maparea = miniexp_symbol("maparea");
|
|
Packit |
df99a1 |
int i = 0;
|
|
Packit |
df99a1 |
for (p = annotations; miniexp_consp(p); p = miniexp_cdr(p))
|
|
Packit |
df99a1 |
if (miniexp_caar(p) == s_maparea)
|
|
Packit |
df99a1 |
i += 1;
|
|
Packit |
df99a1 |
miniexp_t *k = (miniexp_t*)malloc((1+i)*sizeof(miniexp_t));
|
|
Packit |
df99a1 |
if (! k) return 0;
|
|
Packit |
df99a1 |
i = 0;
|
|
Packit |
df99a1 |
for (p = annotations; miniexp_consp(p); p = miniexp_cdr(p))
|
|
Packit |
df99a1 |
if (miniexp_caar(p) == s_maparea)
|
|
Packit |
df99a1 |
k[i++] = miniexp_car(p);
|
|
Packit |
df99a1 |
k[i] = 0;
|
|
Packit |
df99a1 |
return k;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
static void
|
|
Packit |
df99a1 |
metadata_sub(miniexp_t p, GMap<miniexp_t,miniexp_t> &m)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
miniexp_t s_metadata = miniexp_symbol("metadata");
|
|
Packit |
df99a1 |
while (miniexp_consp(p))
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (miniexp_caar(p) == s_metadata)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
miniexp_t q = miniexp_cdar(p);
|
|
Packit |
df99a1 |
while (miniexp_consp(q))
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
miniexp_t a = miniexp_car(q);
|
|
Packit |
df99a1 |
q = miniexp_cdr(q);
|
|
Packit |
df99a1 |
if (miniexp_consp(a) &&
|
|
Packit |
df99a1 |
miniexp_symbolp(miniexp_car(a)) &&
|
|
Packit |
df99a1 |
miniexp_stringp(miniexp_cadr(a)) )
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
m[miniexp_car(a)] = miniexp_cadr(a);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
p = miniexp_cdr(p);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
miniexp_t *
|
|
Packit |
df99a1 |
ddjvu_anno_get_metadata_keys(miniexp_t p)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
minivar_t l;
|
|
Packit |
df99a1 |
GMap<miniexp_t,miniexp_t> m;
|
|
Packit |
df99a1 |
metadata_sub(p, m);
|
|
Packit |
df99a1 |
int i = m.size();
|
|
Packit |
df99a1 |
miniexp_t *k = (miniexp_t*)malloc((1+i)*sizeof(miniexp_t));
|
|
Packit |
df99a1 |
if (! k) return 0;
|
|
Packit |
df99a1 |
i = 0;
|
|
Packit |
df99a1 |
for (GPosition p=m; p; ++p)
|
|
Packit |
df99a1 |
k[i++] = m.key(p);
|
|
Packit |
df99a1 |
k[i] = 0;
|
|
Packit |
df99a1 |
return k;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
const char *
|
|
Packit |
df99a1 |
ddjvu_anno_get_metadata(miniexp_t p, miniexp_t key)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GMap<miniexp_t,miniexp_t> m;
|
|
Packit |
df99a1 |
metadata_sub(p, m);
|
|
Packit |
df99a1 |
if (m.contains(key))
|
|
Packit |
df99a1 |
return miniexp_to_str(m[key]);
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
const char *
|
|
Packit |
df99a1 |
ddjvu_anno_get_xmp(miniexp_t p)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
miniexp_t s = miniexp_symbol("xmp");
|
|
Packit |
df99a1 |
while (miniexp_consp(p))
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
miniexp_t a = miniexp_car(p);
|
|
Packit |
df99a1 |
p = miniexp_cdr(p);
|
|
Packit |
df99a1 |
if (miniexp_car(a) == s)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
miniexp_t q = miniexp_nth(1, a);
|
|
Packit |
df99a1 |
if (miniexp_stringp(q))
|
|
Packit |
df99a1 |
return miniexp_to_str(q);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// ----------------------------------------
|
|
Packit |
df99a1 |
// Backdoors
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GP<DjVuImage>
|
|
Packit |
df99a1 |
ddjvu_get_DjVuImage(ddjvu_page_t *page)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
return page->img;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GP<DjVuDocument>
|
|
Packit |
df99a1 |
ddjvu_get_DjVuDocument(ddjvu_document_t *document)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
return document->doc;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|