From 812aa90acbef4930ae356ab194f3f2a8f573f6e4 Mon Sep 17 00:00:00 2001 From: Martin Schröder Date: Tue, 26 Dec 2006 23:37:34 +0000 Subject: Import pdftex 1.40-rc4, which also changes the signature of print_version_and_exit, and adds a new library (libs/obsdcompat). git-svn-id: svn://tug.org/texlive/trunk@2959 c570f23f-e606-0410-a88d-b1316a301751 --- Build/source/texk/web2c/pdftexdir/writejbig2.c | 745 +++++++++++++++++++++++++ 1 file changed, 745 insertions(+) create mode 100644 Build/source/texk/web2c/pdftexdir/writejbig2.c (limited to 'Build/source/texk/web2c/pdftexdir/writejbig2.c') diff --git a/Build/source/texk/web2c/pdftexdir/writejbig2.c b/Build/source/texk/web2c/pdftexdir/writejbig2.c new file mode 100644 index 00000000000..15de6e101df --- /dev/null +++ b/Build/source/texk/web2c/pdftexdir/writejbig2.c @@ -0,0 +1,745 @@ +/*********************************************************************** +Copyright (c) 2002-2006 Han The Thanh, + +This file is part of pdfTeX. + +pdfTeX is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your option) +any later version. + +pdfTeX is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License along +with pdfTeX; if not, write to the Free Software Foundation, Inc., 59 +Temple Place, Suite 330, Boston, MA 02111-1307 USA + +This is experimental JBIG2 image support to pdfTeX. JBIG2 image decoding +is part of Adobe PDF-1.4, and requires Acroread 5.0 or later. + +References +========== + +* 14492 FCD: Information technology -- coded representation of picture +and audio information -- lossy/lossless coding of bi-level images / +JBIG committee, 1999 July 16. This JBIG2 Working Draft is available from +http://www.jpeg.org/public/fcd14492.pdf. The references in the C-code +correspond to the sections of this document. + +* PDF Reference, 5th edition, version 1.6, 1985--2005 Adobe Systems +Incorporated. Available online: + +http://partners.adobe.com/public/developer/en/pdf/PDFReference16.pdf + +News +==== + +31 May 2006: no need to wait for endoffileflag in sequential access +organization. + +10 May 2006: ygetc() for some catching of broken JBIG2 files; modify to +accept Example 3.4 from PDFRef 5th ed. with short end-of-file segment. + +09 May 2006: pages_maketree() and segments_maketree() by AVL tree, +some cleaning up. + +06 May 2006: File list replaced by AVL tree; new_fileinfo(), +new_pageinfo(). + +04 May 2006: Updated for pdftex-1.40-beta-20060213. + +08 Jan. 2003: Added flushjbig2page0objects() function. Now at the end +of the pdfTeX run all pending page0 objects are written out. + +08 Jan. 2003: Release on private webpage. + +04 Jan. 2003: Completely rewritten. Now with some data structures. +Rudimentary local file and image bookkeeping. Multiple image inclusion +from one JBIG2 file. Only required page0 segments are marked for +inclusion. + +13 Nov. 2002: pdfcrypting removed. + +08 Dec. 2002: bug in page 0 stream writing repaired. +Strategy for multiple page inclusion from same JBIG2 file: When writing +1st image, create fresh PDF object for page 0, and include any page +0 segments from complete file (even if these segments are not needed +for image). When writing next image, check by filename comparison if +PDF object for page 0 of this JBIG2 file has already been written. This +can only remember the file name for the direct predecessor JBIG2 image +(but images of other types might come inbetween). If such page 0 PDF +object exists, reference it. Else create fresh one. + +09 Dec. 2002: JBIG2 seg. page numbers > 0 are now set to 1, see PDF Ref. + +$Id: writejbig2.c,v 1.347 2006/05/31 19:18:32 hahe Exp hahe $ +***********************************************************************/ + +#include "writejbig2.h" +#undef DEBUG + +/**********************************************************************/ + +struct avl_table *file_tree = NULL; + +static int comp_file_entry(const void *pa, const void *pb, void *p) +{ + return strcmp(((const FILEINFO *) pa)->filename, + ((const FILEINFO *) pb)->filename); +} + +static int comp_page_entry(const void *pa, const void *pb, void *p) +{ + return ((const PAGEINFO *) pa)->pagenum - ((const PAGEINFO *) pb)->pagenum; +} + +static int comp_segment_entry(const void *pa, const void *pb, void *p) +{ + return ((const SEGINFO *) pa)->segnum - ((const SEGINFO *) pb)->segnum; +} + +/**********************************************************************/ + +int ygetc(FILE * stream) +{ + int c = getc(stream); + if (c < 0) { + if (c == EOF) + pdftex_fail("getc() failed; premature end of JBIG2 image file"); + else + pdftex_fail("getc() failed (can't happen)"); + } + return c; +} + +/**********************************************************************/ + +FILEINFO *new_fileinfo() +{ + FILEINFO *fip; + fip = xtalloc(1, FILEINFO); + fip->file = NULL; + fip->filename = NULL; + fip->filesize = 0; + initlinkedlist(&(fip->pages)); + initlinkedlist(&(fip->page0)); + fip->filehdrflags = 0; + fip->sequentialaccess = false; + fip->numofpages = 0; + fip->streamstart = 0; + fip->pdfpage0objnum = 0; + fip->phase = INITIAL; + return fip; +} + +PAGEINFO *new_pageinfo() +{ + PAGEINFO *pip; + pip = xtalloc(1, PAGEINFO); + initlinkedlist(&(pip->segments)); + pip->pagenum = 0; + pip->width = 0; + pip->height = 0; + pip->xres = 0; + pip->yres = 0; + pip->pagesegmentflags = 0; + pip->stripinginfo = 0; + pip->stripedheight = 0; + return pip; +} + +void init_seginfo(SEGINFO * sip) +{ + sip->segnum = 0; + sip->isrefered = false; + sip->refers = false; + sip->seghdrflags = 0; + sip->pageassocsizeflag = false; + sip->reftosegcount = 0; + sip->countofrefered = 0; + sip->fieldlen = 0; + sip->segnumwidth = 0; + sip->segpage = 0; + sip->segdatalen = 0; + sip->hdrstart = 0; + sip->hdrend = 0; + sip->datastart = 0; + sip->dataend = 0; + sip->endofstripeflag = false; + sip->endofpageflag = false; + sip->pageinfoflag = false; + sip->endoffileflag = false; +} + +/**********************************************************************/ + +void initlinkedlist(LIST * lp) +{ + lp->first = NULL; + lp->last = NULL; + lp->tree = NULL; +} + +LIST *litem_append(LIST * lp) +{ + LITEM *ip; + ip = xtalloc(1, LITEM); + if (lp->first == NULL) { + lp->first = ip; + ip->prev = NULL; + } else { + lp->last->next = ip; + ip->prev = lp->last; + } + lp->last = ip; + ip->next = NULL; + ip->d = NULL; + return lp; +} + +/**********************************************************************/ + +void pages_maketree(LIST * plp) +{ + LITEM *ip; + void **aa; + assert(plp->tree == NULL); + plp->tree = avl_create(comp_page_entry, NULL, &avl_xallocator); + assert(plp->tree != NULL); + for (ip = plp->first; ip != NULL; ip = ip->next) { + aa = avl_probe(plp->tree, (PAGEINFO *) ip->d); + assert(aa != NULL); + } +} + +void segments_maketree(LIST * slp) +{ + LITEM *ip; + void **aa; + assert(slp->tree == NULL); + slp->tree = avl_create(comp_segment_entry, NULL, &avl_xallocator); + assert(slp->tree != NULL); + for (ip = slp->first; ip != NULL; ip = ip->next) { + aa = avl_probe(slp->tree, (SEGINFO *) ip->d); + assert(aa != NULL); + } +} + +/**********************************************************************/ + +PAGEINFO *find_pageinfo(LIST * plp, unsigned long pagenum) +{ + PAGEINFO tmp; + tmp.pagenum = pagenum; + assert(plp->tree != NULL); + return (PAGEINFO *) avl_find(plp->tree, &tmp); +} + +SEGINFO *find_seginfo(LIST * slp, unsigned long segnum) +{ + SEGINFO tmp; + tmp.segnum = segnum; + assert(slp->tree != NULL); + return (SEGINFO *) avl_find(slp->tree, &tmp); +} + +/**********************************************************************/ + +unsigned int read2bytes(FILE * f) +{ + unsigned int c = ygetc(f); + return (c << 8) + ygetc(f); +} + +unsigned long read4bytes(FILE * f) +{ + unsigned int l = read2bytes(f); + return (l << 16) + read2bytes(f); +} + +/**********************************************************************/ + +unsigned long getstreamlen(LITEM * slip, boolean refer) +{ + SEGINFO *sip; + unsigned long len = 0; + for (; slip != NULL; slip = slip->next) { + sip = slip->d; + if (refer || sip->isrefered) + len += sip->hdrend - sip->hdrstart + sip->dataend - sip->datastart; + } + return len; +} + +/**********************************************************************/ + +void readfilehdr(FILEINFO * fip) +{ + unsigned int i; + /* Annex D.4 File header syntax */ + /* Annex D.4.1 ID string */ + unsigned char jbig2_id[] = { 0x97, 'J', 'B', '2', 0x0d, 0x0a, 0x1a, 0x0a }; + xfseek(fip->file, 0, SEEK_SET, fip->filename); + for (i = 0; i < 8; i++) + if (ygetc(fip->file) != jbig2_id[i]) + pdftex_fail + ("readfilehdr(): reading JBIG2 image file failed: ID string missing"); + /* Annex D.4.2 File header flags */ + fip->filehdrflags = ygetc(fip->file); + fip->sequentialaccess = (fip->filehdrflags & 0x01) ? true : false; + if (fip->sequentialaccess) { /* Annex D.1 vs. Annex D.2 */ + xfseek(fip->file, 0, SEEK_END, fip->filename); + fip->filesize = xftell(fip->file, fip->filename); + xfseek(fip->file, 9, SEEK_SET, fip->filename); + } + /* Annex D.4.3 Number of pages */ + if (!(fip->filehdrflags >> 1) & 0x01) /* known number of pages */ + fip->numofpages = read4bytes(fip->file); + /* --- at end of file header --- */ +} + +/**********************************************************************/ +/* for first reading of file; return value tells if header been read */ + +boolean readseghdr(FILEINFO * fip, SEGINFO * sip) +{ + unsigned int i; + sip->hdrstart = xftell(fip->file, fip->filename); + if (fip->sequentialaccess && sip->hdrstart == fip->filesize) + return false; /* no endoffileflag is ok for sequentialaccess */ +#ifdef DEBUG + printf("\nhdrstart %d\n", sip->hdrstart); +#endif + /* 7.2.2 Segment number */ + sip->segnum = read4bytes(fip->file); +#ifdef DEBUG + printf(" segnum %d\n", sip->segnum); +#endif + /* 7.2.3 Segment header flags */ + sip->seghdrflags = ygetc(fip->file); +#ifdef DEBUG + printf(" hdrflags %d\n", sip->seghdrflags & 0x3f); +#endif + checkseghdrflags(sip); + if (fip->sequentialaccess && sip->endoffileflag) /* accept shorter segment, */ + return true; /* makes it compliant with Example 3.4 of PDFRef. 5th ed. */ + sip->pageassocsizeflag = ((sip->seghdrflags >> 6) & 0x01) ? true : false; + /* 7.2.4 Referred-to segment count and retention flags */ + sip->reftosegcount = (unsigned int) ygetc(fip->file); + sip->countofrefered = sip->reftosegcount >> 5; + if (sip->countofrefered < 5) + sip->fieldlen = 1; + else { + sip->fieldlen = 5 + sip->countofrefered / 8; + xfseek(fip->file, sip->fieldlen - 1, SEEK_CUR, fip->filename); + } + /* 7.2.5 Referred-to segment numbers */ + if (sip->segnum <= 256) + sip->segnumwidth = 1; + else if (sip->segnum <= 65536) + sip->segnumwidth = 2; + else + sip->segnumwidth = 4; + for (i = 0; i < sip->countofrefered; i++) { + switch (sip->segnumwidth) { + case 1: + (void) ygetc(fip->file); + break; + case 2: + (void) read2bytes(fip->file); + break; + case 4: + (void) read4bytes(fip->file); + break; + } + } + /* 7.2.6 Segment page association */ + if (sip->pageassocsizeflag) + sip->segpage = read4bytes(fip->file); + else + sip->segpage = ygetc(fip->file); + /* 7.2.7 Segment data length */ + sip->segdatalen = read4bytes(fip->file); + sip->hdrend = xftell(fip->file, fip->filename); + /* ---- at end of segment header ---- */ + return true; +} + +/**********************************************************************/ +/* for writing, marks refered page0 segments, sets segpage > 0 to 1 */ + +void writeseghdr(FILEINFO * fip, SEGINFO * sip) +{ + unsigned int i; + unsigned long referedseg; + /* 7.2.2 Segment number */ + /* 7.2.3 Segment header flags */ + /* 7.2.4 Referred-to segment count and retention flags */ + for (i = 0; i < 5 + sip->fieldlen; i++) + pdfout(ygetc(fip->file)); + /* 7.2.5 Referred-to segment numbers */ + for (i = 0; i < sip->countofrefered; i++) { + switch (sip->segnumwidth) { + case 1: + referedseg = ygetc(fip->file); + pdfout(referedseg); + break; + case 2: + referedseg = read2bytes(fip->file); + pdfout((referedseg >> 8) & 0xff); + pdfout(referedseg & 0xff); + break; + case 4: + referedseg = read4bytes(fip->file); + pdfout((referedseg >> 24) & 0xff); + pdfout((referedseg >> 16) & 0xff); + pdfout((referedseg >> 8) & 0xff); + pdfout(referedseg & 0xff); + break; + } + if (fip->page0.last != NULL && !sip->refers) + markpage0seg(fip, referedseg); + } + if (sip->countofrefered > 0) + sip->refers = true; + /* 7.2.6 Segment page association */ + if (sip->pageassocsizeflag) + for (i = 0; i < 3; i++) { + (void) ygetc(fip->file); + pdfout(0); + } + (void) ygetc(fip->file); + pdfout((sip->segpage > 0) ? 1 : 0); + /* 7.2.7 Segment data length */ + for (i = 0; i < 4; i++) + pdfout(ygetc(fip->file)); + /* ---- at end of segment header ---- */ +} + +/**********************************************************************/ +/* for recursive marking of refered page0 segments */ + +void checkseghdr(FILEINFO * fip, SEGINFO * sip) +{ + unsigned int i; + unsigned long referedseg; + /* 7.2.2 Segment number */ + /* 7.2.3 Segment header flags */ + /* 7.2.4 Referred-to segment count and retention flags */ + xfseek(fip->file, 5 + sip->fieldlen, SEEK_CUR, fip->filename); + /* 7.2.5 Referred-to segment numbers */ + for (i = 0; i < sip->countofrefered; i++) { + switch (sip->segnumwidth) { + case 1: + referedseg = ygetc(fip->file); + break; + case 2: + referedseg = read2bytes(fip->file); + break; + case 4: + referedseg = read4bytes(fip->file); + break; + } + if (!sip->refers) + markpage0seg(fip, referedseg); + } + if (sip->countofrefered > 0) + sip->refers = true; + /* 7.2.6 Segment page association */ + /* 7.2.7 Segment data length */ + if (sip->pageassocsizeflag) + xfseek(fip->file, 8, SEEK_CUR, fip->filename); + else + xfseek(fip->file, 5, SEEK_CUR, fip->filename); + /* ---- at end of segment header ---- */ +} + +/**********************************************************************/ + +void checkseghdrflags(SEGINFO * sip) +{ + sip->endofstripeflag = false; + sip->endofpageflag = false; + sip->pageinfoflag = false; + sip->endoffileflag = false; + /* 7.3 Segment types */ + switch (sip->seghdrflags & 0x3f) { + case M_SymbolDictionary: + case M_IntermediateTextRegion: + case M_ImmediateTextRegion: + case M_ImmediateLosslessTextRegion: + case M_PatternDictionary: + case M_IntermediateHalftoneRegion: + case M_ImmediateHalftoneRegion: + case M_ImmediateLosslessHalftoneRegion: + case M_IntermediateGenericRegion: + case M_ImmediateGenericRegion: + case M_ImmediateLosslessGenericRegion: + case M_IntermediateGenericRefinementRegion: + case M_ImmediateGenericRefinementRegion: + case M_ImmediateLosslessGenericRefinementRegion: + break; + case M_PageInformation: + sip->pageinfoflag = true; + break; + case M_EndOfPage: + sip->endofpageflag = true; + break; + case M_EndOfStripe: + sip->endofstripeflag = true; + break; + case M_EndOfFile: + sip->endoffileflag = true; + break; + case M_Profiles: + case M_Tables: + case M_Extension: + break; + default: + pdftex_fail + ("checkseghdrflags(): unknown segment type in JBIG2 image file"); + break; + } +} + +/**********************************************************************/ + +void markpage0seg(FILEINFO * fip, unsigned long referedseg) +{ + PAGEINFO *pip; + SEGINFO *sip; + pip = fip->page0.first->d; + sip = find_seginfo(&(pip->segments), referedseg); + if (sip != NULL) { + if (!sip->refers && sip->countofrefered > 0) + checkseghdr(fip, sip); + sip->isrefered = true; + } +} + +/**********************************************************************/ + +unsigned long findstreamstart(FILEINFO * fip) +{ + SEGINFO tmp; + assert(!fip->sequentialaccess); /* D.2 Random-access organisation */ + do /* find random-access stream start */ + (void) readseghdr(fip, &tmp); + while (!tmp.endoffileflag); + fip->streamstart = tmp.hdrend; + readfilehdr(fip); + return fip->streamstart; +} + +/**********************************************************************/ + +void rd_jbig2_info(FILEINFO * fip) +{ + unsigned long seekdist = 0; /* for sequential-access only */ + unsigned long streampos = 0; /* for random-access only */ + unsigned long currentpage = 0; + boolean sipavail = false; + PAGEINFO *pip; + SEGINFO *sip; + LIST *plp, *slp; + fip->file = xfopen(fip->filename, FOPEN_RBIN_MODE); + readfilehdr(fip); + if (!fip->sequentialaccess) /* D.2 Random-access organisation */ + streampos = findstreamstart(fip); + while (true) { /* loop over segments */ + if (!sipavail) { + sip = xtalloc(1, SEGINFO); + sipavail = true; + } + init_seginfo(sip); + if (!readseghdr(fip, sip) || sip->endoffileflag) + break; + if (sip->segpage > 0) { + if (sip->segpage > currentpage) { + plp = litem_append(&(fip->pages)); + plp->last->d = new_pageinfo(); + currentpage = sip->segpage; + } + pip = fip->pages.last->d; + } else { + if (fip->page0.last == NULL) { + plp = litem_append(&(fip->page0)); + plp->last->d = new_pageinfo(); + } + pip = fip->page0.last->d; + } + if (!sip->endofpageflag) { + slp = litem_append(&(pip->segments)); + slp->last->d = sip; + sipavail = false; + } + if (!fip->sequentialaccess) + sip->datastart = streampos; + else + sip->datastart = sip->hdrend; + sip->dataend = sip->datastart + sip->segdatalen; + if (!fip->sequentialaccess + && (sip->pageinfoflag || sip->endofstripeflag)) + xfseek(fip->file, sip->datastart, SEEK_SET, fip->filename); + seekdist = sip->segdatalen; + /* 7.4.8 Page information segment syntax */ + if (sip->pageinfoflag) { + pip->pagenum = sip->segpage; + pip->width = read4bytes(fip->file); + pip->height = read4bytes(fip->file); + pip->xres = read4bytes(fip->file); + pip->yres = read4bytes(fip->file); + pip->pagesegmentflags = ygetc(fip->file); + /* 7.4.8.6 Page striping information */ + pip->stripinginfo = read2bytes(fip->file); + seekdist -= 19; + } + if (sip->endofstripeflag) { + pip->stripedheight = read4bytes(fip->file); + seekdist -= 4; + } + if (!fip->sequentialaccess + && (sip->pageinfoflag || sip->endofstripeflag)) + xfseek(fip->file, sip->hdrend, SEEK_SET, fip->filename); + if (!fip->sequentialaccess) + streampos += sip->segdatalen; + if (fip->sequentialaccess) + xfseek(fip->file, seekdist, SEEK_CUR, fip->filename); + if (sip->endofpageflag && currentpage && (pip->stripinginfo >> 15)) + pip->height = pip->stripedheight; + } + fip->phase = HAVEINFO; + if (sipavail) + xfree(sip); + xfclose(fip->file, fip->filename); +} + +/**********************************************************************/ + +void wr_jbig2(FILEINFO * fip, unsigned long page) +{ + LITEM *slip; + PAGEINFO *pip; + SEGINFO *sip; + unsigned long i; + if (page > 0) { + pip = find_pageinfo(&(fip->pages), page); + assert(pip != NULL); + pdf_puts("/Type /XObject\n"); + pdf_puts("/Subtype /Image\n"); + pdf_printf("/Width %i\n", pip->width); + pdf_printf("/Height %i\n", pip->height); + pdf_puts("/ColorSpace /DeviceGray\n"); + pdf_puts("/BitsPerComponent 1\n"); + pdf_printf("/Length %lu\n", getstreamlen(pip->segments.first, true)); + pdf_puts("/Filter [/JBIG2Decode]\n"); + if (fip->page0.last != NULL) { + if (fip->pdfpage0objnum == 0) { + pdfcreateobj(0, 0); + fip->pdfpage0objnum = objptr; + } + pdf_printf("/DecodeParms [<< /JBIG2Globals %lu 0 R >>]\n", + fip->pdfpage0objnum); + } + } else { + pip = find_pageinfo(&(fip->page0), page); + assert(pip != NULL); + pdfbegindict(fip->pdfpage0objnum, 0); + pdf_printf("/Length %lu\n", getstreamlen(pip->segments.first, false)); + } + pdf_puts(">>\n"); + pdf_puts("stream\n"); + fip->file = xfopen(fip->filename, FOPEN_RBIN_MODE); + for (slip = pip->segments.first; slip != NULL; slip = slip->next) { /* loop over page segments */ + sip = slip->d; + if (sip->isrefered || page > 0) { + xfseek(fip->file, sip->hdrstart, SEEK_SET, fip->filename); + /* mark refered-to page 0 segments, change segpages > 1 to 1 */ + writeseghdr(fip, sip); + xfseek(fip->file, sip->datastart, SEEK_SET, fip->filename); + for (i = sip->datastart; i < sip->dataend; i++) + pdfout(ygetc(fip->file)); + } + } + pdfendstream(); + xfclose(fip->file, fip->filename); +} + +/**********************************************************************/ + +void read_jbig2_info(integer img) +{ + FILEINFO *fip, tmp; + PAGEINFO *pip; + void **aa; + if (jbig2_ptr(img)->selected_page < 1) + pdftex_fail + ("read_jbig2_info(): page %d not in JBIG2 image file; page must be > 0", + (int) jbig2_ptr(img)->selected_page); + if (file_tree == NULL) { + file_tree = avl_create(comp_file_entry, NULL, &avl_xallocator); + assert(file_tree != NULL); + } + tmp.filename = img_name(img); + fip = (FILEINFO *) avl_find(file_tree, &tmp); + if (fip == NULL) { + fip = new_fileinfo(); + fip->filename = xstrdup(img_name(img)); + aa = avl_probe(file_tree, fip); + assert(aa != NULL); + } + if (fip->phase == INITIAL) { + rd_jbig2_info(fip); + pages_maketree(&(fip->pages)); + if (fip->page0.last != NULL) { + pages_maketree(&(fip->page0)); + pip = fip->page0.first->d; + segments_maketree(&(pip->segments)); + } + } + pip = find_pageinfo(&(fip->pages), jbig2_ptr(img)->selected_page); + if (pip == NULL) + pdftex_fail("read_jbig2_info(): page %d not found in JBIG2 image file", + (int) jbig2_ptr(img)->selected_page); + img_width(img) = pip->width; + img_height(img) = pip->height; + img_xres(img) = (int) (pip->xres * 0.0254 + 0.5); + img_yres(img) = (int) (pip->yres * 0.0254 + 0.5); +} + +/**********************************************************************/ + +void write_jbig2(integer img) +{ + FILEINFO *fip, tmp; + PAGEINFO *pip; + assert(file_tree != NULL); + tmp.filename = img_name(img); + fip = (FILEINFO *) avl_find(file_tree, &tmp); + assert(fip != NULL); + assert(fip->phase == HAVEINFO); /* don't write before rd_jbig2_info() call */ + pip = find_pageinfo(&(fip->pages), jbig2_ptr(img)->selected_page); + assert(pip != NULL); + wr_jbig2(fip, pip->pagenum); +} + +/**********************************************************************/ + +void flushjbig2page0objects() +{ + FILEINFO *fip; + struct avl_traverser t; + if (file_tree != NULL) { + avl_t_init(&t, file_tree); + for (fip = avl_t_first(&t, file_tree); fip != NULL; + fip = avl_t_next(&t)) { + if (fip->page0.last != NULL) + wr_jbig2(fip, 0); + } + } +} + +/**********************************************************************/ -- cgit v1.2.3