static void pdf_check_stream(PDF *p, size_t len) { size_t max; int cur; if (p->stream.curpos + len <= p->stream.maxpos) return; if (p->stream.flush & PDF_FLUSH_HEAVY) { pdf_flush_stream(p); if (p->stream.curpos + len <= p->stream.maxpos) return; } max = (size_t) (2 * (p->stream.maxpos - p->stream.basepos)); cur = p->stream.curpos - p->stream.basepos; p->stream.basepos = (pdf_byte *) p->realloc(p, (void *) p->stream.basepos, max, "pdf_check_stream"); p->stream.maxpos = p->stream.basepos + max; p->stream.curpos = p->stream.basepos + cur; pdf_check_stream(p, len); }
PDFLIB_API void PDFLIB_CALL PDF_close(PDF *p) { static const char fn[] = "PDF_close"; PDF_TRACE(("%s\t\t(pdf[%p]);\n", fn, (void *) p)); if (PDF_SANITY_CHECK_FAILED(p)) return; PDF_CHECK_SCOPE(p, fn, pdf_state_document); if (PDF_GET_STATE(p) != pdf_state_error) { if (p->current_page == 0) pdf_error(p, PDF_RuntimeError, "Empty document"); pdf_wrapup_document(p); /* dump the remaining PDF structures */ } pdf_flush_stream(p); pdf_cleanup_document(p); /* UPR stuff not released here but in PDF_delete() */ PDF_SET_STATE(p, fn, pdf_state_object); }
/* Finish the pattern definition. */ PDFLIB_API void PDFLIB_CALL PDF_end_pattern(PDF *p) { static const char fn[] = "PDF_end_pattern"; long length; PDF_TRACE(("%s\t(pdf[%p]);\n", fn, (void *) p)); if (PDF_SANITY_CHECK_FAILED(p)) return; PDF_CHECK_SCOPE(p, fn, pdf_state_pattern); /* check whether PDF_save() and PDF_restore() calls are balanced */ if (p->sl > 0) pdf_error(p, PDF_RuntimeError, "Unmatched save level at end of pattern"); pdf_end_text(p); p->contents = c_none; if (p->compresslevel) pdf_compress_end(p); length = pdf_tell(p) - p->start_contents_pos; pdf_end_stream(p); pdf_end_obj(p); /* pattern */ pdf_begin_obj(p, p->contents_length_id); /* Length object */ pdf_printf(p, "%ld\n", length); pdf_end_obj(p); pdf_begin_obj(p, p->res_id); /* Resource object */ pdf_begin_dict(p); /* Resource dict */ pdf_write_page_procsets(p); /* ProcSet resources */ pdf_write_page_fonts(p); /* Font resources */ pdf_write_page_colorspaces(p); /* Color space resources */ pdf_write_page_pattern(p); /* Pattern resources */ pdf_write_xobjects(p); /* XObject resources */ pdf_end_dict(p); /* resource dict */ pdf_end_obj(p); /* resource object */ PDF_POP_STATE(p, fn); if (p->flush & PDF_FLUSH_PAGE) pdf_flush_stream(p); }
PDFLIB_API void PDFLIB_CALL PDF_end_page(PDF *p) { static const char fn[] = "PDF_end_page"; int index; PDF_TRACE(("%s\t(pdf[%p]);\n", fn, (void *) p)); if (PDF_SANITY_CHECK_FAILED(p)) return; PDF_CHECK_SCOPE(p, fn, pdf_state_page); /* check whether PDF_save() and PDF_restore() calls are balanced */ if (p->sl > 0) pdf_error(p, PDF_RuntimeError, "Unmatched save level at end of page"); /* restore text parameter and color defaults for out-of-page usage. */ pdf_init_tstate(p); pdf_init_cstate(p); pdf_end_contents_section(p); /* Page object */ pdf_begin_obj(p, p->pages[p->current_page]); pdf_begin_dict(p); pdf_puts(p, "/Type/Page\n"); pdf_printf(p, "/Parent %ld 0 R\n", pdf_get_pnode_id(p)); p->res_id = pdf_alloc_id(p); pdf_printf(p, "/Resources %ld 0 R\n", p->res_id); pdf_printf(p, "/MediaBox[0 0 %f %f]\n", p->width, p->height); if (p->CropBox.llx != (float) 0 || p->CropBox.lly != (float) 0 || p->CropBox.urx != (float) 0 || p->CropBox.ury != (float) 0 ) { if (p->CropBox.urx <= p->CropBox.llx || p->CropBox.ury <= p->CropBox.lly) pdf_error(p, PDF_ValueError, "Illegal CropBox dimensions"); pdf_printf(p, "/CropBox[%f %f %f %f]\n", p->CropBox.llx, p->CropBox.lly, p->CropBox.urx, p->CropBox.ury); } if (p->BleedBox.llx != (float) 0 || p->BleedBox.lly != (float) 0 || p->BleedBox.urx != (float) 0 || p->BleedBox.ury != (float) 0 ) { if (p->BleedBox.urx <= p->BleedBox.llx || p->BleedBox.ury <= p->BleedBox.lly) pdf_error(p, PDF_ValueError, "Illegal BleedBox dimensions"); pdf_printf(p, "/BleedBox[%f %f %f %f]\n", p->BleedBox.llx, p->BleedBox.lly, p->BleedBox.urx, p->BleedBox.ury); } if (p->TrimBox.llx != (float) 0 || p->TrimBox.lly != (float) 0 || p->TrimBox.urx != (float) 0 || p->TrimBox.ury != (float) 0 ) { if (p->TrimBox.urx <= p->TrimBox.llx || p->TrimBox.ury <= p->TrimBox.lly) pdf_error(p, PDF_ValueError, "Illegal TrimBox dimensions"); pdf_printf(p, "/TrimBox[%f %f %f %f]\n", p->TrimBox.llx, p->TrimBox.lly, p->TrimBox.urx, p->TrimBox.ury); } if (p->ArtBox.llx != (float) 0 || p->ArtBox.lly != (float) 0 || p->ArtBox.urx != (float) 0 || p->ArtBox.ury != (float) 0 ) { if (p->ArtBox.urx <= p->ArtBox.llx || p->ArtBox.ury <= p->ArtBox.lly) pdf_error(p, PDF_ValueError, "Illegal ArtBox dimensions"); pdf_printf(p, "/ArtBox[%f %f %f %f]\n", p->ArtBox.llx, p->ArtBox.lly, p->ArtBox.urx, p->ArtBox.ury); } /* * The duration can be placed in the transition dictionary (/D) * or in the page dictionary (/Dur). We put it here so it can * be used without setting a transition effect. */ if (p->duration > 0) pdf_printf(p, "/Dur %f\n", p->duration); pdf_write_page_transition(p); pdf_puts(p, "/Contents["); for (index = 0; index < p->next_content; index++) { pdf_printf(p, "%ld 0 R", p->contents_ids[index]); pdf_putc(p, (char) (index + 1 % 8 ? PDF_SPACE : PDF_NEWLINE)); } pdf_puts(p, "]\n"); /* Thumbnail image */ if (p->thumb_id != BAD_ID) pdf_printf(p, "/Thumb %ld 0 R\n", p->thumb_id); pdf_write_annots_root(p); pdf_end_dict(p); /* Page object */ pdf_end_obj(p); pdf_write_page_annots(p); /* Annotation dicts */ pdf_begin_obj(p, p->res_id); /* resource object */ pdf_begin_dict(p); /* resource dict */ pdf_write_page_procsets(p); /* ProcSet resources */ pdf_write_page_fonts(p); /* Font resources */ pdf_write_page_colorspaces(p); /* Color space resources */ pdf_write_page_pattern(p); /* Pattern resources */ pdf_write_xobjects(p); /* XObject resources */ pdf_end_dict(p); /* resource dict */ pdf_end_obj(p); /* resource object */ pdf_cleanup_page(p); PDF_SET_STATE(p, fn, pdf_state_document); if (p->flush & PDF_FLUSH_PAGE) pdf_flush_stream(p); }
void pdf_write_page_annots(PDF *p) { pdf_annot *ann; long length, start_pos; id length_id; PDF_data_source src; for (ann = p->annots; ann != NULL; ann = ann->next) { pdf_begin_obj(p, ann->obj_id); /* Annotation object */ pdf_begin_dict(p); /* Annotation dict */ pdf_puts(p, "/Type/Annot\n"); switch (ann->type) { case ann_text: pdf_puts(p, "/Subtype/Text\n"); pdf_printf(p, "/Rect[%f %f %f %f]\n", ann->rect.llx, ann->rect.lly, ann->rect.urx, ann->rect.ury); pdf_write_border_style(p, ann); if (ann->open) pdf_puts(p, "/Open true\n"); if (ann->icon != icon_text_note) /* note is default */ pdf_printf(p, "/Name/%s\n", pdf_icon_names[ann->icon]); /* Contents key is required, but may be empty */ pdf_puts(p, "/Contents"); if (ann->contents) { pdf_quote_string(p, ann->contents); pdf_putc(p, PDF_NEWLINE); } else pdf_puts(p, "()\n"); /* empty contents is OK */ /* title is optional */ if (ann->title) { pdf_puts(p, "/T"); pdf_quote_string(p, ann->title); pdf_putc(p, PDF_NEWLINE); } break; case ann_locallink: pdf_puts(p, "/Subtype/Link\n"); pdf_printf(p, "/Rect[%f %f %f %f]\n", ann->rect.llx, ann->rect.lly, ann->rect.urx, ann->rect.ury); pdf_write_border_style(p, ann); /* preallocate page object id for a later page */ if (ann->dest.page > p->current_page) { while (ann->dest.page >= p->pages_capacity) pdf_grow_pages(p); /* if this page has already been used as a link target * it will already have an object id. */ if (p->pages[ann->dest.page] == BAD_ID) p->pages[ann->dest.page] = pdf_alloc_id(p); } if (ann->dest.type == retain) { pdf_printf(p, "/Dest[%ld 0 R/XYZ null null 0]\n", p->pages[ann->dest.page]); } else if (ann->dest.type == fitpage) { pdf_printf(p, "/Dest[%ld 0 R/Fit]\n", p->pages[ann->dest.page]); } else if (ann->dest.type == fitwidth) { pdf_printf(p, "/Dest[%ld 0 R/FitH 0]\n", p->pages[ann->dest.page]); } else if (ann->dest.type == fitheight) { pdf_printf(p, "/Dest[%ld 0 R/FitV 0]\n", p->pages[ann->dest.page]); } else if (ann->dest.type == fitbbox) { pdf_printf(p, "/Dest[%ld 0 R/FitB]\n", p->pages[ann->dest.page]); } break; case ann_pdflink: pdf_puts(p, "/Subtype/Link\n"); pdf_printf(p, "/Rect[%f %f %f %f]\n", ann->rect.llx, ann->rect.lly, ann->rect.urx, ann->rect.ury); pdf_write_border_style(p, ann); pdf_puts(p, "/A"); pdf_begin_dict(p); /* A dict */ pdf_puts(p, "/Type/Action/S/GoToR\n"); if (ann->dest.type == retain) { pdf_printf(p, "/D[%d 0 R/XYZ null null 0]\n", ann->dest.page-1); /* zero-based */ } else if (ann->dest.type == fitpage) { /* zero-based */ pdf_printf(p, "/D[%d 0 R/Fit]\n", ann->dest.page-1); } else if (ann->dest.type == fitwidth) { /* Trick: we don't know the height of a future page yet, * so we use a "large" value for top which will do for * most pages. If it doesn't work, not much harm is done. */ /* zero-based */ pdf_printf(p, "/D[%d 0 R/FitH 2000]\n", ann->dest.page-1); } else if (ann->dest.type == fitheight) { /* zero-based */ pdf_printf(p, "/D[%d 0 R/FitV 0]\n", ann->dest.page-1); } else if (ann->dest.type == fitbbox) { /* zero-based */ pdf_printf(p, "/D[%d 0 R/FitB]\n", ann->dest.page-1); } pdf_puts(p, "/F"); pdf_begin_dict(p); /* F dict */ pdf_puts(p, "/Type/FileSpec\n"); pdf_printf(p, "/F("); pdf_puts(p, ann->filename); pdf_puts(p,")\n"); pdf_end_dict(p); /* F dict */ pdf_end_dict(p); /* A dict */ break; case ann_launchlink: pdf_puts(p, "/Subtype/Link\n"); pdf_printf(p, "/Rect[%f %f %f %f]\n", ann->rect.llx, ann->rect.lly, ann->rect.urx, ann->rect.ury); pdf_write_border_style(p, ann); pdf_puts(p, "/A"); pdf_begin_dict(p); /* A dict */ pdf_puts(p, "/Type/Action/S/Launch\n"); pdf_puts(p, "/F"); pdf_begin_dict(p); /* F dict */ pdf_puts(p, "/Type/FileSpec\n"); pdf_printf(p, "/F("); pdf_puts(p, ann->filename); pdf_puts(p,")\n"); pdf_end_dict(p); /* F dict */ pdf_end_dict(p); /* A dict */ break; case ann_weblink: pdf_puts(p, "/Subtype/Link\n"); pdf_printf(p, "/Rect[%f %f %f %f]\n", ann->rect.llx, ann->rect.lly, ann->rect.urx, ann->rect.ury); pdf_write_border_style(p, ann); pdf_printf(p, "/A<</S/URI/URI("); pdf_puts(p, ann->filename); pdf_puts(p, ")>>\n"); break; case ann_attach: pdf_puts(p, "/Subtype/FileAttachment\n"); pdf_printf(p, "/Rect[%f %f %f %f]\n", ann->rect.llx, ann->rect.lly, ann->rect.urx, ann->rect.ury); pdf_write_border_style(p, ann); if (ann->icon != icon_file_pushpin) /* pushpin is default */ pdf_printf(p, "/Name/%s\n", pdf_icon_names[ann->icon]); if (ann->title) { pdf_puts(p, "/T"); pdf_quote_string(p, ann->title); pdf_putc(p, PDF_NEWLINE); } if (ann->contents) { pdf_puts(p, "/Contents"); pdf_quote_string(p, ann->contents); pdf_putc(p, PDF_NEWLINE); } /* the icon is too small without these flags (=28) */ pdf_printf(p, "/F %d\n", pdf_ann_flag_print | pdf_ann_flag_nozoom | pdf_ann_flag_norotate); pdf_puts(p, "/FS"); pdf_begin_dict(p); /* FS dict */ pdf_puts(p, "/Type/FileSpec\n"); pdf_printf(p, "/F("); pdf_puts(p, ann->filename); pdf_puts(p, ")\n"); /* alloc id for the actual embedded file stream */ ann->obj_id = pdf_alloc_id(p); pdf_printf(p, "/EF<</F %ld 0 R>>\n", ann->obj_id); pdf_end_dict(p); /* FS dict */ break; default: pdf_error(p, PDF_SystemError, "Unknown annotation type %d", ann->type); } pdf_end_dict(p); /* Annotation dict */ pdf_end_obj(p); /* Annotation object */ } /* Write the actual embedded files with preallocated ids */ for (ann = p->annots; ann != NULL; ann = ann->next) { if (ann->type != ann_attach) continue; pdf_begin_obj(p, ann->obj_id); /* EmbeddedFile */ pdf_puts(p, "<</Type/EmbeddedFile\n"); if (ann->mimetype) pdf_printf(p, "/Subtype (%s)\n", ann->mimetype); if (p->compresslevel) pdf_puts(p, "/Filter/FlateDecode\n"); length_id = pdf_alloc_id(p); pdf_printf(p, "/Length %ld 0 R\n", length_id); pdf_end_dict(p); /* F dict */ pdf_begin_stream(p); /* Embedded file stream */ start_pos = pdf_tell(p); /* write the file in the PDF */ src.private_data = (void *) ann->filename; src.init = pdf_data_source_file_init; src.fill = pdf_data_source_file_fill; src.terminate = pdf_data_source_file_terminate; src.length = (long) 0; src.offset = (long) 0; pdf_compress(p, &src); length = pdf_tell(p) - start_pos; pdf_end_stream(p); /* Embedded file stream */ pdf_end_obj(p); /* EmbeddedFile object */ pdf_begin_obj(p, length_id); /* Length object */ pdf_printf(p, "%ld\n", length); pdf_end_obj(p); /* Length object */ if (p->flush & PDF_FLUSH_CONTENT) pdf_flush_stream(p); } }
void pdf_put_image(PDF *p, int im, pdf_bool firststrip) { id length_id; long length; pdf_image *image; int i; image = &p->images[im]; /* york: how to check? see also F-imagecolor! switch (image->colorspace) { case ImageMask: case DeviceGray: case Indexed: case DeviceRGB: case DeviceCMYK: break; default: pdf_error(p, PDF_SystemError, "Unknown color space"); break; } */ /* Images may also be written to the output before the first page */ if (PDF_GET_STATE(p) == pdf_state_page) pdf_end_contents_section(p); /* Image object */ image->no = pdf_new_xobject(p, image_xobject, NEW_ID); pdf_begin_dict(p); /* XObject */ pdf_puts(p, "/Type/XObject\n"); pdf_puts(p, "/Subtype/Image\n"); pdf_printf(p,"/Width %d\n", (int) image->width); pdf_printf(p,"/Height %d\n", (int) image->height); pdf_printf(p,"/BitsPerComponent %d\n", image->bpc); /* * Transparency handling */ /* Masking by color: single transparent color value */ if (image->transparent) { if (image->colorspace == Indexed || image->colorspace == DeviceGray) pdf_printf(p,"/Mask[%d %d]\n", (int) image->transval[0], (int) image->transval[0]); else if (image->colorspace == DeviceRGB) pdf_printf(p,"/Mask[%d %d %d %d %d %d]\n", (int) image->transval[0], (int) image->transval[0], (int) image->transval[1], (int) image->transval[1], (int) image->transval[2], (int) image->transval[2]); else if (image->colorspace == DeviceCMYK) pdf_printf(p,"/Mask[%d %d %d %d %d %d %d %d]\n", (int) image->transval[0], (int) image->transval[0], (int) image->transval[1], (int) image->transval[1], (int) image->transval[2], (int) image->transval[2], (int) image->transval[3], (int) image->transval[3]); else pdf_error(p, PDF_SystemError, "Unknown color space with transparency"); /* Masking by position: separate bitmap mask */ } else if (image->mask != -1) { pdf_printf(p, "/Mask %ld 0 R\n", p->xobjects[p->images[image->mask].no].obj_id); } switch (image->colorspace) { case ImageMask: pdf_puts(p, "/ImageMask true\n"); break; case Indexed: if (firststrip) image->colormap_id = pdf_alloc_id(p); pdf_puts(p, "/ColorSpace[/Indexed/DeviceRGB "); pdf_printf(p, "%d %ld 0 R]\n", image->palette_size - 1, image->colormap_id); break; default: /* colorize the image with a spot color */ if (image->colorspace >= LastCS) { /* TODO: reconsider spot color numbering scheme */ int spot = image->colorspace - LastCS; p->colorspaces[spot].used_on_current_page = pdf_true; pdf_printf(p, "/ColorSpace %ld 0 R\n", p->colorspaces[spot].obj_id); /* the following is tricky: /Separation color space * always works as a subtractive color space. The * image, however, is Grayscale, and therefore * additive. */ if (firststrip) { image->invert = !image->invert; } } else { pdf_printf(p, "/ColorSpace/%s\n", pdf_colorspace_names[image->colorspace]); } break; } /* special case: referenced image data instead of direct data */ if (image->reference != pdf_ref_direct) { if (image->compression != none) { pdf_printf(p, "/FFilter[/%s]\n", pdf_filter_names[image->compression]); } if (image->compression == ccitt) { pdf_puts(p, "/FDecodeParms[<<"); if ((int) image->width != 1728) /* CCITT default width */ pdf_printf(p, "/Columns %d", (int) image->width); pdf_printf(p, "/Rows %d", (int) image->height); /* write CCITT parameters if required */ if (image->params) pdf_puts(p, image->params); pdf_puts(p, ">>]\n"); } if (image->reference == pdf_ref_file) { /* LATER: make image file name platform-neutral: * Change : to / on the Mac * Change \ to / on Windows */ pdf_printf(p, "/F(%s)/Length 0", image->filename); } else if (image->reference == pdf_ref_url) { pdf_printf(p, "/F<</FS/URL/F(%s)>>/Length 0", image->filename); } pdf_end_dict(p); /* XObject */ pdf_begin_stream(p); /* dummy image data */ pdf_end_stream(p); /* dummy image data */ if (PDF_GET_STATE(p) == pdf_state_page) pdf_begin_contents_section(p); pdf_end_obj(p); /* XObject */ return; } /* * Now the (more common) handling of actual image * data to be included in the PDF output. */ /* do we need a filter (either ASCII or decompression)? */ if (p->debug['a']) { pdf_puts(p, "/Filter[/ASCIIHexDecode"); if (image->compression != none) pdf_printf(p, "/%s", pdf_filter_names[image->compression]); pdf_puts(p, "]\n"); } else { /* force compression if not a recognized precompressed image format */ if (!image->use_raw && p->compresslevel) image->compression = flate; if (image->compression != none) pdf_printf(p, "/Filter[/%s]\n", pdf_filter_names[image->compression]); } /* prepare precompressed (raw) image data */ if (image->use_raw) { pdf_printf(p, "/DecodeParms[%s<<", (p->debug['a'] ? "null" : "")); /* write EarlyChange or CCITT parameters if required */ if (image->params) pdf_puts(p, image->params); if (image->compression == flate || image->compression == lzw) { if (image->predictor != pred_default) { pdf_printf(p, "/Predictor %d", (int) image->predictor); pdf_printf(p, "/Columns %d", (int) image->width); if (image->bpc != 8) pdf_printf(p, "/BitsPerComponent %d", image->bpc); if (image->colorspace < LastCS) { switch (image->colorspace) { case Indexed: case ImageMask: case DeviceGray: /* 1 is default */ break; case DeviceRGB: pdf_puts(p, "/Colors 3"); break; case DeviceCMYK: pdf_puts(p, "/Colors 4"); break; default: pdf_error(p, PDF_SystemError, "Unknown colorspace (%d)", (int )image->colorspace); break; } } } } if (image->compression == ccitt) { if ((int) image->width != 1728) /* CCITT default width */ pdf_printf(p, "/Columns %d", (int) image->width); pdf_printf(p, "/Rows %d", (int) image->height); } pdf_puts(p, ">>]\n"); /* DecodeParms dict and array */ } if (image->invert) { pdf_puts(p, "/Decode[1 0"); for (i = 1; i < image->components; i++) pdf_puts(p, " 1 0"); pdf_puts(p, "]\n"); } /* Write the actual image data */ length_id = pdf_alloc_id(p); pdf_printf(p,"/Length %ld 0 R\n", length_id); pdf_end_dict(p); /* XObject */ pdf_begin_stream(p); /* image data */ p->start_contents_pos = pdf_tell(p); /* image data */ if (p->debug['a']) pdf_ASCIIHexEncode(p, &image->src); else { if (image->use_raw) pdf_copy(p, &image->src); else pdf_compress(p, &image->src); } length = pdf_tell(p) - p->start_contents_pos; pdf_end_stream(p); /* image data */ pdf_end_obj(p); /* XObject */ pdf_begin_obj(p, length_id); /* Length object */ pdf_printf(p,"%ld\n", length); pdf_end_obj(p); if (p->flush & PDF_FLUSH_CONTENT) pdf_flush_stream(p); /* Image data done */ /* * Write colormap information for indexed color spaces */ if (firststrip && image->colorspace == Indexed) { pdf_begin_obj(p, image->colormap_id); /* colormap object */ pdf_begin_dict(p); if (p->debug['a']) pdf_puts(p, "/Filter[/ASCIIHexDecode]\n"); else if (p->compresslevel) pdf_puts(p, "/Filter[/FlateDecode]\n"); /* Length of colormap object */ length_id = pdf_alloc_id(p); pdf_printf(p,"/Length %ld 0 R\n", length_id); pdf_end_dict(p); pdf_begin_stream(p); /* colormap data */ p->start_contents_pos = pdf_tell(p); if (image->components != 1) { pdf_error(p, PDF_SystemError, "Bogus indexed colorspace (%d color components)", image->components); } image->src.init = pdf_noop; image->src.fill = pdf_data_source_buf_fill; image->src.terminate = pdf_noop; image->src.buffer_start = (unsigned char *) image->colormap; image->src.buffer_length= (size_t) (image->palette_size * 3); image->src.bytes_available = 0; image->src.next_byte = NULL; /* Write colormap data */ if (p->debug['a']) pdf_ASCIIHexEncode(p, &image->src); else { pdf_compress(p, &image->src); } length = pdf_tell(p) - p->start_contents_pos; pdf_end_stream(p); /* Colormap data */ pdf_end_obj(p); /* Colormap object */ pdf_begin_obj(p, length_id); /* Length object for colormap */ pdf_printf(p, "%ld\n", length); pdf_end_obj(p); /* Length object for colormap */ } if (PDF_GET_STATE(p) == pdf_state_page) pdf_begin_contents_section(p); if (p->flush & PDF_FLUSH_CONTENT) pdf_flush_stream(p); }