static void display_djvm_dirm(ByteStream & out_str, IFFByteStream & iff, GUTF8String head, size_t, DjVmInfo& djvminfo, int) { GP<DjVmDir> dir = DjVmDir::create(); dir->decode(iff.get_bytestream()); GPList<DjVmDir::File> list = dir->get_files_list(); if (dir->is_indirect()) { out_str.format( "Document directory (indirect, %d files %d pages)", dir->get_files_num(), dir->get_pages_num()); for (GPosition p=list; p; ++p) out_str.format( "\n%s%s -> %s", (const char*)head, (const char*)list[p]->get_load_name(), (const char*)list[p]->get_save_name() ); } else { out_str.format( "Document directory (bundled, %d files %d pages)", dir->get_files_num(), dir->get_pages_num()); djvminfo.dir = dir; djvminfo.map.empty(); for (GPosition p=list; p; ++p) djvminfo.map[list[p]->offset] = list[p]; } }
void PageInfo::DecodeText(GP<ByteStream> pTextStream) { if (pTextStream == NULL) return; pTextStream->seek(0); GP<DjVuText> pDjVuText = DjVuText::create(); pDjVuText->decode(pTextStream); pText = pDjVuText->txt; bTextDecoded = true; }
void PageInfo::DecodeAnno(GP<ByteStream> pAnnoStream) { if (pAnnoStream == NULL) return; pAnnoStream->seek(0); GP<DjVuAnno> pDjVuAnno = DjVuAnno::create(); pDjVuAnno->decode(pAnnoStream); pAnt = pDjVuAnno->ant; if (pAnt != NULL) { for (GPosition pos = pAnt->map_areas; pos; ++pos) { GP<GMapArea> pArea = pAnt->map_areas[pos]; anno.push_back(Annotation()); anno.back().Init(pArea, szPage, nInitialRotate); } } bAnnoDecoded = true; }
PageInfo DjVuSource::ReadPageInfo(int nPage, bool bNeedText, bool bNeedAnno) { ASSERT(nPage >= 0 && nPage < m_nPageCount); PageInfo pageInfo; pageInfo.szPage.cx = 100; pageInfo.szPage.cy = 100; pageInfo.nDPI = 100; pageInfo.bDecoded = true; GP<ByteStream> pAnnoStream; if (bNeedAnno) pAnnoStream = ByteStream::create(); GP<ByteStream> pTextStream; if (bNeedText) pTextStream = ByteStream::create(); try { // Get raw data from the document and decode only requested chunks // DjVuFile is not used to ensure that we do not wait for a lock // to be released and thus do not block the UI thread GURL url = m_pDjVuDoc->page_to_url(nPage); GP<DataPool> pool = m_pDjVuDoc->request_data(NULL, url); GP<ByteStream> stream = pool->get_stream(); GP<IFFByteStream> iff(IFFByteStream::create(stream)); // Check file format GUTF8String chkid; if (!iff->get_chunk(chkid) || (chkid != "FORM:DJVI" && chkid != "FORM:DJVU" && chkid != "FORM:PM44" && chkid != "FORM:BM44")) { return pageInfo; } bool bHasIW44 = false; // Find chunk with page info while (iff->get_chunk(chkid) != 0) { GP<ByteStream> chunk_stream = iff->get_bytestream(); if (chkid == "INFO") { // Get page dimensions and resolution from info chunk GP<DjVuInfo> pInfo = DjVuInfo::create(); pInfo->decode(*chunk_stream); // Check data for consistency pageInfo.szPage.cx = max(pInfo->width, 0); pageInfo.szPage.cy = max(pInfo->height, 0); pageInfo.nInitialRotate = pInfo->orientation; pageInfo.nDPI = max(pInfo->dpi, 0); if ((pInfo->orientation & 1) != 0) swap(pageInfo.szPage.cx, pageInfo.szPage.cy); } else if (!bHasIW44 && (chkid == "PM44" || chkid == "BM44")) { bHasIW44 = true; // Get image dimensions and resolution from bitmap chunk UINT serial = chunk_stream->read8(); UINT slices = chunk_stream->read8(); UINT major = chunk_stream->read8(); UINT minor = chunk_stream->read8(); UINT xhi = chunk_stream->read8(); UINT xlo = chunk_stream->read8(); UINT yhi = chunk_stream->read8(); UINT ylo = chunk_stream->read8(); pageInfo.szPage.cx = (xhi << 8) | xlo; pageInfo.szPage.cy = (yhi << 8) | ylo; pageInfo.nDPI = 100; } else if (chkid == "TXTa" || chkid == "TXTz") { pageInfo.bHasText = true; if (bNeedText) { const GP<IFFByteStream> iffout = IFFByteStream::create(pTextStream); iffout->put_chunk(chkid); iffout->copy(*chunk_stream); iffout->close_chunk(); } } else if (bNeedAnno && chkid == "FORM:ANNO") { pAnnoStream->copy(*chunk_stream); } else if (bNeedAnno && (chkid == "ANTa" || chkid == "ANTz")) { const GP<IFFByteStream> iffout = IFFByteStream::create(pAnnoStream); iffout->put_chunk(chkid); iffout->copy(*chunk_stream); iffout->close_chunk(); } else if (bNeedAnno && chkid == "INCL") { set<GUTF8String> processed; ReadAnnotations(chunk_stream, processed, pAnnoStream); } iff->seek_close_chunk(); } if (bNeedText && pTextStream->tell()) pageInfo.DecodeText(pTextStream); if (bNeedAnno && pAnnoStream->tell()) pageInfo.DecodeAnno(pAnnoStream); } catch (GException&) { } catch (...) { if (pApplication != NULL) pApplication->ReportFatalError(); } return pageInfo; }