786
ddjvu_document_s::notify_file_flags_changed(const DjVuFile*, long s, long)
825
ddjvu_document_s::callback(void *arg)
788
if (pageinfoflag && !fileflag)
789
if (s & DjVuFile::ALL_DATA_PRESENT)
790
msg_push(xhead(DDJVU_PAGEINFO, this));
827
ddjvu_document_t *doc = (ddjvu_document_t *)arg;
828
if (doc && doc->pageinfoflag && !doc->fileflag)
829
msg_push(xhead(DDJVU_PAGEINFO, doc));
794
834
ddjvu_document_s::request_data(const DjVuPort *p, const GURL &url)
836
// Note: the following line try to restore
837
// the bytes stored in the djvu file
838
// despite LT's i18n and gurl classes.
839
GUTF8String name = (const char*)url.fname();
796
840
GMonitorLock lock(&monitor);
797
841
GP<DataPool> pool;
842
if (names.contains(name))
844
int streamid = names[name];
845
return streams[streamid];
800
849
if (doc && url.is_local_file_url())
801
850
return DataPool::create(url);
805
855
if (++streamid > 0)
806
856
streams[streamid] = pool = DataPool::create();
808
858
pool = streams[(streamid = 0)];
859
names[name] = streamid;
860
pool->add_trigger(-1, callback, (void*)this);
810
862
GP<ddjvu_message_p> p = new ddjvu_message_p;
811
863
p->p.m_newstream.streamid = streamid;
812
// Note: the following line try to restore
813
// the bytes stored in the djvu file
814
// despite LT's i18n and gurl classes.
815
p->tmp1 = (const char*)url.fname();
816
865
p->p.m_newstream.name = (const char*)(p->tmp1);
817
866
p->p.m_newstream.url = 0;
1078
ERROR1(document,ex);
1038
ddjvu_document_get_pageinfo(ddjvu_document_t *document, int pageno,
1039
ddjvu_pageinfo_t *pageinfo)
1086
ddjvu_document_get_filenum(ddjvu_document_t *document)
1090
DjVuDocument *doc = document->doc;
1091
if (! (doc && doc->is_init_ok()))
1093
int doc_type = doc->get_doc_type();
1094
if (doc_type == DjVuDocument::BUNDLED ||
1095
doc_type == DjVuDocument::INDIRECT )
1097
GP<DjVmDir> dir = doc->get_djvm_dir();
1098
return dir->get_files_num();
1100
else if (doc_type == DjVuDocument::OLD_BUNDLED)
1102
GP<DjVmDir0> dir0 = doc->get_djvm_dir0();
1103
return dir0->get_files_num();
1106
return doc->get_pages_num();
1110
ERROR1(document,ex);
1117
#undef ddjvu_document_get_fileinfo
1119
extern "C" DDJVUAPI ddjvu_status_t
1120
ddjvu_document_get_fileinfo(ddjvu_document_t *d, int f, ddjvu_fileinfo_t *i);
1123
ddjvu_document_get_fileinfo(ddjvu_document_t *d, int f, ddjvu_fileinfo_t *i)
1125
// for binary backward compatibility with ddjvuapi=17
1126
struct info17_s { char t; int p,s; const char *d, *n, *l; };
1127
return ddjvu_document_get_fileinfo_imp(d,f,i,sizeof(info17_s));
1131
ddjvu_document_get_fileinfo_imp(ddjvu_document_t *document, int fileno,
1132
ddjvu_fileinfo_t *info,
1133
unsigned int infosz )
1135
struct info17_s { char t; int p,s; const char *d, *n, *l; };
1139
memset(info, 0, infosz);
1140
DjVuDocument *doc = document->doc;
1142
return DDJVU_JOB_NOTSTARTED;
1143
if (! doc->is_init_ok())
1144
return document->status();
1145
int type = doc->get_doc_type();
1146
if ( type == DjVuDocument::BUNDLED ||
1147
type == DjVuDocument::INDIRECT )
1149
GP<DjVmDir> dir = doc->get_djvm_dir();
1150
GP<DjVmDir::File> file = dir->pos_to_file(fileno, &info->pageno);
1152
G_THROW("Illegal file number");
1154
if (file->is_page())
1158
if (file->is_thumbnails())
1160
if (file->is_shared_anno())
1162
info->size = file->size;
1163
info->id = file->get_load_name();
1164
info->name = file->get_save_name();
1165
info->title = file->get_title();
1166
return DDJVU_JOB_OK;
1168
else if (type == DjVuDocument::OLD_BUNDLED)
1170
GP<DjVmDir0> dir0 = doc->get_djvm_dir0();
1171
GP<DjVuNavDir> nav = doc->get_nav_dir();
1172
GP<DjVmDir0::FileRec> frec = dir0->get_file(fileno);
1174
G_THROW("Illegal file number");
1175
info->size = frec->size;
1176
info->id = (const char*) frec->name;
1177
info->name = info->title = info->id;
1179
return DDJVU_JOB_STARTED;
1180
else if (nav->name_to_page(frec->name) >= 0)
1184
return DDJVU_JOB_OK;
1188
if (fileno<0 || fileno>=doc->get_pages_num())
1189
G_THROW("Illegal file number");
1191
info->pageno = fileno;
1193
GP<DjVuNavDir> nav = doc->get_nav_dir();
1194
info->id = (nav) ? (const char *) nav->page_to_name(fileno) : 0;
1195
info->name = info->title = info->id;
1196
GP<DjVuFile> file = doc->get_djvu_file(fileno, true);
1197
GP<DataPool> pool = (file) ? file->get_init_data_pool() : 0;
1198
info->size = (pool) ? pool->get_length() : -1;
1199
return DDJVU_JOB_OK;
1204
ERROR1(document,ex);
1207
return DDJVU_JOB_FAILED;
1212
ddjvu_document_search_pageno(ddjvu_document_t *document, const char *name)
1216
DjVuDocument *doc = document->doc;
1217
if (! (doc && doc->is_init_ok()))
1219
GP<DjVmDir> dir = doc->get_djvm_dir();
1222
GP<DjVmDir::File> file;
1223
if (! (file = dir->id_to_file(GUTF8String(name))))
1224
if (! (file = dir->name_to_file(GUTF8String(name))))
1225
if (! (file = dir->title_to_file(GUTF8String(name))))
1228
long int p = strtol(name, &edata, 10);
1229
if (edata!=name && !*edata && p>=1)
1230
file = dir->page_to_file(p-1);
1235
int fileno = dir->get_file_pos(file);
1236
if (dir->pos_to_file(fileno, &pageno))
1242
ERROR1(document,ex);
1250
ddjvu_document_check_pagedata(ddjvu_document_t *document, int pageno)
1254
document->pageinfoflag = true;
1255
DjVuDocument *doc = document->doc;
1256
if (doc && doc->is_init_ok())
1259
if (doc->get_doc_type()==DjVuDocument::INDIRECT)
1260
file = doc->get_djvu_file(pageno, true);
1262
file = doc->get_djvu_file(pageno, false);
1263
if (file && file->is_data_present())
1269
ERROR1(document,ex);
1276
#undef ddjvu_document_get_pageinfo
1278
extern "C" DDJVUAPI ddjvu_status_t
1279
ddjvu_document_get_pageinfo(ddjvu_document_t *d, int p, ddjvu_pageinfo_t *i);
1282
ddjvu_document_get_pageinfo(ddjvu_document_t *d, int p, ddjvu_pageinfo_t *i)
1284
// for binary backward compatibility with ddjvuapi<=17
1285
struct info17_s { int w; int h; int d; };
1286
return ddjvu_document_get_pageinfo_imp(d,p,i,sizeof(struct info17_s));
1290
ddjvu_document_get_pageinfo_imp(ddjvu_document_t *document, int pageno,
1291
ddjvu_pageinfo_t *pageinfo,
1292
unsigned int infosz)
1294
struct info17_s { int w; int h; int d; };
1298
memset(pageinfo, 0, infosz);
1043
1299
DjVuDocument *doc = document->doc;
1104
ERROR(document, ex);
1374
ERROR1(document, ex);
1107
1377
return DDJVU_JOB_FAILED;
1382
get_file_dump(DjVuFile *file)
1384
DjVuDumpHelper dumper;
1385
GP<DataPool> pool = file->get_init_data_pool();
1386
GP<ByteStream> str = dumper.dump(pool);
1387
int size = str->size();
1389
if ((size = str->size()) > 0 && (buffer = (char*)malloc(size+1)))
1392
int len = str->readall(buffer, size);
1401
ddjvu_document_get_pagedump(ddjvu_document_t *document, int pageno)
1405
DjVuDocument *doc = document->doc;
1408
document->pageinfoflag = true;
1409
GP<DjVuFile> file = doc->get_djvu_file(pageno);
1410
if (file && file->is_data_present())
1411
return get_file_dump(file);
1416
ERROR1(document, ex);
1424
ddjvu_document_get_filedump(ddjvu_document_t *document, int fileno)
1428
DjVuDocument *doc = document->doc;
1432
int type = doc->get_doc_type();
1433
if ( type != DjVuDocument::BUNDLED &&
1434
type != DjVuDocument::INDIRECT )
1435
file = doc->get_djvu_file(fileno);
1438
GP<DjVmDir> dir = doc->get_djvm_dir();
1439
GP<DjVmDir::File> fdesc = dir->pos_to_file(fileno);
1441
file = doc->get_djvu_file(fdesc->get_load_name());
1443
document->pageinfoflag = true;
1444
if (file && file->is_data_present())
1445
return get_file_dump(file);
1450
ERROR1(document, ex);
1111
1458
// ----------------------------------------
1800
ddjvu_page_rotation_t
1801
ddjvu_page_get_rotation(ddjvu_page_t *page)
1803
ddjvu_page_rotation_t rot = DDJVU_ROTATE_0;
1806
if (page && page->img)
1807
rot = (ddjvu_page_rotation_t)(page->img->get_rotate() & 3);
1817
ddjvu_page_rotation_t
1818
ddjvu_page_get_initial_rotation(ddjvu_page_t *page)
1820
ddjvu_page_rotation_t rot = DDJVU_ROTATE_0;
1824
if (page && page->img)
1825
info = page->img->get_info();
1827
rot = (ddjvu_page_rotation_t)(info->orientation & 3);
1838
// ----------------------------------------
1842
rect2grect(const ddjvu_rect_t *r, GRect &g)
1846
g.xmax = r->x + r->w;
1847
g.ymax = r->y + r->h;
1851
grect2rect(const GRect &g, ddjvu_rect_t *r)
1867
ddjvu_rectmapper_t *
1868
ddjvu_rectmapper_create(ddjvu_rect_t *input, ddjvu_rect_t *output)
1870
GRect ginput, goutput;
1871
rect2grect(input, ginput);
1872
rect2grect(output, goutput);
1873
GRectMapper *mapper = new GRectMapper;
1874
if (!ginput.isempty())
1875
mapper->set_input(ginput);
1876
if (!goutput.isempty())
1877
mapper->set_output(goutput);
1878
return (ddjvu_rectmapper_t*)mapper;
1882
ddjvu_rectmapper_modify(ddjvu_rectmapper_t *mapper,
1883
int rotation, int mirrorx, int mirrory)
1885
GRectMapper *gmapper = (GRectMapper*)mapper;
1886
if (! gmapper) return;
1887
gmapper->rotate(rotation);
1895
ddjvu_rectmapper_release(ddjvu_rectmapper_t *mapper)
1897
GRectMapper *gmapper = (GRectMapper*)mapper;
1898
if (! gmapper) return;
1903
ddjvu_map_point(ddjvu_rectmapper_t *mapper, int *x, int *y)
1905
GRectMapper *gmapper = (GRectMapper*)mapper;
1906
if (! gmapper) return;
1907
gmapper->map(*x,*y);
1911
ddjvu_map_rect(ddjvu_rectmapper_t *mapper, ddjvu_rect_t *rect)
1913
GRectMapper *gmapper = (GRectMapper*)mapper;
1914
if (! gmapper) return;
1916
rect2grect(rect,grect);
1917
gmapper->map(grect);
1918
grect2rect(grect,rect);
1922
ddjvu_unmap_point(ddjvu_rectmapper_t *mapper, int *x, int *y)
1924
GRectMapper *gmapper = (GRectMapper*)mapper;
1925
if (! gmapper) return;
1926
gmapper->unmap(*x,*y);
1930
ddjvu_unmap_rect(ddjvu_rectmapper_t *mapper, ddjvu_rect_t *rect)
1932
GRectMapper *gmapper = (GRectMapper*)mapper;
1933
if (! gmapper) return;
1935
rect2grect(rect,grect);
1936
gmapper->unmap(grect);
1937
grect2rect(grect,rect);
1824
2302
GP<GPixmap> pm;
1825
2303
GP<GBitmap> bm;
2305
rect2grect(pagerect, prect);
2306
rect2grect(renderrect, rrect);
1828
2307
if (pixelformat && pixelformat->ytoptobottom)
1830
prect.xmin = pagerect->x;
1831
prect.xmax = prect.xmin + pagerect->w;
1832
2309
prect.ymin = renderrect->y + renderrect->h;
1833
2310
prect.ymax = prect.ymin + pagerect->h;
1834
rrect.xmin = renderrect->x;
1835
rrect.xmax = rrect.xmin + renderrect->w;
1836
2311
rrect.ymin = pagerect->y + pagerect->h;
1837
2312
rrect.ymax = rrect.ymin + renderrect->h;
1841
prect.xmin = pagerect->x;
1842
prect.xmax = prect.xmin + pagerect->w;
1843
prect.ymin = pagerect->y;
1844
prect.ymax = prect.ymin + pagerect->h;
1845
rrect.xmin = renderrect->x;
1846
rrect.xmax = rrect.xmin + renderrect->w;
1847
rrect.ymin = renderrect->y;
1848
rrect.ymax = rrect.ymin + renderrect->h;
1851
2315
DjVuImage *img = page->img;
2468
ERROR(document, ex);
2935
ERROR1(document, ex);
2474
2941
// ----------------------------------------
2475
// Not yet implemented
2942
// Saving (insufficiently tested)
2944
struct DJVUNS ddjvu_savejob_s : public ddjvu_runnablejob_s
2947
virtual ddjvu_status_t run();
2948
// virtual port functions:
2949
virtual bool inherits(const GUTF8String&);
2950
virtual void notify_file_flags_changed(const DjVuFile*, long, long);
2956
ddjvu_savejob_s::inherits(const GUTF8String &classname)
2958
return (classname == "ddjvu_savejob_s")
2959
|| ddjvu_runnablejob_s::inherits(classname);
2963
ddjvu_savejob_s::notify_file_flags_changed(const DjVuFile *file, long mask, long)
2965
if (mask & (DjVuFile::ALL_DATA_PRESENT ||
2966
DjVuFile::DECODE_FAILED || DjVuFile::DECODE_STOPPED ||
2967
DjVuFile::STOPPED || DjVuFile::DECODE_STOPPED ))
2969
GMonitorLock lock(&monitor);
2975
ddjvu_savejob_s::run()
2977
DjVuDocument *doc = mydoc->doc;
2978
doc->wait_for_complete_init();
2979
// Determine which components to save
2981
GArray<GUTF8String> comp_ids;
2982
GPArray<DjVuFile> comp_files;
2983
if (doc->get_doc_type()==DjVuDocument::BUNDLED ||
2984
doc->get_doc_type()==DjVuDocument::INDIRECT)
2986
GP<DjVmDir> dir = doc->get_djvm_dir();
2987
ncomp = dir->get_files_num();
2988
comp_ids.resize(ncomp - 1);
2989
comp_files.resize(ncomp - 1);
2990
GPList<DjVmDir::File> flist = dir->get_files_list();
2991
GPosition pos=flist;
2992
for (int comp=0; comp<ncomp; ++pos, ++comp)
2993
comp_ids[comp] = flist[pos]->get_load_name();
2997
ncomp = doc->get_pages_num();
2998
comp_ids.resize(ncomp - 1);
2999
comp_files.resize(ncomp - 1);
3000
{ // extra nesting for windows
3001
for (int comp=0; comp<ncomp; comp++)
3002
comp_ids[comp] = GUTF8String(comp);
3005
// Monitoring download progress
3008
get_portcaster()->add_route(doc, this);
3009
while (lo < ncomp && !mystop)
3011
int in_progress = 0;
3012
GMonitorLock lock(&monitor);
3013
while (lo<hi && comp_files[lo]->is_data_present())
3015
{ // extra nesting for windows
3016
for (int comp=lo; comp<hi; comp++)
3017
if (! comp_files[comp]->is_data_present())
3020
while (hi<ncomp && in_progress < 2)
3022
comp_files[hi] = doc->get_djvu_file(comp_ids[hi]);
3026
if (in_progress > 0)
3033
return DDJVU_JOB_OK;
2478
3038
ddjvu_document_save(ddjvu_document_t *document, FILE *output,
2479
3039
int optc, const char * const * optv)
3041
ddjvu_savejob_s *job = 0;
3044
job = new ddjvu_savejob_s;
3046
job->myctx = document->myctx;
3047
job->mydoc = document;
3051
GNativeString narg(optv[0]);
3052
GUTF8String uarg = narg;
3053
complain(uarg, "Unrecognized option.");
3058
job->obs = ByteStream::create(output, "wb", false);
3066
ERROR1(document, ex);
2486
3075
// ----------------------------------------
2487
3076
// S-Expressions (generic)
2811
3417
while ((length=bs->read(buffer, sizeof(buffer))))
2812
3418
raw += GUTF8String(buffer, length);
2815
3421
anno_dat.s = (const char*)raw;
2816
3422
anno_dat.compat = anno_compat(anno_dat.s);
2817
3423
anno_dat.blen = 0;
2818
3424
anno_dat.state = 0;
2819
3425
anno_dat.eof = false;
3426
int (*saved_getc)(void) = minilisp_getc;
3427
int (*saved_ungetc)(int) = minilisp_ungetc;
2820
3429
minilisp_getc = anno_getc;
2821
3430
minilisp_ungetc = anno_ungetc;
2823
3431
while (* anno_dat.s )
2824
3432
if ((a = miniexp_read()) != miniexp_dummy)
2825
3433
result = miniexp_cons(a, result);
3435
minilisp_getc = saved_getc;
3436
minilisp_ungetc = saved_ungetc;
3441
get_bytestream_anno(GP<ByteStream> annobs)
3443
if (! (annobs && annobs->size()))
3445
GP<IFFByteStream> iff = IFFByteStream::create(annobs);
3448
while (iff->get_chunk(chkid))
3451
if (chkid == "ANTa")
3452
bs = iff->get_bytestream();
3453
else if (chkid == "ANTz")
3454
bs = BSByteStream::create(iff->get_bytestream());
3456
anno_sub(bs, result);
3459
return miniexp_reverse(result);
3464
get_file_anno(GP<DjVuFile> file)
3466
// Make sure all data is present
3467
if (! file || ! file->is_all_data_present())
3469
if (file && file->is_data_present())
3471
if (! file->are_incl_files_created())
3472
file->process_incl_chunks();
3473
if (! file->are_incl_files_created())
3474
return miniexp_status(DDJVU_JOB_FAILED);
3476
return miniexp_dummy;
3478
// Access annotation data
3479
return get_bytestream_anno(file->get_merged_anno());
2829
3484
ddjvu_document_get_pageanno(ddjvu_document_t *document, int pageno)
2836
3491
document->pageinfoflag = true;
2837
GP<DjVuFile> file = doc->get_djvu_file(pageno);
2838
// Make sure all data is present
2839
if (! file || ! file->is_all_data_present())
2841
if (file->is_data_present())
2843
if (! file->are_incl_files_created())
2844
file->process_incl_chunks();
2845
if (! file->are_incl_files_created())
2846
return miniexp_status(DDJVU_JOB_FAILED);
2848
return miniexp_dummy;
2850
// Access annotation data
2851
GP<ByteStream> annobs = file->get_merged_anno();
2852
if (! (annobs && annobs->size()))
2855
GP<IFFByteStream> iff = IFFByteStream::create(annobs);
2857
while (iff->get_chunk(chkid))
2860
if (chkid == "ANTa")
2861
bs = iff->get_bytestream();
2862
else if (chkid == "ANTz")
2863
bs = BSByteStream::create(iff->get_bytestream());
2865
anno_sub(bs, result);
2868
result = miniexp_reverse(result);
2869
miniexp_protect(document, result);
3492
minivar_t result = get_file_anno( doc->get_djvu_file(pageno) );
3493
if (miniexp_consp(result))
3494
miniexp_protect(document, result);
2875
ERROR(document, ex);
3500
ERROR1(document, ex);
2878
3503
return miniexp_status(DDJVU_JOB_FAILED);
3508
ddjvu_document_get_anno(ddjvu_document_t *document, int compat)
3512
DjVuDocument *doc = document->doc;
3515
#if EXPERIMENTAL_DOCUMENT_ANNOTATIONS
3516
// not yet implemented
3517
GP<ByteStream> anno = doc->get_document_anno();
3519
return get_bytestream_anno(anno);
3523
// look for shared annotations
3524
int doc_type = doc->get_doc_type();
3525
if (doc_type != DjVuDocument::BUNDLED &&
3526
doc_type != DjVuDocument::INDIRECT )
3528
GP<DjVmDir> dir = doc->get_djvm_dir();
3529
int filenum = dir->get_files_num();
3530
GP<DjVmDir::File> fdesc;
3531
for (int i=0; i<filenum; i++)
3533
GP<DjVmDir::File> f = dir->pos_to_file(i);
3534
if (!f->is_shared_anno())
3542
GUTF8String id = fdesc->get_load_name();
3543
return get_file_anno(doc->get_djvu_file(id));
3550
ERROR1(document, ex);
2883
3559
/* ------ helpers for annotations ---- */