diff options
Diffstat (limited to 'support/dktools/dk3pdf.ctr')
-rw-r--r-- | support/dktools/dk3pdf.ctr | 4233 |
1 files changed, 4233 insertions, 0 deletions
diff --git a/support/dktools/dk3pdf.ctr b/support/dktools/dk3pdf.ctr new file mode 100644 index 0000000000..afcab2fd66 --- /dev/null +++ b/support/dktools/dk3pdf.ctr @@ -0,0 +1,4233 @@ +%% options + +copyright owner = Dirk Krause +copyright year = 2011-xxxx +license = bsd + + + +%% header + +#ifdef __cplusplus +extern "C" { +#endif + +/** Create PDF writer structure. + @param app Application structure, required here. + @return Pointer to new structure on success, NULL on error. +*/ +dk3_pdf_t * +dk3pdf_open_app(dk3_app_t *app); + +/** Write PDF to output file. + @param pdf PDF writer structure. + @param ofile Output file. + @return 1 on success, 0 on error. +*/ +int +dk3pdf_write_file(dk3_pdf_t *pdf, FILE *ofile); + +/** Write PDF to output file. + @param pdf PDF writer structure. + @param ofile Output file. + @param pcomm Communicator object. + @param minpb Minimum progress bar value. + @param maxpb Maximum progress bar value. + @return 1 on success, 0 on error. +*/ +int +dk3pdf_write_file_progress( + dk3_pdf_t *pdf, + FILE *ofile, + void *pcomm, + int minpb, + int maxpb +); + +/** Destroy PDF writer structure, release memory. + @param pdf Structure to destroy. +*/ +void +dk3pdf_close(dk3_pdf_t *pdf); + +/** Prepare media box for next page to open. + @param pdf PDF writer structure. + @param x0 Left x. + @param x1 Right x. + @param y0 Bottom y. + @param y1 Top y. +*/ +void +dk3pdf_set_next_mediabox( + dk3_pdf_t *pdf, + long x0, + long x1, + long y0, + long y1 +); + +/** Open a new page. + @param pdf PDF writer structure. + @return 1 on success, 0 on error. +*/ +int +dk3pdf_open_page(dk3_pdf_t *pdf); + +/** Open a new page, set clip path to media box. + @param pdf PDF writer structure. + @param wc Flag: With clip path setting. + @return 1 on success, 0 on error. +*/ +int +dk3pdf_open_page_with_clip(dk3_pdf_t *pdf, int wc); + +/** Close the current page. + @param pdf PDF writer structure. + @return 1 on success, 0 on error. +*/ +int +dk3pdf_close_page(dk3_pdf_t *pdf); + +/** Write save graphics state instruction to current page. + @param pdf PDF writer structure. + @return 1 on success, 0 on error. +*/ +int +dk3pdf_gsave(dk3_pdf_t *pdf); + +/** Write restore graphics state instruction to current page. + @param pdf PDF writer structure. + @return 1 on success, 0 on error. +*/ +int +dk3pdf_grestore(dk3_pdf_t *pdf); + +/** Translate coordinates, use long values. + @param pdf PDF writer structure. + @param x X translation. + @param y Y translation. + @return 1 on success, 0 on error. +*/ +int +dk3pdf_translate_long(dk3_pdf_t *pdf, long x, long y); + +/** Translate coordinates, use double values. + @param pdf PDF writer structure. + @param x X translation. + @param y Y translation. + @return 1 on success, 0 on error. +*/ +int +dk3pdf_translate_double(dk3_pdf_t *pdf, double x, double y); + +/** Rotate coordinates, use integer value. + @param pdf PDF writer structure. + @param angle Rotation angle in degree. + @return 1 on success, 0 on error. +*/ +int +dk3pdf_rotate_int(dk3_pdf_t *pdf, int angle); + +/** Rotate coordinates, use double value. + @param pdf PDF writer structure. + @param angle Rotation angle in degree. + @return 1 on success, 0 on error. +*/ +int +dk3pdf_rotate_double(dk3_pdf_t *pdf, double angle); + +/** Scale coordinates, use long values. + @param pdf PDF writer structure. + @param x X scale factor. + @param y Y scale factor. + @return 1 on success, 0 on error. +*/ +int +dk3pdf_scale_long(dk3_pdf_t *pdf, long x, long y); + +/** Scale coordinates, use double values. + @param pdf PDF writer structure. + @param x X scale factor. + @param y Y scale factor. + @return 1 on success, 0 on error. +*/ +int +dk3pdf_scale_double(dk3_pdf_t *pdf, double x, double y); + +/** Add XObject to current page. + @param pdf PDF writer structure. + @param xo XObject to add. + @return 1 on success, 0 on error. +*/ +int +dk3pdf_add_xobject_to_page(dk3_pdf_t *pdf, dk3_pdf_xobject_t *xo); + +/** Add image. + @param pdf PDF writer structure. + @param bif Image, the current frame will be added. + @param opt Conversion options. + @param pc Communicator object. + @param min Minimum progress bar value (0-1000). + @param max Maximum progress bar value (0-1000). + @return Pointer to object on success, NULL on error. +*/ +dk3_pdf_xobject_t * +dk3pdf_add_image_progress( + dk3_pdf_t *pdf, + dk3_bif_t *bif, + dk3_bm_eps_options_t *opt, + void *pc, + int min, + int max +); + +/** Add image. + @param pdf PDF writer structure. + @param bif Image, the current frame will be added. + @param opt Conversion options. + @return Pointer to object on success, NULL on error. +*/ +dk3_pdf_xobject_t * +dk3pdf_add_image( + dk3_pdf_t *pdf, + dk3_bif_t *bif, + dk3_bm_eps_options_t *opt +); + +/** PDF newpath and lineto. Start new path and move to specified position. + @param pdf PDF writer structure. + @param x New x position. + @param y New y position. + @return 1 on success, 0 on error. +*/ +int +dk3pdf_newpath_moveto(dk3_pdf_t *pdf, double x, double y); + +/** PDF lineto. + @param pdf PDF writer structure. + @param x New x + @param y New y. + @return 1 on success, 0 on error. +*/ +int +dk3pdf_lineto(dk3_pdf_t *pdf, double x, double y); + +/** PDF curveto. + @param pdf PDF writer structure. + @param xcs Control point X near start. + @param ycs Control point Y near start. + @param xce Control point X near end. + @param yce Control point Y near end. + @param xe End point X. + @param ye End point Y. + @return 1 on success, 0 on error. +*/ +int +dk3pdf_curveto( + dk3_pdf_t *pdf, + double xcs, double ycs, + double xce, double yce, + double xe, double ye +); + +/** Set nonstroking gray. + @param pdf PDF writer structure. + @param g New gray value. + @return 1 on success, 0 on error. +*/ +int +dk3pdf_set_nonstroking_gray(dk3_pdf_t *pdf, double g); + +/** Set stroking gray. + @param pdf PDF writer structure. + @param g New gray value. + @return 1 on success, 0 on error. +*/ +int +dk3pdf_set_stroking_gray(dk3_pdf_t *pdf, double g); + +/** Close path, fill (non-zero winding rule), and stroke path. + @param pdf PDF writer structure. + @return 1 on success, 0 on error. +*/ +int +dk3pdf_closepath_fill_stroke_nz(dk3_pdf_t *pdf); + +/** Close path, fill (even/odd rule), and stroke path. + @param pdf PDF writer structure. + @return 1 on success, 0 on error. +*/ +int +dk3pdf_closepath_fill_stroke_eo(dk3_pdf_t *pdf); + +/** Close path. + @param pdf PDF writer structure. + @return 1 on success, 0 on error. +*/ +int +dk3pdf_closepath(dk3_pdf_t *pdf); + +/** Fill current path (non-zero winding rule). + @param pdf PDF writer structure. + @return 1 on success, 0 on error. +*/ +int +dk3pdf_fill_nz(dk3_pdf_t *pdf); + +/** Fill current path (even/odd rule). + @param pdf PDF writer structure. + @return 1 on success, 0 on error. +*/ +int +dk3pdf_fill_eo(dk3_pdf_t *pdf); + +/** Clip to current path (even/odd rule). + @param pdf PDF writer structure. + @return 1 on success, 0 on error. +*/ +int +dk3pdf_clip_eo(dk3_pdf_t *pdf); + +/** Clip to current path (non-zero rule). + @param pdf PDF writer structure. + @return 1 on success, 0 on error. +*/ +int +dk3pdf_clip_nz(dk3_pdf_t *pdf); + +/** Set RGB color for nonstroking operations. + @param pdf PDF writer structure. + @param r Red. + @param g Green. + @param b Blue. + @return 1 on success, 0 on error. +*/ +int +dk3pdf_nonstroking_rgb(dk3_pdf_t *pdf, double r, double g, double b); + +/** Set RGB color for stroking operations. + @param pdf PDF writer structure. + @param r Red. + @param g Green. + @param b Blue. + @return 1 on success, 0 on error. +*/ +int +dk3pdf_stroking_rgb(dk3_pdf_t *pdf, double r, double g, double b); + +/** Set line cap mode. + @param pdf PDF writer structure. + @param lc Line cap DK3_LINECAP_xxx, see @ref linecap. + @return 1 on success, 0 on error. +*/ +int +dk3pdf_set_linecap(dk3_pdf_t *pdf, int lc); + +/** Set line join mode. + @param pdf PDF writer structure. + @param lj Line cap DK3_LINECAP_xxx, see @ref linecap. + @return 1 on success, 0 on error. +*/ +int +dk3pdf_set_linejoin(dk3_pdf_t *pdf, int lj); + +/** Set line dash pattern. + @param pdf PDF writer structure. + @param sv Style values array. + @param nsv Number of elements in sv. + @param ph Phase (initial shift). + @return 1 on success, 0 on error. +*/ +int +dk3pdf_set_line_dash(dk3_pdf_t *pdf, double *sv, size_t nsv, double ph); + +/** Stroke current path. + @param pdf PDF writer structure. + @return 1 on success, 0 on error. +*/ +int +dk3pdf_stroke(dk3_pdf_t *pdf); + +/** Set line width for stroke operations. + @param pdf PDF writer structure. + @param lw New line width. + @return 1 on success, 0 on error. +*/ +int +dk3pdf_set_linewidth(dk3_pdf_t *pdf, double lw); + +/** Create image XObject. + @param pdf PDF writer structure. + @param bif Image, the current frame will be added. + @param opt Conversion options. + @param pc Communication object. + @param min Minimum progress bar value (0-1000). + @param max Maximum progress bar value (0-1000). + @return Pointer to new object on success, NULL on error. +*/ +dk3_pdf_xobject_t * +dk3pdf_create_ixobject_progress( + dk3_pdf_t *pdf, + dk3_bif_t *bif, + dk3_bm_eps_options_t *opt, + void *pc, + int min, + int max +); + +/** Write debug line to graphics contents stream. + @param pdf PDF output structure. + @param txt Text to write. + @return 1 on success, 0 on error. +*/ +int +dk3pdf_write_debug_line(dk3_pdf_t *pdf, char const *txt); + +#ifdef __cplusplus +} +#endif + + + +%% module + +/* + Object numbers + -------------- + 1 Info object (producer) + 2 Root object (type catalog, reference to pages object) + 3 Pages object, reference to page) + + Xobject dictionary object (assign names to object numbers) + + Page object (references to xobject dictionary, contents stream) + Page contents stream object, compressed + +*/ + + + +#include "dk3all.h" +#include "dk3pdf.h" +#include "dk3bmj.h" +#include "dk3bif.h" +#include "dk3bifa.h" + + +$!trace-include + + + +/** Start position of PDF object. +*/ +typedef struct { + + /** Object number. + */ + unsigned long objno; + + /** Start position in file or stream. + */ + dk3_um_t startpos; + +} dk3_pdf_object_start_t; + + + +/** Job information for PDF writing. +*/ +typedef struct { + + /** The PDF writer structure to write to file. + */ + dk3_pdf_t *pdf; + + /** Output file. + */ + FILE *of; + + /** Output stream. + */ + dk3_stream_t *os; + + /** Object start position collection. + */ + dk3_sto_t *s_objstart; + + /** Iterator for object start positions. + */ + dk3_sto_it_t *i_objstart; + + /** Object number for first page to show. + */ + unsigned long firstPageObjectNumber; + + /** Largest object number seen. + */ + unsigned long largestObjectNumber; + + /** Height of first page. + */ + dk3_bif_coord_t firstPageHeight; + +} dk3_pdf_writer_job_t; + + + +/** Conversion job for one image. +*/ +typedef struct { + + /** Output PDF. + */ + dk3_pdf_t *pdf; + + /** XObject to produce. + */ + dk3_pdf_xobject_t *xo; + + /** Output filter. + */ + dk3_of_t *of; + + /** Conversion option set. + */ + dk3_bm_eps_options_t *opt; + + /** Input image. + */ + dk3_bif_t *bif; + + /** Conversion procedure, DK3_BMEPS_xxx, see @ref bmepscompression. + */ + int procedure; + + /** Flag: Color data found. + */ + int h_color; + + /** Flag: Alpha data found. + */ + int h_alpha; + + /** Bits per component. + */ + int bpc; + + /** Flag: Use dct. + */ + int use_dct; + +} dk3_pdf_image_job_t; + + + +/** Keywords used by the dk3pdf module. +*/ +static char const * dk3pdf_c8_kw[] = { +/* 0 */ "\n", +/* 1 */ " ", +/* 2 */ "q\n", +/* 3 */ "Q\n", +/* 4 */ "cm\n", +/* 5 */ "/X", +/* 6 */ " Do\n", +/* 7 */ "%PDF-1.4\n", +/* 8 */ " 0 obj\n", +/* 9 */ "endobj\n", +/* 10 */ "<<\n/Producer (http://dktools.sourceforge.net)\n", +/* 11 */ "<<\n", +/* 12 */ ">>\n", +/* 13 */ "/Type /Catalog\n", +/* 14 */ "/Pages 3 0 R\n", +/* 15 */ "/OpenAction [ ", +/* 16 */ " 0 R /FitH ", +/* 17 */ " ]\n", +/* 18 */ "xref 0 ", +/* 19 */ "0000000000 65535 f \n", +/* 20 */ "0", +/* 21 */ " 00000 n \n", +/* 22 */ "trailer\n<< /Size ", +/* 23 */ " /Info 1 0 R /Root 2 0 R >>\nstartxref\n", +/* 24 */ "\n%%EOF\n", +/* 25 */ "stream\n", +/* 26 */ "\nendstream\n", +/* 27 */ "/Type /XObject\n", +/* 28 */ "/Subtype /Image\n", +/* 29 */ "/Width ", +/* 30 */ "/Height ", +/* 31 */ "/BitsPerComponent ", +/* 32 */ "/ColorSpace ", +/* 33 */ "/DeviceCMYK\n", +/* 34 */ "/DeviceGray\n", +/* 35 */ "/DeviceRGB\n", +/* 36 */ "/Filter ", +/* 37 */ "/FlateDecode\n", +/* 38 */ "/DCTDecode\n", +/* 39 */ "/Length ", +/* 40 */ "/Decode [ 1 0 1 0 1 0 1 0 ]\n", +/* 41 */ "/Predictor 2\n", +/* 42 */ "/Predictor 11\n", +/* 43 */ "/Predictor 12\n", +/* 44 */ "/Predictor 13\n", +/* 45 */ "/Predictor 14\n", +/* 46 */ "/SMask ", +/* 47 */ " 0 R\n", +/* 48 */ "/Type /Page\n", +/* 49 */ "/Parent 3 0 R\n", +/* 50 */ "/MediaBox [ %ld %ld %ld %ld ]\n", +/* 51 */ "/Resources ", +/* 52 */ "/ProcSet [ /PDF /ImageB /ImageC ]\n", +/* 53 */ "/XObject %lu 0 R\n", +/* 54 */ "/Contents %lu 0 R\n", +/* 55 */ "/Group << /S /Transparency /I true /CS /DeviceRGB >>\n", +/* 56 */ "/X%lu %lu 0 R\n", +/* 57 */ "/Type /Pages\n", +/* 58 */ "/Count ", +/* 59 */ "%lu\n", +/* 60 */ "/Kids [\n", +/* 61 */ "]\n", +/* 62 */ "%lu 0 R\n", +/* 63 */ "/Interpolate true\n", +/* 64 */ "/DecodeParms <<\n", +/* 65 */ "/Colors ", +/* 66 */ "4", +/* 67 */ "1", +/* 68 */ "3", +/* 69 */ "/Columns ", +/* 70 */ "%lg", +/* 71 */ "m\n", /* PDF moveto */ +/* 72 */ "l\n", /* PDF lineto */ +/* 73 */ "g\n", /* PDF nonstroke setgray */ +/* 74 */ "G\n", /* PDF stroke setgray */ +/* 75 */ "b\n", /* PDF closepath, fill (nonzero), and stroke */ +/* 76 */ "B\n", /* PDF fill (nonzero), and stroke */ +/* 77 */ "b*\n", /* PDF closepath, fill (even/odd), and stroke */ +/* 78 */ "B*\n", /* PDF fill (even/odd), and stroke */ +/* 79 */ "f\n", /* PDF fill (nonzero) */ +/* 80 */ "f*\n", /* PDF fill (even/odd) */ +/* 81 */ "h\n", /* PDF closepath */ +/* 82 */ "rg\n", /* PDF setrgbcolor (nonstroking) */ +/* 83 */ "RG\n", /* PDF setrgbcolor (stroking) */ +/* 84 */ "2", /* PDF Line cap style square */ +/* 85 */ " J\n", /* PDF setlinecap */ +/* 86 */ "s\n", /* PDF closepath and stroke */ +/* 87 */ " w\n", /* PDF setlinewidth */ +/* 88 */ "W* n\n", /* PDF eoclip */ +/* 89 */ "c\n", /* PDF curveto */ +/* 90 */ " j\n", /* PDF setlinejoin */ +/* 91 */ " d\n", /* PDF setdash */ +/* 92 */ "[", +/* 93 */ "]", +/* 94 */ " S\n", /* PDF stroke */ +/* 95 */ "%ld", +/* 96 */ " re W n\n", /* PDF re eoclip */ +/* 97 */ " W n\n", +/* 98 */ "% ", +/* 99 */ "0", +/* 100 */ "/CropBox [ %ld %ld %ld %ld ]\n", +/* 101 */ "%04d%02d%02d%02d%02d%02d", +/* 102 */ "/CreationDate (D:", +/* 103 */ ")\n/ModDate (D:", +/* 104 */ ")\n", +}; + + + +/** Adjust a value to a given range. + @param min Range minimum. + @param max Range maximum. + @param val Uncorrected value. + @return Value, corrected if necessary. +*/ +static +double +dk3pdf_to_range(double min, double max, double val) +{ + double back; + $? "+ dk3pdf_to_range min=%lg max=%lg val=%lg", min, max, val + back = val; + if(back < min) { back = min; } + if(back > max) { back = max; } $? "- dk3pdf_to_range %lg", back + return back; +} + + + +/** Compare to PDF pages. + @param l Left pointer. + @param r Right pointer. + @param cr Comparison criteria (0=page/page, 1=page/number). + @return Comparison result. +*/ +static +int +dk3pdf_compare_pages(void const *l, void const *r, int cr) +{ + dk3_pdf_page_t const *pl; /* Left page object. */ + dk3_pdf_page_t const *pr; /* Right page object. */ + unsigned long const *ul; /* Page number. */ + int back = 0; + if(l) { + if(r) { + pl = (dk3_pdf_page_t const *)l; + switch(cr) { + case 1: { + ul = (unsigned long const *)r; + if(pl->pageno > *ul) { + back = 1; + } else { + if(pl->pageno < *ul) { + back = -1; + } + } + } break; + default: { + pr = (dk3_pdf_page_t const *)r; + if(pl->pageno > pr->pageno) { + back = 1; + } else { + if(pl->pageno < pr->pageno) { + back = -1; + } + } + } break; + } + } else { + back = 1; + } + } else { + if(r) { + back = -1; + } + } + return back; +} + + + +/** Compare two object start entries. + @param l Left pointer. + @param r Right pointer. + @param cr Comparison criteria (ignored). + @return Comparison result. +*/ +static +int +dk3pdf_compare_object_start(void const *l, void const *r, int cr) +{ + int back = 0; + dk3_pdf_object_start_t const *pl; /* Left object start. */ + dk3_pdf_object_start_t const *pr; /* Right object start. */ + if(l) { + if(r) { + pl = (dk3_pdf_object_start_t const *)l; + pr = (dk3_pdf_object_start_t const *)r; + if(pl->objno > pr->objno) { + back = 1; + } else { + if(pl->objno < pr->objno) { + back = -1; + } + } + } else { + back = 1; + } + } else { + if(r) { + back = -1; + } + } + return back; +} + + + +/** Compare Xobjects. + @param l Left object. + @param r Right object. + @param cr Comparison criteria (ignored). + @return Comparison result (0=xobject/xobject, 1=xobject/number). +*/ +static +int +dk3pdf_compare_xobjects(void const *l, void const *r, int cr) +{ + int back = 0; + dk3_pdf_xobject_t const *pl; /* Left XObject. */ + dk3_pdf_xobject_t const *pr; /* Right XObject. */ + unsigned long const *ul; /* Right XObject number. */ + if(l) { + if(r) { + pl = (dk3_pdf_xobject_t const *)l; + switch(cr) { + case 1: { + ul = (unsigned long const *)r; + if(pl->objno > *ul) { + back = 1; + } else { + if(pl->objno < *ul) { + back = -1; + } + } + } break; + default: { + pr = (dk3_pdf_xobject_t const *)r; + if(pl->objno > pr->objno) { + back = 1; + } else { + if(pl->objno < pr->objno) { + back = -1; + } + } + } break; + } + } else { + back = 1; + } + } else { + if(r) { + back = -1; + } + } + return back; +} + + + +/** Initialize PDF job. + @param job PDF creator job. + @param pdf PDF structure. + @param of Output filter. + @return 1 on success, 0 on error. +*/ +static +int +dk3pdf_job_init(dk3_pdf_writer_job_t *job, dk3_pdf_t *pdf, FILE *of) +{ + int back = 0; + $? "+ dk3pdf_job_init" + job->of = NULL; + job->os = NULL; + job->s_objstart = NULL; + job->i_objstart = NULL; + job->largestObjectNumber = 0UL; + job->firstPageObjectNumber = 0UL; + job->firstPageHeight = 0L; + if((pdf) && (of)) { + job->of = of; + job->pdf = pdf; + job->os = dk3stream_open_file_app(of, DK3_STREAM_FLAG_WRITE, pdf->app); + if(job->os) { + job->s_objstart = dk3sto_open_app(pdf->app); + if(job->s_objstart) { + dk3sto_set_comp(job->s_objstart, dk3pdf_compare_object_start, 0); + job->i_objstart = dk3sto_it_open(job->s_objstart); + if(job->i_objstart) { $? ". ok" + back = 1; + } else { $? "! iterator" + } + } else { $? "! storage" + } + } else { $? "! stream" + } + } else { $? "! arguments" + } $? "- dk3pdf_job_init %d", back + return back; +} + + + +/** Clean up PDF writer job. + @param job Job to clean up. +*/ +static +void +dk3pdf_job_end(dk3_pdf_writer_job_t *job) +{ + dk3_pdf_position_t *pos; /* Traverse start position collection. */ + $? "+ dk3pdf_job_end" + if(job->os) { + dk3stream_close(job->os); + } + job->os = NULL; + if(job->i_objstart) { + dk3sto_it_reset(job->i_objstart); + while((pos = (dk3_pdf_position_t *)dk3sto_it_next(job->i_objstart)) != NULL) + { + dk3_delete(pos); + } + dk3sto_it_close(job->i_objstart); + } + job->i_objstart = NULL; + if(job->s_objstart) { + dk3sto_close(job->s_objstart); + } + job->s_objstart = NULL; $? "- dk3pdf_job_end" +} + + + +/** Destroy XObject, release memory. + @param xo Object to destroy. +*/ +static +void +dk3pdf_xobject_delete(dk3_pdf_xobject_t *xo) +{ + $? "+ dk3pdf_xobject_delete" + if(xo) { $? ". object %lu", xo->objno + if(xo->tempfilename) { + dk3sf_remove_file_app(xo->tempfilename, NULL); + dk3_delete(xo->tempfilename); + } + xo->tempfilename = NULL; + xo->mask = NULL; + xo->width = 0L; + xo->height = 0L; + xo->objno = 0UL; + xo->xot = 0; + xo->procedure = DK3_BMEPS_RGB_FLATE; + xo->bpc = 0; + xo->dct = 0; + xo->pred = 0; + dk3_delete(xo); + } $? "- dk3pdf_xobject_delete" +} + + + +/** Create image XObject, allocate memory. + @param pdf PDF structure. + @return Pointer to new XObject on success, NULL on error. +*/ +static +dk3_pdf_xobject_t * +dk3pdf_xobject_new(dk3_pdf_t *pdf) +{ + dkChar buf[DK3_MAX_PATH]; /* Buffer for conversion. */ + dk3_pdf_xobject_t *back = NULL; + int ok = 0; /* Flag: Success so far. */ + $? "+ dk3pdf_xobject_new" + back = dk3_new_app(dk3_pdf_xobject_t,1,pdf->app); + if(back) { + back->tempfilename = NULL; + back->mask = NULL; + back->width = 0L; + back->height = 0L; + back->objno = 0UL; + back->xot = DK3_PDF_XO_TYPE_IMAGE; + back->procedure = 0; + back->bpc = 8; + back->dct = 0; + back->pred = 0; + back->slgt = DK3_UM_0; + back->adobe_marker_found = 0; + back->interpolate = 0; + if(dk3app_get_temp_file_name(pdf->app, buf, DK3_SIZEOF(buf,dkChar))) { + back->tempfilename = dk3str_dup_app(buf, pdf->app); + if(back->tempfilename) { + ok = 1; + } + } + if(!(ok)) { + dk3pdf_xobject_delete(back); + back = NULL; + } + } $? "- dk3pdf_xobject_new %!8s", TR_8PTR(back) + return back; +} + + + +/** Destroy page object, release memory. + @param pa Page object to destroy. +*/ +void +dk3pdf_page_delete(dk3_pdf_page_t *pa) +{ + $? "+ dk3pdf_page_delete" + if(pa) { $? ". object %lu page %lu", pa->objno, pa->pageno + if(pa->tempof) { + dk3of_close(pa->tempof); + } + if(pa->tempstream) { + dk3stream_close(pa->tempstream); + } + if(pa->tempfile) { + fclose(pa->tempfile); + } + if(pa->tempfilename) { + dk3sf_remove_file_app(pa->tempfilename,NULL); + dk3_delete(pa->tempfilename); + } + if(pa->i_xobjects) { + dk3sto_it_close(pa->i_xobjects); + } + if(pa->s_xobjects) { + dk3sto_close(pa->s_xobjects); + } + pa->tempfilename = NULL; + pa->tempfile = NULL; + pa->tempstream = NULL; + pa->tempof = NULL; + pa->s_xobjects = NULL; + pa->i_xobjects = NULL; + pa->objno = 0UL; + pa->pageno = 0UL; + pa->mbx0 = 0L; + pa->mbx1 = 0L; + pa->mby0 = 0L; + pa->mby1 = 0L; + dk3_delete(pa); + } $? "- dk3pdf_page_delete" +} + + + +/** Create new page object. + @param pdf PDF structure. + @return Pointer to new page object on success, NULL on error. +*/ +static +dk3_pdf_page_t * +dk3pdf_page_new(dk3_pdf_t *pdf) +{ + dkChar fnb[DK3_MAX_PATH]; /* Conversion buffer. */ + dk3_pdf_page_t *back = NULL; + int ok = 0; /* Flag: OK so far. */ + $? "+ dk3pdf_page_new" + if(dk3app_get_temp_file_name(pdf->app, fnb, DK3_SIZEOF(fnb,dkChar))) { + back = dk3_new_app(dk3_pdf_page_t,1,pdf->app); + if(back) { + back->tempfilename = NULL; + back->tempfile = NULL; + back->tempstream = NULL; + back->tempof = NULL; + back->s_xobjects = NULL; + back->i_xobjects = NULL; + back->objno = 0UL; + back->pageno = pdf->nextpage; + back->mbx0 = pdf->mbx0; + back->mbx1 = pdf->mbx1; + back->mby0 = pdf->mby0; + back->mby1 = pdf->mby1; + back->slgt = DK3_UM_0; + back->tempfilename = dk3str_dup_app(fnb, pdf->app); + if(back->tempfilename) { + back->tempfile = dk3sf_fopen_app( + back->tempfilename, + dk3app_not_localized(53), + pdf->app + ); + } + if(back->tempfile) { + back->tempstream = dk3stream_open_file_app( + back->tempfile, + DK3_STREAM_FLAG_WRITE, + pdf->app + ); + } + if(back->tempstream) { + back->tempof = dk3of_open_app(back->tempstream, pdf->app); + if(back->tempof) { + if(dk3of_add_cell(back->tempof, DK3_OF_CELL_TYPE_FLATE)) { + back->s_xobjects = dk3sto_open_app(pdf->app); + if(back->s_xobjects) { + back->i_xobjects = dk3sto_it_open(back->s_xobjects); + if(back->i_xobjects) { + ok = 1; + } + } + } + } + } + if(!(ok)) { + dk3pdf_page_delete(back); + back = NULL; + } + } + } $? "- dk3pdf_page_new %!8s", TR_8PTR(back) + return back; +} + + + + +dk3_pdf_t * +dk3pdf_open_app(dk3_app_t *app) +{ + dk3_pdf_t *back = NULL; + int ok = 0; /* Flag: Success. */ + $? "+ dk3pdf_open_app" + if(app) { + back = dk3_new_app(dk3_pdf_t,1,app); + if(back) { + back->app = app; + back->s_xobjects = NULL; + back->i_xobjects = NULL; + back->s_pages = NULL; + back->i_pages = NULL; + back->cp = NULL; + back->nextobject = 4UL; + back->nextpage = 0UL; + back->mbx0 = 0L; + back->mbx1 = 595L; + back->mby0 = 0L; + back->mby1 = 842L; + back->documentMode = 0; + back->s_xobjects = dk3sto_open_app(app); + if(back->s_xobjects) { + dk3sto_set_comp(back->s_xobjects, dk3pdf_compare_xobjects, 0); + back->i_xobjects = dk3sto_it_open(back->s_xobjects); + } + back->s_pages = dk3sto_open_app(app); + if(back->s_pages) { + dk3sto_set_comp(back->s_pages, dk3pdf_compare_pages, 0); + back->i_pages = dk3sto_it_open(back->s_pages); + } + if(back->s_xobjects) { + if(back->i_xobjects) { + if(back->s_pages) { + if(back->i_pages) { + ok = 1; + } + } + } + } + if(!(ok)) { + dk3pdf_close(back); + back = NULL; + } + } + } $? "- dk3pdf_open_app %!8s", TR_8PTR(back) + return back; +} + + + +void +dk3pdf_close(dk3_pdf_t *pdf) +{ + dk3_pdf_xobject_t *xo; /* Traverse XObjects collection to clean up. */ + dk3_pdf_page_t *pa; /* Traverse page collection to clean up. */ + $? "+ dk3pdf_close" + if(pdf) { + if(pdf->s_xobjects) { + if(pdf->i_xobjects) { + dk3sto_it_reset(pdf->i_xobjects); + while((xo = (dk3_pdf_xobject_t *)dk3sto_it_next(pdf->i_xobjects)) + != NULL + ) + { + dk3pdf_xobject_delete(xo); + } + dk3sto_it_close(pdf->i_xobjects); + } + dk3sto_close(pdf->s_xobjects); + } + pdf->s_xobjects = NULL; + pdf->i_xobjects = NULL; + if(pdf->s_pages) { + if(pdf->i_pages) { + dk3sto_it_reset(pdf->i_pages); + while((pa = (dk3_pdf_page_t *)dk3sto_it_next(pdf->i_pages)) != NULL) { + dk3pdf_page_delete(pa); + } + dk3sto_it_close(pdf->i_pages); + } + dk3sto_close(pdf->s_pages); + } + pdf->s_pages = NULL; + pdf->i_pages = NULL; + pdf->s_xobjects = NULL; + dk3_delete(pdf); + } $? "- dk3pdf_close" +} + + + + +void +dk3pdf_set_next_mediabox( + dk3_pdf_t *pdf, + long x0, + long x1, + long y0, + long y1 +) +{ + if(pdf) { + pdf->mbx0 = x0; + pdf->mbx1 = x1; + pdf->mby0 = y0; + pdf->mby1 = y1; + } $? "= dk3pdf_set_next_mediabox x0=%ld y0=%ld x1=%ld y1=%ld", x0, y0, x1, y1 +} + + + +/** Write long value. + @param of Output filter stream. + @param x Value to write. +*/ +static +void +dk3pdf_write_long(dk3_of_t *of, long x) +{ + char buf[64]; /* Conversion buffer. */ + sprintf(buf, dk3pdf_c8_kw[95], x); + dk3of_write_c8_string(of, buf); $? "= dk3pdf_write_long %ld", x +} + + + +int +dk3pdf_open_page_with_clip(dk3_pdf_t *pdf, int wc) +{ + dk3_pdf_page_t *np; /* Next page pointer. */ + int back = 0; +#if 1 + long x; + long y; + long w; + long h; +#endif + $? "+ dk3pdf_open_page" + if(pdf) { + if(pdf->cp) { + dk3pdf_close_page(pdf); + } + np = dk3pdf_page_new(pdf); + if(np) { + if(dk3sto_add(pdf->s_pages, (void *)np)) { + pdf->nextpage += 1UL; + pdf->cp = np; + if(np->tempof) { + back = dk3of_start_chunk(np->tempof); + if(back) { + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[2]); + if(wc) { + /* 2013-01-10: Set clip path. + */ + if(np->mbx0 < np->mbx1) { + x = np->mbx0; w = np->mbx1 - np->mbx0; + } else { + x = np->mbx1; w = np->mbx0 - np->mbx1; + } + if(np->mby0 < np->mby1) { + y = np->mby0; h = np->mby1 - np->mby0; + } else { + y = np->mby1; h = np->mby0 - np->mby1; + } + dk3pdf_write_long((pdf->cp)->tempof, x); + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[1]); + dk3pdf_write_long((pdf->cp)->tempof, y); + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[1]); + dk3pdf_write_long((pdf->cp)->tempof, w); + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[1]); + dk3pdf_write_long((pdf->cp)->tempof, h); + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[96]); + } + } + } + } + } + } $? "- dk3pdf_open_page %d", back + return back; +} + + + +int +dk3pdf_open_page(dk3_pdf_t *pdf) +{ + int back; + back = dk3pdf_open_page_with_clip(pdf, 0); + return back; +} + + + +int +dk3pdf_close_page(dk3_pdf_t *pdf) +{ + dk3_stat_t stb; /* Stat buffer for contents stream file. */ + int back = 0; + $? "+ dk3pdf_close_page" + if(pdf) { + if(pdf->cp) { + if((pdf->cp)->tempof) { + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[3]); + back = dk3of_end_chunk((pdf->cp)->tempof); + dk3of_close((pdf->cp)->tempof); + (pdf->cp)->tempof = NULL; + } + if((pdf->cp)->tempstream) { + dk3stream_close((pdf->cp)->tempstream); + (pdf->cp)->tempstream = NULL; + } + if((pdf->cp)->tempfile) { + if(!dk3sf_fclose_fn_app( + (pdf->cp)->tempfile, (pdf->cp)->tempfilename, pdf->app + ) + ) + { + back = 0; + } + pdf->cp->tempfile = NULL; + } + if((pdf->cp)->tempfilename) { + if(dk3sf_stat_app(&stb, (pdf->cp)->tempfilename, pdf->app)) { + (pdf->cp)->slgt = stb.sz; + } else { + back = 0; + /* ERROR: Stat failed for content stream! */ + } + } + } + pdf->cp = NULL; + } $? "- dk3pdf_close_page %d", back + return back; +} + + + +int +dk3pdf_gsave(dk3_pdf_t *pdf) +{ + int back = 0; + $? "+ dk3pdf_gsave" + if(pdf) { + if(pdf->cp) { + if((pdf->cp)->tempof) { + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[2]); + back = 1; + } + } + } $? "- dk3pdf_gsave %d", back + return back; +} + + + +int +dk3pdf_grestore(dk3_pdf_t *pdf) +{ + int back = 0; + $? "+ dk3pdf_grestore" + if(pdf) { + if(pdf->cp) { + if((pdf->cp)->tempof) { + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[3]); + back = 1; + } + } + } $? "- dk3pdf_grestore %d", back + return back; +} + + + +/** Change current transformation matrix. + @param of Output filter to write to. + @param cmv Matrix values. +*/ +static +void +dk3pdf_cm_long(dk3_of_t *of, long *cmv) +{ + char buf[64]; /* Conversion buffer. */ + $? "+ dk3pdf_cm_long" + sprintf(buf, "%ld", cmv[0]); + dk3of_write_c8_string(of, buf); + dk3of_write_c8_string(of, dk3pdf_c8_kw[1]); + sprintf(buf, "%ld", cmv[1]); + dk3of_write_c8_string(of, buf); + dk3of_write_c8_string(of, dk3pdf_c8_kw[1]); + sprintf(buf, "%ld", cmv[2]); + dk3of_write_c8_string(of, buf); + dk3of_write_c8_string(of, dk3pdf_c8_kw[1]); + sprintf(buf, "%ld", cmv[3]); + dk3of_write_c8_string(of, buf); + dk3of_write_c8_string(of, dk3pdf_c8_kw[1]); + sprintf(buf, "%ld", cmv[4]); + dk3of_write_c8_string(of, buf); + dk3of_write_c8_string(of, dk3pdf_c8_kw[1]); + sprintf(buf, "%ld", cmv[5]); + dk3of_write_c8_string(of, buf); + dk3of_write_c8_string(of, dk3pdf_c8_kw[1]); + dk3of_write_c8_string(of, dk3pdf_c8_kw[4]); + dk3of_write_c8_string(of, dk3pdf_c8_kw[0]); $? "- dk3pdf_cm_long" +} + + + +/** Write double value, correct comma to dot. + @param of Output filter stream. + @param x Value to write. +*/ +static +void +dk3pdf_write_double(dk3_of_t *of, double x) +{ +#if VERSION_BEFORE_20140722 + char buf[64]; /* Conversion buffer. */ + char *ptr; + sprintf(buf, dk3pdf_c8_kw[70], x); + ptr = buf; + while(*ptr) { if(*ptr == ',') { *ptr = '.'; } ptr++; } + dk3of_write_c8_string(of, buf); $? "= dk3pdf_write_double %lg", x +#else + if (1.0e-8 <= fabs(x)) { + (void)dk3of_double_to_c8_no_sci(of, x); + } else { + dk3of_write_c8_string(of, dk3pdf_c8_kw[99]); + } +#endif +} + + + +/** Change current transformation matrix. + @param of Output filter to write to. + @param cmv Matrix values. +*/ +static +void +dk3pdf_cm_double(dk3_of_t *of, double *cmv) +{ + $? "+ dk3pdf_cm_double" + dk3pdf_write_double(of, cmv[0]); + dk3of_write_c8_string(of, dk3pdf_c8_kw[1]); + dk3pdf_write_double(of, cmv[1]); + dk3of_write_c8_string(of, dk3pdf_c8_kw[1]); + dk3pdf_write_double(of, cmv[2]); + dk3of_write_c8_string(of, dk3pdf_c8_kw[1]); + dk3pdf_write_double(of, cmv[3]); + dk3of_write_c8_string(of, dk3pdf_c8_kw[1]); + dk3pdf_write_double(of, cmv[4]); + dk3of_write_c8_string(of, dk3pdf_c8_kw[1]); + dk3pdf_write_double(of, cmv[5]); + dk3of_write_c8_string(of, dk3pdf_c8_kw[1]); + dk3of_write_c8_string(of, dk3pdf_c8_kw[4]); $? "- dk3pdf_cm_double" +} + + + +int +dk3pdf_translate_long(dk3_pdf_t *pdf, long x, long y) +{ + long cmv[] = { 0L, 0L, 0L, 0L, 0L, 0L }; /* Matrix values. */ + int back = 0; + $? "+ dk3pdf_translate_long %ld %ld", x, y + if(pdf) { + if(pdf->cp) { + if((pdf->cp)->tempof) { + back = 1; + cmv[0] = 1L; + cmv[3] = 1L; + cmv[4] = x; + cmv[5] = y; + dk3pdf_cm_long((pdf->cp)->tempof, cmv); + } + } + } $? "- dk3pdf_translate_long %d", back + return back; +} + + + +int +dk3pdf_translate_double(dk3_pdf_t *pdf, double x, double y) +{ + double cmv[] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; /* Matrix values. */ + int back = 0; + $? "+ dk3pdf_translate_double %lg %lg", x, y + if(pdf) { + if(pdf->cp) { + if((pdf->cp)->tempof) { + back = 1; + cmv[0] = 1.0; + cmv[3] = 1.0; + cmv[4] = x; + cmv[5] = y; + dk3pdf_cm_double((pdf->cp)->tempof, cmv); + } + } + } $? "- dk3pdf_translate_double %d", back + return back; +} + + + +/** Convert long value to double. + @param l Long value to convert. + @return Conversion result. +*/ +static +double +dk3pdf_l_to_d(long l) +{ + return ((double)l); +} + +int +dk3pdf_rotate_int(dk3_pdf_t *pdf, int angle) +{ + long cmv[] = { 0L, 0L, 0L, 0L, 0L, 0L }; /* Matrix values. */ + int back = 0; + $? "+ dk3pdf_rotate_int %d", angle + if(pdf) { + if(pdf->cp) { + if((pdf->cp)->tempof) { + back = 1; + if(angle % 90) { + back = dk3pdf_rotate_double(pdf, dk3pdf_l_to_d((long)angle)); + } else { + if(angle % 360) { + switch(angle % 360) { + case 90: { + cmv[1] = 1L; + cmv[2] = -1L; + } break; + case 180: { + cmv[0] = -1L; + cmv[3] = -1L; + } break; + case 270: { + cmv[1] = -1L; + cmv[2] = 1L; + } break; + } + dk3pdf_cm_long((pdf->cp)->tempof, cmv); + } + } + } + } + } $? "- dk3pdf_rotate_int %d", back + return back; +} + + + +int +dk3pdf_rotate_double(dk3_pdf_t *pdf, double angle) +{ + double cmv[] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; /* Matrix values. */ + int back = 0; + $? "+ dk3pdf_rotate_double %lg", angle + if(pdf) { + if(pdf->cp) { + if((pdf->cp)->tempof) { + back = 1; + cmv[0] = cos(angle); + cmv[1] = sin(angle); + cmv[2] = 0.0 - cmv[1]; + cmv[3] = cmv[0]; + dk3pdf_cm_double((pdf->cp)->tempof, cmv); + } + } + } $? "- dk3pdf_rotate_double %d", back + return back; +} + + + +int +dk3pdf_scale_long(dk3_pdf_t *pdf, long x, long y) +{ + long cmv[] = { 0L, 0L, 0L, 0L, 0L, 0L }; /* Matrix values. */ + int back = 0; + $? "+ dk3pdf_scale_long %ld %ld", x, y + if(pdf) { + if(pdf->cp) { + if((pdf->cp)->tempof) { + back = 1; + cmv[0] = x; + cmv[3] = y; + dk3pdf_cm_long((pdf->cp)->tempof, cmv); + } + } + } $? "- dk3pdf_scale_long %d", back + return back; +} + + + +int +dk3pdf_scale_double(dk3_pdf_t *pdf, double x, double y) +{ + double cmv[] = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; /* Matrix values. */ + int back = 0; + $? "+ dk3pdf_scale_double %lg %lg", x, y + if(pdf) { + if(pdf->cp) { + if((pdf->cp)->tempof) { + back = 1; + cmv[0] = x; + cmv[3] = y; + dk3pdf_cm_double((pdf->cp)->tempof, cmv); + } + } + } $? "- dk3pdf_scale_double %d", back + return back; +} + + + +int +dk3pdf_add_xobject_to_page(dk3_pdf_t *pdf, dk3_pdf_xobject_t *xo) +{ + char buf[64]; /* Conversion buffer for number. */ + int back = 0; + $? "+ dk3pdf_add_xobject_to_page" + if((pdf) && (xo)) { $? ". pdf && xo" + if(pdf->cp) { $? ". cp " + if((pdf->cp)->tempof) { $? ". tempof" + sprintf(buf, "%lu", xo->objno); + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[5]); + dk3of_write_c8_string((pdf->cp)->tempof, buf); + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[6]); + if(!((pdf->cp)->s_xobjects)) { + (pdf->cp)->s_xobjects = dk3sto_open_app(pdf->app); + } + if(!((pdf->cp)->i_xobjects)) { + if((pdf->cp)->s_xobjects) { + (pdf->cp)->i_xobjects = dk3sto_it_open((pdf->cp)->s_xobjects); + } + } + if(((pdf->cp)->s_xobjects) && ((pdf->cp)->i_xobjects)) { $? ". sto ok" + if(dk3sto_add((pdf->cp)->s_xobjects, (void *)xo)) { $? ". add ok" + back = 1; + } + } + } else { $? "! tempof" + } + } else { $? "! cp" + } + } else { $? "! pdf && xo" + } $? "- dk3pdf_add_xobject_to_page %d", back + return back; +} + + + +/** Initialize image conversion job. + @param job Image conversion job to initialize. + @param opt Conversion options. + @param pdf Destination pdf structure. + @param bif Source bitmap image. +*/ +static +void +dk3pdf_image_job_init( + dk3_pdf_image_job_t *job, + dk3_bm_eps_options_t *opt, + dk3_pdf_t *pdf, + dk3_bif_t *bif +) +{ + $? "+ dk3pdf_image_job_init" + job->pdf = pdf; + job->bif = bif; + job->of = NULL; + job->procedure = DK3_BMEPS_RGB_FLATE; + job->h_color = 0; + job->h_alpha = 0; + job->bpc = 8; + job->opt = opt; + job->use_dct = 0; + job->xo = NULL; $? "- dk3pdf_image_job_init" +} + + + +/** Transfer DCT-encoded data directly from JPEG image to + output file. + @param ofile Destination file. + @param bif Source image. + @param app Application structure for diagnostics, may be NULL. +*/ +static +void +dk3pdf_transfer_dct_data(FILE *ofile, dk3_bif_t *bif, dk3_app_t *app) +{ + char buf[4096]; /* Data buffer. */ + FILE *ifile; /* Input file. */ + size_t rb; /* Number of bytes read. */ + int cc; /* Flag: Can continue. */ + $? "+ dk3pdf_transfer_dct_data" + ifile = dk3bif_get_file(bif); + if(ifile) { + rewind(ifile); + do { + cc = 0; + rb = dk3sf_fread_app(buf, 1, sizeof(buf), ifile, app); + if(rb > 0) { + cc = 1; + dk3sf_fwrite_app(buf, 1, rb, ofile, app); + } + } while(cc); + } $? "- dk3pdf_transfer_dct_data" +} + + + + +/** Add color data mixed, 8 bits per component. + @param job Image conversion job. + @param pcomm Communicator object. + @param minpb Minimum progress bar value. + @param maxpb Maximum progress bar value. +*/ +static +void +dk3pdf_out_col_8_mixed( + dk3_pdf_image_job_t *job, + void *pcomm, + int minpb, + int maxpb +) +{ + dk3_bif_coord_t y; /* Current line. */ + dk3_bif_coord_t x; /* Current column. */ + dk3_bif_coord_t h; /* Image height. */ + dk3_bif_coord_t w; /* Image width. */ + unsigned char v[3]; /* RGB values. */ + unsigned char ored, og, ob; /* Previous RGB values. */ + unsigned char r, g, b; /* RGB values. */ + $? "+ dk3pdf_out_col_8_mixed %!8s min=%d max=%d", TR_8PTR(pcomm), minpb, maxpb + w = dk3bif_get_width(job->bif); + h = dk3bif_get_height(job->bif); + switch((job->opt)->pred) { + case DK3_COMPRESSION_PREDICTOR_TIFF: { + for(y = 0L; y < h; y++) { + ored = og = ob = 0x00; + for(x = 0L; x < w; x++) { + r = (unsigned char)dk3bif_get_mixed_red(job->bif, x, y); + g = (unsigned char)dk3bif_get_mixed_green(job->bif, x, y); + b = (unsigned char)dk3bif_get_mixed_blue(job->bif, x, y); + v[0] = r - ored; + v[1] = g - og; + v[2] = b - ob; + dk3of_write_bytes(job->of, v, 3); + ored = r; og = g; ob = b; + } +#if DK3_USE_WX + dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y); +#endif + } + } break; + case DK3_COMPRESSION_PREDICTOR_PNG_SUB: { + for(y = 0L; y < h; y++) { + r = 0x01; + dk3of_write_bytes(job->of, &r, 1); + ored = og = ob = 0x00; + for(x = 0L; x < w; x++) { + r = (unsigned char)dk3bif_get_mixed_red(job->bif, x, y); + g = (unsigned char)dk3bif_get_mixed_green(job->bif, x, y); + b = (unsigned char)dk3bif_get_mixed_blue(job->bif, x, y); + v[0] = r - ored; + v[1] = g - og; + v[2] = b - ob; + dk3of_write_bytes(job->of, v, 3); + ored = r; og = g; ob = b; + } +#if DK3_USE_WX + dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y); +#endif + } + } break; + case DK3_COMPRESSION_PREDICTOR_PNG_UP: { + for(y = 0L; y < h; y++) { + r = 0x02; + dk3of_write_bytes(job->of, &r, 1); + for(x = 0L; x < w; x++) { + ored = (unsigned char)dk3bif_get_mixed_red(job->bif, x, (y - 1L)); + og = (unsigned char)dk3bif_get_mixed_green(job->bif, x, (y - 1L)); + ob = (unsigned char)dk3bif_get_mixed_blue(job->bif, x, (y - 1L)); + r = (unsigned char)dk3bif_get_mixed_red(job->bif, x, y); + g = (unsigned char)dk3bif_get_mixed_green(job->bif, x, y); + b = (unsigned char)dk3bif_get_mixed_blue(job->bif, x, y); + v[0] = r - ored; + v[1] = g - og; + v[2] = b - ob; + dk3of_write_bytes(job->of, v, 3); + } +#if DK3_USE_WX + dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y); +#endif + } + } break; + case DK3_COMPRESSION_PREDICTOR_PNG_AVERAGE: { + for(y = 0L; y < h; y++) { + r = 0x03; + dk3of_write_bytes(job->of, &r, 1); + for(x = 0L; x < w; x++) { + r = (unsigned char)dk3bif_get_mixed_red(job->bif, x, y); + g = (unsigned char)dk3bif_get_mixed_green(job->bif, x, y); + b = (unsigned char)dk3bif_get_mixed_blue(job->bif, x, y); + ored = (unsigned char)dk3bif_get_mixed_red(job->bif, (x - 1L), y); + og = (unsigned char)dk3bif_get_mixed_red(job->bif, x, (y - 1L)); + ored = (unsigned char)dk3bif_average(ored, og); + v[0] = r - ored; + ored = (unsigned char)dk3bif_get_mixed_green(job->bif, (x - 1L), y); + og = (unsigned char)dk3bif_get_mixed_green(job->bif, x, (y - 1L)); + ored = (unsigned char)dk3bif_average(ored, og); + v[1] = g - ored; + ored = (unsigned char)dk3bif_get_mixed_blue(job->bif, (x - 1L), y); + og = (unsigned char)dk3bif_get_mixed_blue(job->bif, x, (y - 1L)); + ored = (unsigned char)dk3bif_average(ored, og); + v[2] = b - ored; + dk3of_write_bytes(job->of, v, 3); + } +#if DK3_USE_WX + dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y); +#endif + } + } break; + case DK3_COMPRESSION_PREDICTOR_PNG_PAETH: { + for(y = 0L; y < h; y++) { + r = 0x04; + dk3of_write_bytes(job->of, &r, 1); + for(x = 0L; x < w; x++) { + r = (unsigned char)dk3bif_get_mixed_red(job->bif, x, y); + g = (unsigned char)dk3bif_get_mixed_green(job->bif, x, y); + b = (unsigned char)dk3bif_get_mixed_blue(job->bif, x, y); + ored = (unsigned char)dk3bif_paeth( + dk3bif_get_mixed_red(job->bif, (x - 1L), y), + dk3bif_get_mixed_red(job->bif, x, (y - 1L)), + dk3bif_get_mixed_red(job->bif, (x - 1L), (y - 1L)) + ); + og = (unsigned char)dk3bif_paeth( + dk3bif_get_mixed_green(job->bif, (x - 1L), y), + dk3bif_get_mixed_green(job->bif, x, (y - 1L)), + dk3bif_get_mixed_green(job->bif, (x - 1L), (y - 1L)) + ); + ob = (unsigned char)dk3bif_paeth( + dk3bif_get_mixed_blue(job->bif, (x - 1L), y), + dk3bif_get_mixed_blue(job->bif, x, (y - 1L)), + dk3bif_get_mixed_blue(job->bif, (x - 1L), (y - 1L)) + ); + v[0] = r - ored; + v[1] = g - og; + v[2] = b - ob; + dk3of_write_bytes(job->of, v, 3); + } +#if DK3_USE_WX + dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y); +#endif + } + } break; + default: { + for(y = 0L; y < h; y++) { + for(x = 0L; x < w; x++) { + v[0] = (unsigned char)dk3bif_get_mixed_red(job->bif, x, y); + v[1] = (unsigned char)dk3bif_get_mixed_green(job->bif, x, y); + v[2] = (unsigned char)dk3bif_get_mixed_blue(job->bif, x, y); + dk3of_write_bytes(job->of, v, 3); + } +#if DK3_USE_WX + dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y); +#endif + } + } break; + } $? "- dk3pdf_out_col_8_mixed" +} + + + +/** Add color data directly, 8 bits per component. + @param job Image conversion job. + @param pcomm Communicator object. + @param minpb Minimum progress bar value. + @param maxpb Maximum progress bar value. +*/ +static +void +dk3pdf_out_col_8_not_mixed( + dk3_pdf_image_job_t *job, + void *pcomm, + int minpb, + int maxpb +) +{ + dk3_bif_coord_t y; /* Current line. */ + dk3_bif_coord_t x; /* Current column. */ + dk3_bif_coord_t h; /* Image height. */ + dk3_bif_coord_t w; /* Image width. */ + unsigned char v[3]; /* RGB values. */ + unsigned char ored, og, ob; /* Previous RGB values. */ + unsigned char r, g, b; /* RGB values. */ + $? "+ dk3pdf_out_col_8_not_mixed" + w = dk3bif_get_width(job->bif); + h = dk3bif_get_height(job->bif); + switch((job->opt)->pred) { + case DK3_COMPRESSION_PREDICTOR_TIFF: { + for(y = 0L; y < h; y++) { + ored = og = ob = 0x00; + for(x = 0L; x < w; x++) { + r = (unsigned char)dk3bif_get_red(job->bif, x, y); + g = (unsigned char)dk3bif_get_green(job->bif, x, y); + b = (unsigned char)dk3bif_get_blue(job->bif, x, y); + v[0] = r - ored; + v[1] = g - og; + v[2] = b - ob; + dk3of_write_bytes(job->of, v, 3); + ored = r; og = g; ob = b; + } +#if DK3_USE_WX + dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y); +#endif + } + } break; + case DK3_COMPRESSION_PREDICTOR_PNG_SUB: { + for(y = 0L; y < h; y++) { + r = 0x01; + dk3of_write_bytes(job->of, &r, 1); + ored = og = ob = 0x00; + for(x = 0L; x < w; x++) { + r = (unsigned char)dk3bif_get_red(job->bif, x, y); + g = (unsigned char)dk3bif_get_green(job->bif, x, y); + b = (unsigned char)dk3bif_get_blue(job->bif, x, y); + v[0] = r - ored; + v[1] = g - og; + v[2] = b - ob; + dk3of_write_bytes(job->of, v, 3); + ored = r; og = g; ob = b; + } +#if DK3_USE_WX + dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y); +#endif + } + } break; + case DK3_COMPRESSION_PREDICTOR_PNG_UP: { + for(y = 0L; y < h; y++) { + r = 0x02; + dk3of_write_bytes(job->of, &r, 1); + for(x = 0L; x < w; x++) { + ored = (unsigned char)dk3bif_get_red(job->bif, x, (y - 1L)); + og = (unsigned char)dk3bif_get_green(job->bif, x, (y - 1L)); + ob = (unsigned char)dk3bif_get_blue(job->bif, x, (y - 1L)); + r = (unsigned char)dk3bif_get_red(job->bif, x, y); + g = (unsigned char)dk3bif_get_green(job->bif, x, y); + b = (unsigned char)dk3bif_get_blue(job->bif, x, y); + v[0] = r - ored; + v[1] = g - og; + v[2] = b - ob; + dk3of_write_bytes(job->of, v, 3); + } +#if DK3_USE_WX + dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y); +#endif + } + } break; + case DK3_COMPRESSION_PREDICTOR_PNG_AVERAGE: { + for(y = 0L; y < h; y++) { + r = 0x03; + dk3of_write_bytes(job->of, &r, 1); + for(x = 0L; x < w; x++) { + r = (unsigned char)dk3bif_get_red(job->bif, x, y); + g = (unsigned char)dk3bif_get_green(job->bif, x, y); + b = (unsigned char)dk3bif_get_blue(job->bif, x, y); + ored = (unsigned char)dk3bif_get_red(job->bif, (x - 1L), y); + og = (unsigned char)dk3bif_get_red(job->bif, x, (y - 1L)); + ored = (unsigned char)dk3bif_average(ored, og); + v[0] = r - ored; + ored = (unsigned char)dk3bif_get_green(job->bif, (x - 1L), y); + og = (unsigned char)dk3bif_get_green(job->bif, x, (y - 1L)); + ored = (unsigned char)dk3bif_average(ored, og); + v[1] = g - ored; + ored = (unsigned char)dk3bif_get_blue(job->bif, (x - 1L), y); + og = (unsigned char)dk3bif_get_blue(job->bif, x, (y - 1L)); + ored = (unsigned char)dk3bif_average(ored, og); + v[2] = b - ored; + dk3of_write_bytes(job->of, v, 3); + } +#if DK3_USE_WX + dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y); +#endif + } + } break; + case DK3_COMPRESSION_PREDICTOR_PNG_PAETH: { + for(y = 0L; y < h; y++) { + r = 0x04; + dk3of_write_bytes(job->of, &r, 1); + for(x = 0L; x < w; x++) { + r = (unsigned char)dk3bif_get_red(job->bif, x, y); + g = (unsigned char)dk3bif_get_green(job->bif, x, y); + b = (unsigned char)dk3bif_get_blue(job->bif, x, y); + ored = (unsigned char)dk3bif_paeth( + dk3bif_get_red(job->bif, (x - 1L), y), + dk3bif_get_red(job->bif, x, (y - 1L)), + dk3bif_get_red(job->bif, (x - 1L), (y - 1L)) + ); + og = (unsigned char)dk3bif_paeth( + dk3bif_get_green(job->bif, (x - 1L), y), + dk3bif_get_green(job->bif, x, (y - 1L)), + dk3bif_get_green(job->bif, (x - 1L), (y - 1L)) + ); + ob = (unsigned char)dk3bif_paeth( + dk3bif_get_blue(job->bif, (x - 1L), y), + dk3bif_get_blue(job->bif, x, (y - 1L)), + dk3bif_get_blue(job->bif, (x - 1L), (y - 1L)) + ); + v[0] = r - ored; + v[1] = g - og; + v[2] = b - ob; + dk3of_write_bytes(job->of, v, 3); + } +#if DK3_USE_WX + dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y); +#endif + } + } break; + default: { + for(y = 0L; y < h; y++) { + for(x = 0L; x < w; x++) { + v[0] = (unsigned char)dk3bif_get_red(job->bif, x, y); + v[1] = (unsigned char)dk3bif_get_green(job->bif, x, y); + v[2] = (unsigned char)dk3bif_get_blue(job->bif, x, y); + dk3of_write_bytes(job->of, v, 3); + } +#if DK3_USE_WX + dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y); +#endif + } + } break; + } $? "- dk3pdf_out_col_8_not_mixed" +} + + + +/** Add gray data mixed, 8 bits per component. + @param job Image conversion job. + @param pcomm Communicator object. + @param minpb Minimum progress bar value. + @param maxpb Maximum progress bar value. +*/ +static +void +dk3pdf_out_gray_8_mixed( + dk3_pdf_image_job_t *job, + void *pcomm, + int minpb, + int maxpb +) +{ + dk3_bif_coord_t y; /* Current line. */ + dk3_bif_coord_t x; /* Current column. */ + dk3_bif_coord_t h; /* Image height. */ + dk3_bif_coord_t w; /* Image width. */ + unsigned char v, p, q; /* Value and predictor(s). */ + $? "+ dk3pdf_out_gray_8_mixed" + w = dk3bif_get_width(job->bif); + h = dk3bif_get_height(job->bif); + switch((job->opt)->pred) { + case DK3_COMPRESSION_PREDICTOR_TIFF: { + for(y = 0L; y < h; y++) { + p = 0x00; + for(x = 0L; x < w; x++) { + v = (unsigned char)dk3bif_get_mixed_gray(job->bif, x, y); + q = v - p; + dk3of_write_bytes(job->of, &q, 1); + p = v; + } +#if DK3_USE_WX + dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y); +#endif + } + } break; + case DK3_COMPRESSION_PREDICTOR_PNG_SUB: { + for(y = 0L; y < h; y++) { + q = 0x01; + dk3of_write_bytes(job->of, &q, 1); + p = 0x00; + for(x = 0L; x < w; x++) { + v = (unsigned char)dk3bif_get_mixed_gray(job->bif, x, y); + q = v - p; + dk3of_write_bytes(job->of, &q, 1); + p = v; + } +#if DK3_USE_WX + dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y); +#endif + } + } break; + case DK3_COMPRESSION_PREDICTOR_PNG_UP: { + for(y = 0L; y < h; y++) { + q = 0x02; + dk3of_write_bytes(job->of, &q, 1); + for(x = 0L; x < w; x++) { + p = (unsigned char)dk3bif_get_mixed_gray(job->bif, x, (y - 1L)); + v = (unsigned char)dk3bif_get_mixed_gray(job->bif, x, y); + q = v - p; + dk3of_write_bytes(job->of, &q, 1); + } +#if DK3_USE_WX + dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y); +#endif + } + } break; + case DK3_COMPRESSION_PREDICTOR_PNG_AVERAGE: { + for(y = 0L; y < h; y++) { + q = 0x03; + dk3of_write_bytes(job->of, &q, 1); + for(x = 0L; x < w; x++) { + p = (unsigned char)dk3bif_average( + dk3bif_get_mixed_gray(job->bif, x, (y - 1L)), + dk3bif_get_mixed_gray(job->bif, (x - 1L), y) + ); + v = (unsigned char)dk3bif_get_mixed_gray(job->bif, x, y); + q = v - p; + dk3of_write_bytes(job->of, &q, 1); + } +#if DK3_USE_WX + dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y); +#endif + } + } break; + case DK3_COMPRESSION_PREDICTOR_PNG_PAETH: { + for(y = 0L; y < h; y++) { + q = 0x04; + dk3of_write_bytes(job->of, &q, 1); + for(x = 0L; x < w; x++) { + v = (unsigned char)dk3bif_get_mixed_gray(job->bif, x, y); + p = (unsigned char)dk3bif_paeth( + dk3bif_get_mixed_gray(job->bif, (x - 1L), y), + dk3bif_get_mixed_gray(job->bif, x, (y - 1L)), + dk3bif_get_mixed_gray(job->bif, (x - 1L), (y - 1L)) + ); + q = v - p; + dk3of_write_bytes(job->of, &q, 1); + } +#if DK3_USE_WX + dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y); +#endif + } + } break; + default: { + for(y = 0L; y < h; y++) { + for(x = 0L; x < w; x++) { + v = (unsigned char)dk3bif_get_mixed_gray(job->bif, x, y); + dk3of_write_bytes(job->of, &v, 1); + } +#if DK3_USE_WX + dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y); +#endif + } + } break; + } $? "- dk3pdf_out_gray_8_mixed" +} + + + +/** Add gray data directly, 8 bits per component. + @param job Image conversion job. + @param pcomm Communicator object. + @param minpb Minimum progress bar value. + @param maxpb Maximum progress bar value. +*/ +static +void +dk3pdf_out_gray_8_not_mixed( + dk3_pdf_image_job_t *job, + void *pcomm, + int minpb, + int maxpb +) +{ + dk3_bif_coord_t y; /* Current line. */ + dk3_bif_coord_t x; /* Current column. */ + dk3_bif_coord_t h; /* Image height. */ + dk3_bif_coord_t w; /* Image width. */ + unsigned char v, p, q; /* Value and predictors. */ + $? "+ dk3pdf_out_gray_8_not_mixed" + w = dk3bif_get_width(job->bif); + h = dk3bif_get_height(job->bif); + switch((job->opt)->pred) { + case DK3_COMPRESSION_PREDICTOR_TIFF: { $? ". tiff predictor" + for(y = 0L; y < h; y++) { + p = 0x00; + for(x = 0L; x < w; x++) { + v = (unsigned char)dk3bif_get_gray(job->bif, x, y); + q = v - p; $? ". x=%ld y=%ld v=%x p=%x q=%x", x, y, (int)v, (int)p, (int)q + dk3of_write_bytes(job->of, &q, 1); + p = v; + } +#if DK3_USE_WX + dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y); +#endif + } + } break; + case DK3_COMPRESSION_PREDICTOR_PNG_SUB: { + for(y = 0L; y < h; y++) { + q = 0x01; + dk3of_write_bytes(job->of, &q, 1); + p = 0x00; + for(x = 0L; x < w; x++) { + v = (unsigned char)dk3bif_get_gray(job->bif, x, y); + q = v - p; + dk3of_write_bytes(job->of, &q, 1); + p = v; + } +#if DK3_USE_WX + dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y); +#endif + } + } break; + case DK3_COMPRESSION_PREDICTOR_PNG_UP: { + for(y = 0L; y < h; y++) { + q = 0x02; + dk3of_write_bytes(job->of, &q, 1); + for(x = 0L; x < w; x++) { + p = (unsigned char)dk3bif_get_gray(job->bif, x, (y - 1L)); + v = (unsigned char)dk3bif_get_gray(job->bif, x, y); + q = v - p; + dk3of_write_bytes(job->of, &q, 1); + } +#if DK3_USE_WX + dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y); +#endif + } + } break; + case DK3_COMPRESSION_PREDICTOR_PNG_AVERAGE: { + dk3_bif_pixel_t lv; + dk3_bif_pixel_t uv; + for(y = 0L; y < h; y++) { + q = 0x03; + dk3of_write_bytes(job->of, &q, 1); + for(x = 0L; x < w; x++) { + uv = dk3bif_get_gray(job->bif, x, (y - 1L)); + lv = dk3bif_get_gray(job->bif, (x - 1L), y); + lv = dk3bif_average(uv, lv); + p = (unsigned char)lv; + v = (unsigned char)dk3bif_get_gray(job->bif, x, y); + q = v - p; + dk3of_write_bytes(job->of, &q, 1); + } +#if DK3_USE_WX + dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y); +#endif + } + } break; + case DK3_COMPRESSION_PREDICTOR_PNG_PAETH: { + for(y = 0L; y < h; y++) { + q = 0x04; + dk3of_write_bytes(job->of, &q, 1); + for(x = 0L; x < w; x++) { + v = (unsigned char)dk3bif_get_gray(job->bif, x, y); + p = (unsigned char)dk3bif_paeth( + dk3bif_get_gray(job->bif, (x - 1L), y), + dk3bif_get_gray(job->bif, x, (y - 1L)), + dk3bif_get_gray(job->bif, (x - 1L), (y - 1L)) + ); + q = v - p; + dk3of_write_bytes(job->of, &q, 1); + } +#if DK3_USE_WX + dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y); +#endif + } + } break; + default: { $? ". no predictor" + for(y = 0L; y < h; y++) { + for(x = 0L; x < w; x++) { + v = (unsigned char)dk3bif_get_gray(job->bif, x, y); + dk3of_write_bytes(job->of, &v, 1); + } +#if DK3_USE_WX + dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y); +#endif + } + } break; + } $? "- dk3pdf_out_gray_8_not_mixed" +} + + + +/** Add color data mixed, bits per component not 8. + @param job Image conversion job. + @param pcomm Communicator object. + @param minpb Minimum progress bar value. + @param maxpb Maximum progress bar value. +*/ +static +void +dk3pdf_out_col_not8_mixed( + dk3_pdf_image_job_t *job, + void *pcomm, + int minpb, + int maxpb +) +{ + dk3_bif_coord_t y; /* Current line. */ + dk3_bif_coord_t x; /* Current column. */ + dk3_bif_coord_t h; /* Image height. */ + dk3_bif_coord_t w; /* Image width. */ + dk3_bif_pixel_t r; /* Red. */ + dk3_bif_pixel_t g; /* Green. */ + dk3_bif_pixel_t b; /* Blue. */ + dk3_bif_pixel_t ored; /* Previous red. */ + dk3_bif_pixel_t og; /* Previous green. */ + dk3_bif_pixel_t ob; /* Previous blue. */ + $? "+ dk3pdf_out_col_not8_mixed" + w = dk3bif_get_width(job->bif); + h = dk3bif_get_height(job->bif); + switch((job->opt)->pred) { + case DK3_COMPRESSION_PREDICTOR_TIFF: { + for(y = 0L; y < h; y++) { + ored = 0U; og = 0U; ob = 0U; + for(x = 0L; x < w; x++) { + r = dk3bif_get_mixed_red(job->bif, x, y); + g = dk3bif_get_mixed_green(job->bif, x, y); + b = dk3bif_get_mixed_blue(job->bif, x, y); + dk3of_write_bits(job->of, (r - ored), job->bpc); + dk3of_write_bits(job->of, (g - og), job->bpc); + dk3of_write_bits(job->of, (b - ob), job->bpc); + ored = r; + og = g; + ob = b; + } + dk3of_flush_bits(job->of); +#if DK3_USE_WX + dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y); +#endif + } + } break; + default: { + for(y = 0L; y < h; y++) { + for(x = 0L; x < w; x++) { + r = dk3bif_get_mixed_red(job->bif, x, y); + g = dk3bif_get_mixed_green(job->bif, x, y); + b = dk3bif_get_mixed_blue(job->bif, x, y); + dk3of_write_bits(job->of, r, job->bpc); + dk3of_write_bits(job->of, g, job->bpc); + dk3of_write_bits(job->of, b, job->bpc); + } + dk3of_flush_bits(job->of); +#if DK3_USE_WX + dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y); +#endif + } + } break; + } $? "- dk3pdf_out_col_not8_mixed" +} + + + +/** Add color data directly, bits per component not 8. + @param job Image conversion job. + @param pcomm Communicator object. + @param minpb Minimum progress bar value. + @param maxpb Maximum progress bar value. +*/ +static +void +dk3pdf_out_col_not8_not_mixed( + dk3_pdf_image_job_t *job, + void *pcomm, + int minpb, + int maxpb +) +{ + dk3_bif_coord_t y; /* Current line. */ + dk3_bif_coord_t x; /* Current column. */ + dk3_bif_coord_t h; /* Image height. */ + dk3_bif_coord_t w; /* Image width. */ + dk3_bif_pixel_t r; /* Red. */ + dk3_bif_pixel_t g; /* Green. */ + dk3_bif_pixel_t b; /* Blue. */ + dk3_bif_pixel_t ored; /* Previous red. */ + dk3_bif_pixel_t og; /* Previous green. */ + dk3_bif_pixel_t ob; /* Previous blue. */ + $? "+ dk3pdf_out_col_not8_not_mixed" + w = dk3bif_get_width(job->bif); + h = dk3bif_get_height(job->bif); + switch((job->opt)->pred) { + case DK3_COMPRESSION_PREDICTOR_TIFF: { + for(y = 0L; y < h; y++) { + ored = 0U; og = 0U; ob = 0U; + for(x = 0L; x < w; x++) { + r = dk3bif_get_red(job->bif, x, y); + g = dk3bif_get_green(job->bif, x, y); + b = dk3bif_get_blue(job->bif, x, y); + dk3of_write_bits(job->of, (r - ored), job->bpc); + dk3of_write_bits(job->of, (g - og), job->bpc); + dk3of_write_bits(job->of, (b - ob), job->bpc); + ored = r; + og = g; + ob = b; + } + dk3of_flush_bits(job->of); +#if DK3_USE_WX + dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y); +#endif + } + } break; + default: { + for(y = 0L; y < h; y++) { + for(x = 0L; x < w; x++) { + r = dk3bif_get_red(job->bif, x, y); + g = dk3bif_get_green(job->bif, x, y); + b = dk3bif_get_blue(job->bif, x, y); + dk3of_write_bits(job->of, r, job->bpc); + dk3of_write_bits(job->of, g, job->bpc); + dk3of_write_bits(job->of, b, job->bpc); + } + dk3of_flush_bits(job->of); +#if DK3_USE_WX + dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y); +#endif + } + } break; + } $? "- dk3pdf_out_col_not8_not_mixed" +} + + + +/** Add gray data mixed, bits per component not 8. + @param job Image conversion job. + @param pcomm Communicator object. + @param minpb Minimum progress bar value. + @param maxpb Maximum progress bar value. +*/ +static +void +dk3pdf_out_gray_not8_mixed( + dk3_pdf_image_job_t *job, + void *pcomm, + int minpb, + int maxpb +) +{ + dk3_bif_coord_t y; /* Current line. */ + dk3_bif_coord_t x; /* Current column. */ + dk3_bif_coord_t h; /* Image height. */ + dk3_bif_coord_t w; /* Image width. */ + dk3_bif_pixel_t g; /* Current gray. */ + dk3_bif_pixel_t og; /* Previous gray. */ + $? "+ dk3pdf_out_gray_not8_mixed" + w = dk3bif_get_width(job->bif); + h = dk3bif_get_height(job->bif); + switch((job->opt)->pred) { + case DK3_COMPRESSION_PREDICTOR_TIFF: { + for(y = 0L; y < h; y++) { + og = 0U; + for(x = 0L; x < w; x++) { + g = dk3bif_get_mixed_gray(job->bif, x, y); + dk3of_write_bits(job->of, (g - og), job->bpc); + og = g; + } + dk3of_flush_bits(job->of); +#if DK3_USE_WX + dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y); +#endif + } + } break; + default: { + for(y = 0L; y < h; y++) { + for(x = 0L; x < w; x++) { + g = dk3bif_get_mixed_gray(job->bif, x, y); + dk3of_write_bits(job->of, g, job->bpc); + } + dk3of_flush_bits(job->of); +#if DK3_USE_WX + dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y); +#endif + } + } break; + } $? "- dk3pdf_out_gray_not8_mixed" +} + + + +/** Add gray data directly, bits per component not 8. + @param job Image conversion job. + @param pcomm Communicator object. + @param minpb Minimum progress bar value. + @param maxpb Maximum progress bar value. +*/ +static +void +dk3pdf_out_gray_not8_not_mixed( + dk3_pdf_image_job_t *job, + void *pcomm, + int minpb, + int maxpb +) +{ + dk3_bif_coord_t y; /* Current line. */ + dk3_bif_coord_t x; /* Current column. */ + dk3_bif_coord_t h; /* Image height. */ + dk3_bif_coord_t w; /* Image width. */ + dk3_bif_pixel_t g; /* Current point gray. */ + dk3_bif_pixel_t og; /* Previous gray. */ + $? "+ dk3pdf_out_gray_not8_not_mixed" + w = dk3bif_get_width(job->bif); + h = dk3bif_get_height(job->bif); + switch((job->opt)->pred) { + case DK3_COMPRESSION_PREDICTOR_TIFF: { + for(y = 0L; y < h; y++) { + og = 0U; + for(x = 0L; x < w; x++) { + g = dk3bif_get_gray(job->bif, x, y); + dk3of_write_bits(job->of, (g - og), job->bpc); + og = g; + } + dk3of_flush_bits(job->of); +#if DK3_USE_WX + dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y); +#endif + } + } break; + default: { + for(y = 0L; y < h; y++) { + for(x = 0L; x < w; x++) { + g = dk3bif_get_gray(job->bif, x, y); + dk3of_write_bits(job->of, g, job->bpc); + } + dk3of_flush_bits(job->of); +#if DK3_USE_WX + dk3bmj_lines_progress(pcomm,minpb,maxpb,h,y); +#endif + } + } break; + } $? "- dk3pdf_out_gray_not8_not_mixed" +} + + + +/** Add another Xobject containing the alpha channel from the + current XObject. + @param job Image conversion job. + @param pcomm Communicator object. + @param min Minimum progress bar value. + @param max Maximum progress bar value. + @return 1 on success, 0 on error. +*/ +static +int +dk3pdf_add_alpha_xobject( + dk3_pdf_image_job_t *job, + void *pcomm, + int min, + int max +) +{ + dk3_stat_t stb; /* Stat buffer. */ + dk3_pdf_xobject_t *mo; /* Mask object. */ + FILE *fipo; /* Output file. */ + dk3_stream_t *os; /* Output stream. */ + dk3_of_t *of; /* Output filter. */ + dk3_bif_coord_t w; /* Image width. */ + dk3_bif_coord_t h; /* Image height. */ + dk3_bif_coord_t x; /* Current column. */ + dk3_bif_coord_t y; /* Current row. */ + dk3_bif_pixel_t v; /* Pixel value. */ + dk3_bif_pixel_t p; /* Previous value. */ + int back = 0; + unsigned char vc; /* Value as byte. */ + unsigned char pc; /* Predictor as byte. */ + unsigned char wc; /* Predictor as byte. */ + $? "+ dk3pdf_add_alpha_xobject" + mo = dk3pdf_xobject_new(job->pdf); + if(mo) { + mo->objno = (job->pdf)->nextobject; + if(dk3sto_add((job->pdf)->s_xobjects, (void *)mo)) { + (job->pdf)->nextobject += 1UL; + w = mo->width = dk3bif_get_width(job->bif); + h = mo->height = dk3bif_get_height(job->bif); + mo->xot = DK3_PDF_XO_TYPE_ALPHA; + mo->procedure = DK3_BMEPS_GRAY_FLATE; + mo->bpc = job->bpc; + mo->pred = (job->opt)->pred; + fipo = dk3sf_fopen_app( + mo->tempfilename, + dk3app_not_localized(53), + (job->pdf)->app + ); + if(fipo) { + (job->xo)->mask = mo; + os = dk3stream_open_file_app( + fipo, + DK3_STREAM_FLAG_WRITE, + (job->pdf)->app + ); + if(os) { + of = dk3of_open_app(os, (job->pdf)->app); + if(of) { + if(dk3of_add_cell(of, DK3_OF_CELL_TYPE_FLATE)) { + if(dk3of_start_chunk(of)) { + if(job->bpc == 8) { + switch((job->opt)->pred) { + case DK3_COMPRESSION_PREDICTOR_TIFF: { + for(y = 0; y < h; y++) { + pc = 0x00; + for(x = 0; x < w; x++) { + vc = (unsigned char)dk3bif_get_alpha(job->bif, x, y); + wc = vc - pc; + dk3of_write_bytes(of, &wc, 1); + pc = vc; + } +#if DK3_USE_WX + dk3bmj_lines_progress(pcomm,min,max,h,y); +#endif + } + } break; + case DK3_COMPRESSION_PREDICTOR_PNG_SUB: { + for(y = 0; y < h; y++) { + pc = 0x00; + wc = 0x01; + dk3of_write_bytes(of, &wc, 1); + for(x = 0; x < w; x++) { + vc = (unsigned char)dk3bif_get_alpha(job->bif, x, y); + wc = vc - pc; + dk3of_write_bytes(of, &wc, 1); + pc = vc; + } +#if DK3_USE_WX + dk3bmj_lines_progress(pcomm,min,max,h,y); +#endif + } + } break; + case DK3_COMPRESSION_PREDICTOR_PNG_UP: { + for(y = 0; y < h; y++) { + wc = 0x02; + dk3of_write_bytes(of, &wc, 1); + for(x = 0; x < w; x++) { + vc = (unsigned char)dk3bif_get_alpha(job->bif, x, y); + pc = (unsigned char)dk3bif_get_alpha( + job->bif, x, (y - 1L) + ); + wc = vc - pc; + dk3of_write_bytes(of, &wc, 1); +#if VERSION_BEFORE_20150821 + pc = vc; +#endif + } +#if DK3_USE_WX + dk3bmj_lines_progress(pcomm,min,max,h,y); +#endif + } + } break; + case DK3_COMPRESSION_PREDICTOR_PNG_AVERAGE: { + for(y = 0; y < h; y++) { + wc = 0x03; + dk3of_write_bytes(of, &wc, 1); + for(x = 0; x < w; x++) { + vc = (unsigned char)dk3bif_get_alpha(job->bif, x, y); + pc = (unsigned char)dk3bif_get_alpha( + job->bif, x, (y - 1L) + ); + wc = (unsigned char)dk3bif_get_alpha( + job->bif, (x - 1L), y + ); + pc = (unsigned char)dk3bif_average(pc, wc); + wc = vc - pc; + dk3of_write_bytes(of, &wc, 1); +#if VERSION_BEFORE_20150821 + pc = vc; +#endif + } +#if DK3_USE_WX + dk3bmj_lines_progress(pcomm,min,max,h,y); +#endif + } + } break; + case DK3_COMPRESSION_PREDICTOR_PNG_PAETH: { + for(y = 0; y < h; y++) { + wc = 0x04; + dk3of_write_bytes(of, &wc, 1); + for(x = 0; x < w; x++) { + vc = (unsigned char)dk3bif_get_alpha(job->bif, x, y); + pc = (unsigned char)dk3bif_paeth( + (unsigned char)dk3bif_get_alpha( + job->bif, (x - 1L), y + ), + (unsigned char)dk3bif_get_alpha( + job->bif, x, (y - 1L) + ), + (unsigned char)dk3bif_get_alpha( + job->bif, (x - 1L), (y - 1L) + ) + ); + wc = vc - pc; + dk3of_write_bytes(of, &wc, 1); +#if VERSION_BEFORE_20150821 + pc = vc; +#endif + } +#if DK3_USE_WX + dk3bmj_lines_progress(pcomm,min,max,h,y); +#endif + } + } break; + default: { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + vc = (unsigned char)dk3bif_get_alpha(job->bif, x, y); + dk3of_write_bytes(of, &vc, 1); + } +#if DK3_USE_WX + dk3bmj_lines_progress(pcomm,min,max,h,y); +#endif + } + } break; + } + } else { + switch((job->opt)->pred) { + case DK3_COMPRESSION_PREDICTOR_TIFF: { + for(y = 0; y < h; y++) { + p = 0U; + for(x = 0; x < w; x++) { + v = dk3bif_get_alpha(job->bif, x, y); + dk3of_write_bits(of, (v - p), job->bpc); + p = v; + } + dk3of_flush_bits(of); +#if DK3_USE_WX + dk3bmj_lines_progress(pcomm,min,max,h,y); +#endif + } + } break; + default: { + for(y = 0; y < h; y++) { + for(x = 0; x < w; x++) { + v = dk3bif_get_alpha(job->bif, x, y); + dk3of_write_bits(of, v, job->bpc); + } + dk3of_flush_bits(of); +#if DK3_USE_WX + dk3bmj_lines_progress(pcomm,min,max,h,y); +#endif + } + } break; + } + } + back = dk3of_end_chunk(of); + } + } + dk3of_close(of); + } + dk3stream_close(os); + } + if(!dk3sf_fclose_fn_app(fipo, mo->tempfilename, (job->pdf)->app)) { + back = 0; + } + if(dk3sf_stat_app(&stb, mo->tempfilename, (job->pdf)->app)) { + mo->slgt = stb.sz; + } else { + back = 0; + /* ERROR: Stat failed! */ + } + } + } else { + dk3pdf_xobject_delete(mo); + } + } $? "- dk3pdf_add_alpha_xobject %d", back + return back; +} + + + +/** Create data stream for XObject in temporary file. + @param job Image conversion job. + @param pc Communication object. + @param min Minimum progress bar value. + @param max Maximum progress bar value. + @return 1 on success, 0 on error. +*/ +static +int +dk3pdf_xobject_data( + dk3_pdf_image_job_t *job, + void *pc, + int min, + int max +) +{ + dk3_stat_t stb; /* Stat buffer for content stream file. */ + FILE *fipo; /* Input file. */ + dk3_stream_t *os; /* Output stream. */ + int back = 0; + int xmax; /* Centered progress bar value. */ + $? "+ dk3pdf_xobject_data %!8s min=%d max=%d", TR_8PTR(pc), min, max + xmax = max; + if(!(job->use_dct)) { + switch(job->procedure) { + case DK3_BMEPS_GRAY_ALPHA_FLATE: case DK3_BMEPS_RGB_ALPHA_FLATE: { + xmax = (min + max) / 2; + } break; + } + } $? ". min=%d xmax=%d max=%d", min, xmax, max + (job->xo)->width = dk3bif_get_width(job->bif); + (job->xo)->height = dk3bif_get_height(job->bif); + (job->xo)->xot = DK3_PDF_XO_TYPE_IMAGE; + (job->xo)->procedure = job->procedure; + (job->xo)->bpc = job->bpc; + if(job->use_dct) { (job->xo)->dct = 1; } + if(!(job->use_dct)) { (job->xo)->pred = (job->opt)->pred; } + fipo = dk3sf_fopen_app( + (job->xo)->tempfilename, + dk3app_not_localized(53), + (job->pdf)->app + ); + if(fipo) { $? ". fipo" + if(job->use_dct) { $? ". use_dct" + back = 1; + dk3pdf_transfer_dct_data(fipo, job->bif, (job->pdf)->app); + } else { + dk3bif_set_bits_per_pixel(job->bif, job->bpc); + os = dk3stream_open_file_app(fipo,DK3_STREAM_FLAG_WRITE,(job->pdf)->app); + if(os) { + job->of = dk3of_open_app(os, (job->pdf)->app); + if(job->of) { + if(dk3of_add_cell(job->of, DK3_OF_CELL_TYPE_FLATE)) { + if(dk3of_start_chunk(job->of)) { + if(job->bpc == 8) { + if(job->h_alpha) { + switch(job->procedure) { + case DK3_BMEPS_RGB_FLATE: { + dk3pdf_out_col_8_mixed(job, pc, min, xmax); + } break; + case DK3_BMEPS_RGB_ALPHA_FLATE: { + dk3pdf_out_col_8_not_mixed(job, pc, min, xmax); + } break; + case DK3_BMEPS_GRAY_FLATE: { + dk3pdf_out_gray_8_mixed(job, pc, min, xmax); + } break; + case DK3_BMEPS_GRAY_ALPHA_FLATE: { + dk3pdf_out_gray_8_not_mixed(job, pc, min, xmax); + } break; + } + } else { + switch(job->procedure) { + case DK3_BMEPS_RGB_FLATE: { + dk3pdf_out_col_8_not_mixed(job, pc, min, xmax); + } break; + case DK3_BMEPS_RGB_ALPHA_FLATE: { + dk3pdf_out_col_8_not_mixed(job, pc, min, xmax); + } break; + case DK3_BMEPS_GRAY_FLATE: { + dk3pdf_out_gray_8_not_mixed(job, pc, min, xmax); + } break; + case DK3_BMEPS_GRAY_ALPHA_FLATE: { + dk3pdf_out_gray_8_not_mixed(job, pc, min, xmax); + } break; + } + } + } else { + if(job->h_alpha) { + switch(job->procedure) { + case DK3_BMEPS_RGB_FLATE: { + dk3pdf_out_col_not8_mixed(job, pc, min, xmax); + } break; + case DK3_BMEPS_RGB_ALPHA_FLATE: { + dk3pdf_out_col_not8_not_mixed(job, pc, min, xmax); + } break; + case DK3_BMEPS_GRAY_FLATE: { + dk3pdf_out_gray_not8_mixed(job, pc, min, xmax); + } break; + case DK3_BMEPS_GRAY_ALPHA_FLATE: { + dk3pdf_out_gray_not8_not_mixed(job, pc, min, xmax); + } break; + } + } else { + switch(job->procedure) { + case DK3_BMEPS_RGB_FLATE: { + dk3pdf_out_col_not8_not_mixed(job, pc, min, xmax); + } break; + case DK3_BMEPS_RGB_ALPHA_FLATE: { + dk3pdf_out_col_not8_not_mixed(job, pc, min, xmax); + } break; + case DK3_BMEPS_GRAY_FLATE: { + dk3pdf_out_gray_not8_not_mixed(job, pc, min, xmax); + } break; + case DK3_BMEPS_GRAY_ALPHA_FLATE: { + dk3pdf_out_gray_not8_not_mixed(job, pc, min, xmax); + } break; + } + } + } + back = dk3of_end_chunk(job->of); + } + } + dk3of_close(job->of); job->of = NULL; + } + dk3stream_close(os); + } + if(back) { + switch(job->procedure) { + case DK3_BMEPS_GRAY_ALPHA_FLATE: case DK3_BMEPS_RGB_ALPHA_FLATE: { + back = dk3pdf_add_alpha_xobject(job, pc, xmax, max); + } break; + } + } + } + if(!dk3sf_fclose_fn_app(fipo, (job->xo)->tempfilename, (job->pdf)->app)) { + back = 0; + } + if(dk3sf_stat_app(&stb, (job->xo)->tempfilename, (job->pdf)->app)) { + (job->xo)->slgt = stb.sz; + } else { + back = 0; + /* ERROR: stat failed! */ + } + } else { $? "! failed to write to temp file" + } $? "- dk3pdf_xobject_data %d", back + return back; +} + + + +dk3_pdf_xobject_t * +dk3pdf_create_ixobject_progress( + dk3_pdf_t *pdf, + dk3_bif_t *bif, + dk3_bm_eps_options_t *opt, + void *pc, + int min, + int max +) +{ + dk3_pdf_image_job_t job; /* Conversion job. */ + dk3_pdf_xobject_t *back = NULL; + int analysis_types = 0; /* Analysis setup. */ + size_t nbits; /* Bits per component. */ + $? "+ dk3pdf_create_ixobject_progress %!8s min=%d max=%d",TR_8PTR(pc),min,max + nbits = dk3bif_get_bits_per_pixel(bif); + dk3pdf_image_job_init(&job, opt, pdf, bif); + switch(dk3bif_get_color_space(bif)) { + case DK3_COLOR_SPACE_RGBA: case DK3_COLOR_SPACE_GRAY_ALPHA: { + job.h_alpha = 1; + } break; + } + switch(dk3bif_get_color_space(bif)) { + case DK3_COLOR_SPACE_GRAY_ALPHA: case DK3_COLOR_SPACE_GRAY: { + } break; + default: { + job.h_color = 1; + } break; + } $? ". bif type = %d", dk3bif_get_type(bif) + switch(dk3bif_get_type(bif)) { + case DK3_BIF_IMAGE_TYPE_JPEG: { $? ". have jpeg" + if(opt->dct) { $? ". dct allowed" + switch(dk3bif_get_bits_per_pixel(bif)) { + case 1: case 2: case 4: case 8: { $? ". bpc ok" + switch(dk3bif_jpeg_get_num_components(bif)) { + case 1: { + job.procedure = DK3_BMEPS_GRAY_DCT; + job.bpc = (int)dk3bif_get_bits_per_pixel(bif); + job.use_dct = 1; + } break; + case 3: { + job.procedure = DK3_BMEPS_RGB_DCT; + job.bpc = (int)dk3bif_get_bits_per_pixel(bif); + job.use_dct = 1; + } break; + case 4: { + job.procedure = DK3_BMEPS_CMYK_DCT; + job.bpc = (int)dk3bif_get_bits_per_pixel(bif); + job.use_dct = 1; + } break; + default: { $? "! num_comp=%u", (unsigned)dk3bif_jpeg_get_num_components(bif) + } break; + } + } break; + default: { $? "! bpc=%u", (unsigned)dk3bif_get_bits_per_pixel(bif) + } break; + } + } + } break; + } + if(!(job.use_dct)) { + if(job.h_color) { analysis_types |= DK3_BIF_ANALYSIS_COLOR; } + if(job.h_alpha) { analysis_types |= DK3_BIF_ANALYSIS_ALPHA; } + if(opt->rbpc) { analysis_types |= DK3_BIF_ANALYSIS_BITS; } + if(analysis_types) { + dk3bif_analyze_progress(bif, analysis_types, pc, min, ((max + min)/2)); + if(opt->rbpc) { nbits = dk3bif_real_bits_per_pixel(bif); } + if(job.h_color) { job.h_color = dk3bif_real_color(bif); } + if(job.h_alpha) { job.h_alpha = dk3bif_real_alpha(bif); } + } +#if 0 + /* 2014-03-2 + New algorithms for bits per component detection and reduction. + */ + job.bpc = 1; + if(nbits > 1) { + job.bpc = 2; + if(nbits > 2) { + job.bpc = 4; + if(nbits > 4) { + job.bpc = 8; + } + } + } +#else + switch (nbits) { + case 1: { job.bpc = 1; } break; + case 2: { job.bpc = 2; } break; + case 4: { job.bpc = 4; } break; + default: { job.bpc = 8; } break; + } +#endif + if(job.h_color) { + if(job.h_alpha) { + switch(opt->mode) { + case DK3_BMEPS_MODE_OBJECT: + case DK3_BMEPS_MODE_PLACED_OBJECT: { + job.procedure = DK3_BMEPS_RGB_ALPHA_FLATE; + } break; + default: { + job.procedure = DK3_BMEPS_RGB_FLATE; + } break; + } + } else { + job.procedure = DK3_BMEPS_RGB_FLATE; + } + } else { + if(job.h_alpha) { + switch(opt->mode) { + case DK3_BMEPS_MODE_OBJECT: + case DK3_BMEPS_MODE_PLACED_OBJECT: { + job.procedure = DK3_BMEPS_GRAY_ALPHA_FLATE; + } break; + default: { + job.procedure = DK3_BMEPS_GRAY_FLATE; + } break; + } + } else { + job.procedure = DK3_BMEPS_GRAY_FLATE; + } + } + if(opt->pred > DK3_COMPRESSION_PREDICTOR_TIFF) { + job.bpc = 8; + } + } +#if DK3_USE_WX + $? ". show progress" + dk3bmj_progress(pc, (min + max)/2); +#endif + back = dk3pdf_xobject_new(pdf); + if(back) { + back->objno = pdf->nextobject; + if(dk3sto_add(pdf->s_xobjects, (void *)back)) { + pdf->nextobject += 1UL; + job.xo = back; + if(job.procedure == DK3_BMEPS_CMYK_DCT) { + if(dk3bif_jpeg_get_found_adobe_marker(bif)) { + back->adobe_marker_found = 1; + } + } + if(opt->ip) { + switch(dk3bif_get_type(bif)) { + case DK3_BIF_IMAGE_TYPE_JPEG: { + if(opt->jip) { + back->interpolate = 1; + } + } break; + default: { + back->interpolate = 1; + } break; + } + } + if(!dk3pdf_xobject_data(&job, pc, (min + max)/2, max)) { + back = NULL; + } + } else { + dk3pdf_xobject_delete(back); + back = NULL; + } + } +#if DK3_USE_WX + $? ". %d", max + dk3bmj_progress(pc, max); +#endif + $? "- dk3pdf_create_ixobject_progress %!8s", TR_8PTR(back) + return back; +} + + + +/* Now we use the function with progress indicator. */ +#if VERSION_BEFORE_20120104 +/** Create image XObject. + @param pdf PDF writer structure. + @param bif Image, the current frame will be added. + @param opt Conversion options. + @return Pointer to new object on success, NULL on error. +*/ +static +dk3_pdf_xobject_t * +dk3pdf_create_ixobject( + dk3_pdf_t *pdf, + dk3_bif_t *bif, + dk3_bm_eps_options_t *opt +) +{ + dk3_pdf_xobject_t *back; + $? "+ dk3pdf_create_ixobject" + back = dk3pdf_create_ixobject_progress(pdf, bif, opt, NULL, 0, 1000); + $? "- dk3pdf_create_ixobject %!8s", TR_8PTR(back) + return back; +} +#endif + + + +dk3_pdf_xobject_t * +dk3pdf_add_image_progress( + dk3_pdf_t *pdf, + dk3_bif_t *bif, + dk3_bm_eps_options_t *opt, + void *pc, + int min, + int max +) +{ + dk3_pdf_xobject_t *back = NULL; + $? "+ dk3pdf_add_image %!8s min=%d max=%d", TR_8PTR(pc), min, max + if((pdf) && (bif)) { $? ". pdf && bif" + if(pdf->cp) { $? ". pdf->cp" + if((pdf->cp)->tempof) { $? ". tempof" + back = dk3pdf_create_ixobject_progress(pdf, bif, opt, pc, min, max); + if(back) { $? ". back" + if(!dk3pdf_add_xobject_to_page(pdf, back)) { + back = NULL; + } + } + } + } + } $? "- dk3pdf_add_image %!8s", TR_8PTR(back) + return back; +} + + + +dk3_pdf_xobject_t * +dk3pdf_add_image( + dk3_pdf_t *pdf, + dk3_bif_t *bif, + dk3_bm_eps_options_t *opt +) +{ + dk3_pdf_xobject_t *back = NULL; + $? "+ dk3pdf_add_image" + back = dk3pdf_add_image_progress(pdf, bif, opt, NULL, 0, 1000); + $? "- dk3pdf_add_image %!8s", TR_8PTR(back) + return back; +} + + + +/** Write line to start object, keep object start position. + @param job PDF writer job structure. + @param on Object number. + @return 1 on success, 0 on error. +*/ +static +int +dk3pdf_begin_object(dk3_pdf_writer_job_t *job, unsigned long on) +{ + char buf[64]; /* Conversion buffer. */ + dk3_pdf_object_start_t *start; /* Start position object. */ + dk3_um_t pos; /* Start position. */ + int back = 0; + $? "+ dk3pdf_begin_object %lu", on + pos = dk3stream_bytes_written(job->os); $? ". pos" + if(on > job->largestObjectNumber) { job->largestObjectNumber = on; } + start = dk3_new_app(dk3_pdf_object_start_t,1,(job->pdf)->app); + if(start) { $? ". start" + start->objno = on; + start->startpos = pos; + if(dk3sto_add(job->s_objstart, (void *)start)) { $? ". add ok" + back = 1; + sprintf(buf, "%lu", on); $? ". sprintf" + dk3stream_c8_fputs(job->os, buf); $? ". buf" + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[8]); $? ". 8" + } else { $? "! add failed" + dk3_delete(start); + } + } else { $? "! start" + } $? "- dk3pdf_begin_object %d", back + return back; +} + + + +/** Write object end. + @param job PDF writer job structure. + @return 1 on success, 0 on error. +*/ +static +void +dk3pdf_end_object(dk3_pdf_writer_job_t *job) +{ + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[9]); $? "= dk3pdf_end_object" +} + + + + +/** Write start of PDF file. + @param job PDF writer job structure. + @return 1 on success, 0 on error. +*/ +static +int +dk3pdf_write_file_start(dk3_pdf_writer_job_t *job) +{ + char buf[64]; /* Conversion buffer. */ + dk3_pdf_page_t *pp; /* Current page. */ + unsigned long ul = 0UL; /* Number of pages. */ + dk3_time_t timer = 0UL; /* Current time. */ + dk3_tm_t locti; /* Local time. */ + int back = 1; + $? "+ dk3pdf_write_file_start" + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[7]); + if(dk3pdf_begin_object(job, 1UL)) { + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[10]); + if (0 != dk3sf_time(&timer)) { + if (0 != dk3sf_localtime_app(&locti, &timer, NULL)) { + sprintf( + buf, dk3pdf_c8_kw[101], + locti.Y, locti.M, locti.D, locti.h, locti.m, locti.s + ); + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[102]); + dk3stream_c8_fputs(job->os, buf); + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[103]); + dk3stream_c8_fputs(job->os, buf); + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[104]); + } + } + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[12]); + dk3pdf_end_object(job); + if(dk3pdf_begin_object(job, 2UL)) { + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[11]); + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[13]); + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[14]); + if((job->pdf)->documentMode) { + if((job->firstPageObjectNumber) && (job->firstPageHeight)) { + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[15]); + sprintf(buf, "%lu", job->firstPageObjectNumber); + dk3stream_c8_fputs(job->os, buf); + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[16]); + sprintf(buf, "%ld", job->firstPageHeight); + dk3stream_c8_fputs(job->os, buf); + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[17]); + } + } + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[12]); + dk3pdf_end_object(job); + if(dk3pdf_begin_object(job, 3UL)) { + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[11]); + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[57]); + ul = 0UL; + dk3sto_it_reset((job->pdf)->i_pages); + while((pp = (dk3_pdf_page_t *)dk3sto_it_next((job->pdf)->i_pages)) + != NULL + ) + { + ul++; + } + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[58]); + sprintf(buf, dk3pdf_c8_kw[59], ul); + dk3stream_c8_fputs(job->os, buf); + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[60]); + dk3sto_it_reset((job->pdf)->i_pages); + while((pp = (dk3_pdf_page_t *)dk3sto_it_next((job->pdf)->i_pages)) + != NULL + ) + { + sprintf(buf, dk3pdf_c8_kw[62], pp->objno); + dk3stream_c8_fputs(job->os, buf); + } + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[61]); + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[12]); + dk3pdf_end_object(job); + } else { $? "! begin_object" + back = 0; + } + } else { $? "! begin_object" + back = 0; + } + } else { $? "! begin_object" + back = 0; + } $? "- dk3pdf_write_file_start %d", back + return back; +} + + + +/** Write decode params for flate compression when + using a predictor. + @param os Output stream. + @param predictorline Index of predictor line. + @param bpc Bits per component. + @param procedure Compression procedure. + @param width Image width. +*/ +static +void +dk3pdf_decode_parms( + dk3_stream_t *os, + int predictorline, + int bpc, + int procedure, + dk3_bif_coord_t width +) +{ + char buf[256]; /* Conversion buffer. */ + $? "+ dk3pdf_decode_parms" + dk3stream_c8_fputs(os, dk3pdf_c8_kw[64]); + dk3stream_c8_fputs(os, dk3pdf_c8_kw[predictorline]); + sprintf(buf, "%d", bpc); + dk3stream_c8_fputs(os, dk3pdf_c8_kw[31]); + dk3stream_c8_fputs(os, buf); + dk3stream_c8_fputs(os, dk3pdf_c8_kw[0]); + dk3stream_c8_fputs(os, dk3pdf_c8_kw[65]); + switch(procedure) { + case DK3_BMEPS_CMYK_DCT: { + dk3stream_c8_fputs(os, dk3pdf_c8_kw[66]); + } break; + case DK3_BMEPS_GRAY_UNCOMPRESSED: + case DK3_BMEPS_GRAY_RUNLENGTH: + case DK3_BMEPS_GRAY_DCT: + case DK3_BMEPS_GRAY_FLATE: + case DK3_BMEPS_GRAY_ALPHA_FLATE: { + dk3stream_c8_fputs(os, dk3pdf_c8_kw[67]); + } break; + default: { + dk3stream_c8_fputs(os, dk3pdf_c8_kw[68]); + } break; + } + dk3stream_c8_fputs(os, dk3pdf_c8_kw[0]); + dk3stream_c8_fputs(os, dk3pdf_c8_kw[69]); + sprintf(buf, "%ld", width); + dk3stream_c8_fputs(os, buf); + dk3stream_c8_fputs(os, dk3pdf_c8_kw[0]); + dk3stream_c8_fputs(os, dk3pdf_c8_kw[12]); $? "- dk3pdf_decode_parms" +} + + + +/** Write XObjects of PDF file. + @param job PDF writer job structure. + @param pcomm Communicator object. + @param minpb Minimum progress bar value. + @param maxpb Maximum progress bar value. + @return 1 on success, 0 on error. +*/ +static +int +dk3pdf_write_file_xobjects( + dk3_pdf_writer_job_t *job, + void *pcomm, + int minpb, + int maxpb +) +{ + char buf[64]; /* Conversion buffer. */ + char sbuf[4096]; /* Data transfer bufer. */ + dk3_pdf_xobject_t *xo; /* Current XObject. */ + dk3_pdf_xobject_t *xmask; /* Mask for object. */ + FILE *fipo; /* Input file (object stream). */ + size_t rb; /* Number of bytes read. */ + int back = 1; + int cc; /* Flag: Can continue transfer. */ + $? "+ dk3pdf_write_file_xobjects" + dk3sto_it_reset((job->pdf)->i_xobjects); + while((xo = (dk3_pdf_xobject_t *)dk3sto_it_next((job->pdf)->i_xobjects)) + != NULL + ) + { + if(dk3pdf_begin_object(job, xo->objno)) { + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[11]); + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[27]); /* /Type /XObject */ + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[28]); /* /Subtype /Image */ + sprintf(buf, "%ld", xo->width); + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[29]); + dk3stream_c8_fputs(job->os, buf); + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[0]); + sprintf(buf, "%ld", xo->height); + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[30]); + dk3stream_c8_fputs(job->os, buf); + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[0]); + sprintf(buf, "%d", xo->bpc); + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[31]); + dk3stream_c8_fputs(job->os, buf); + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[0]); + switch(xo->xot) { + case DK3_PDF_XO_TYPE_ALPHA: { + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[32]); + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[34]); + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[36]); + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[37]); + } break; + default: { + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[32]); + switch(xo->procedure) { + case DK3_BMEPS_CMYK_DCT: { + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[33]); + if(xo->adobe_marker_found) { + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[40]); + } + } break; + case DK3_BMEPS_GRAY_DCT: + case DK3_BMEPS_GRAY_FLATE: + case DK3_BMEPS_GRAY_ALPHA_FLATE: { + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[34]); + } break; + default: { + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[35]); + } break; + } + if(xo->mask) { + xmask = (dk3_pdf_xobject_t *)(xo->mask); + sprintf(buf, "%lu", xmask->objno); + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[46]); + dk3stream_c8_fputs(job->os, buf); + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[47]); + } + if(xo->interpolate) { + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[63]); + } + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[36]); + if(xo->dct) { + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[38]); + } else { + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[37]); + } + } break; + } + if(!(xo->dct)) { + switch(xo->pred) { + case DK3_COMPRESSION_PREDICTOR_TIFF: { + dk3pdf_decode_parms(job->os, 41, xo->bpc, xo->procedure, xo->width); + /* dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[41]); */ + } break; + case DK3_COMPRESSION_PREDICTOR_PNG_SUB: { + dk3pdf_decode_parms(job->os, 42, xo->bpc, xo->procedure, xo->width); + /* dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[42]); */ + } break; + case DK3_COMPRESSION_PREDICTOR_PNG_UP: { + dk3pdf_decode_parms(job->os, 43, xo->bpc, xo->procedure, xo->width); + /* dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[43]); */ + } break; + case DK3_COMPRESSION_PREDICTOR_PNG_AVERAGE: { + dk3pdf_decode_parms(job->os, 44, xo->bpc, xo->procedure, xo->width); + /* dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[44]); */ + } break; + case DK3_COMPRESSION_PREDICTOR_PNG_PAETH: { + dk3pdf_decode_parms(job->os, 45, xo->bpc, xo->procedure, xo->width); + /* dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[45]); */ + } break; + } + } + if(dk3ma_um_to_c8_string(buf, sizeof(buf), xo->slgt)) { + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[39]); + dk3stream_c8_fputs(job->os, buf); + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[0]); + } + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[12]); + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[25]); + /* Data stream */ + fipo = dk3sf_fopen_app( + xo->tempfilename, + dk3app_not_localized(36), + (job->pdf)->app + ); + if(fipo) { + do { + cc = 0; + rb = dk3sf_fread_app(sbuf, 1, sizeof(sbuf), fipo, (job->pdf)->app); + if(rb > 0) { + cc = 1; + if(rb != dk3stream_write_bytes(job->os, sbuf, rb)) { + back = 0; + /* ERROR While writing data! */ + } + } + } while(cc); + if(!dk3sf_fclose_fn_app(fipo, xo->tempfilename, (job->pdf)->app)) { + back = 0; + } + fipo = NULL; + } else { + back = 0; + /* ERROR: Failed to open file! */ + } + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[26]); + dk3pdf_end_object(job); + } else { + back = 0; + /* ERROR: Failed to begin Xobject! */ + } +#if DK3_USE_WX + dk3bmj_obj_progress(pcomm,minpb,maxpb,(job->pdf)->nextobject,(xo->objno + 1UL)); +#endif + } $? "- dk3pdf_write_file_xobjects %d", back + return back; +} + + + +/** Write pages of PDF file. + @param job PDF writer job structure. + @param pcomm Communicator object. + @param minpb Minimum progress bar value. + @param maxpb Maximum progress bar value. + @return 1 on success, 0 on error. +*/ +static +int +dk3pdf_write_file_pages( + dk3_pdf_writer_job_t *job, + void *pcomm, + int minpb, + int maxpb +) +{ + char buf[4096]; /* Data transfer buffer. */ + FILE *fipo; /* Input file (page contents stream). */ + dk3_pdf_page_t *cp; /* Current page. */ + dk3_pdf_xobject_t *xo; /* Traverse XObjects. */ + size_t rb; /* Number of bytes read. */ + int back = 1; + int have_mask; /* Flag: Have alpha mask. */ + int cc; /* Flag: Can continue transfer. */ + $? "+ dk3pdf_write_file_pages" + dk3sto_it_reset((job->pdf)->i_pages); + while((cp = (dk3_pdf_page_t *)dk3sto_it_next((job->pdf)->i_pages)) != NULL) { + $? ". page found" + /* + Mark all Xobjects as unused. + */ + dk3sto_it_reset((job->pdf)->i_xobjects); + while((xo = (dk3_pdf_xobject_t *)dk3sto_it_next((job->pdf)->i_xobjects)) + != NULL + ) + { + xo->used = 0; + } $? ". all objects marked as unused" + /* + Mark Xobjects used by this page. + */ + have_mask = 0; + if((cp->s_xobjects) && (cp->i_xobjects)) { + dk3sto_it_reset(cp->i_xobjects); + while((xo = (dk3_pdf_xobject_t *)dk3sto_it_next(cp->i_xobjects)) != NULL) + { + xo->used = 1; $? ". object found" + if(xo->mask) { $? ". object with mask" + have_mask = 1; + } + } + } $? ". used objects marked" + /* + Write page object. + */ + $? ". going to write objects" + if(dk3pdf_begin_object(job, cp->objno)) { $? ". begin_object" + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[11]); /* << */ + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[48]); $? ". 48" + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[49]); $? ". 49" + sprintf(buf, dk3pdf_c8_kw[50], cp->mbx0, cp->mby0, cp->mbx1, cp->mby1); + dk3stream_c8_fputs(job->os, buf); $? ". buf" + sprintf(buf, dk3pdf_c8_kw[100], cp->mbx0, cp->mby0, cp->mbx1, cp->mby1); + dk3stream_c8_fputs(job->os, buf); + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[51]); /* /Resources << */ + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[11]); $? ". 11" + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[52]); $? ". 52" + if((cp->s_xobjects) && (cp->i_xobjects)) { $? ". objects" + sprintf(buf, dk3pdf_c8_kw[53], (cp->objno + 2UL)); $? ". sprintf" + dk3stream_c8_fputs(job->os, buf); $? ". buf" + } + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[12]); /* >> */ + sprintf(buf, dk3pdf_c8_kw[54], (cp->objno + 1UL)); $? ". sprintf" + dk3stream_c8_fputs(job->os, buf); $? ". buf" + /* Group (for alpha) */ + if(have_mask) { $? ". have_mask" + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[55]); $? ". 55" + } + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[12]); /* >> */ + dk3pdf_end_object(job); $? ". page object finished" + /* + Write content stream object. + */ + if(dk3pdf_begin_object(job, (cp->objno + 1UL))) { + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[11]); + if(dk3ma_um_to_c8_string(buf, sizeof(buf), cp->slgt)) { + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[39]); + dk3stream_c8_fputs(job->os, buf); + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[0]); + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[36]); + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[37]); + } else { + back = 0; + /* ERROR: Failed to convert length! */ + } + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[12]); + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[25]); + fipo = dk3sf_fopen_app( + cp->tempfilename, + dk3app_not_localized(36), + (job->pdf)->app + ); + if(fipo) { + do { + cc = 0; + rb = dk3sf_fread_app(buf, 1, sizeof(buf), fipo, (job->pdf)->app); + if(rb > 0) { + cc = 1; + if(rb != dk3stream_write_bytes(job->os, buf, rb)) { + back = 0; + /* ERROR: Write failed! */ + } + } + } while(cc); + if(!dk3sf_fclose_fn_app(fipo, cp->tempfilename, (job->pdf)->app)) { + back = 0; + } + } else { + back = 0; + /* ERROR: Failed to open file! */ + } + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[26]); + dk3pdf_end_object(job); $? ". stream object finished" + /* + Write XObjects dictionary. + */ + if((cp->s_xobjects) && (cp->i_xobjects)) { + if(dk3pdf_begin_object(job, (cp->objno + 2UL))) { + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[11]); + dk3sto_it_reset((job->pdf)->i_xobjects); + while((xo = + (dk3_pdf_xobject_t *)dk3sto_it_next((job->pdf)->i_xobjects) + ) + != NULL + ) + { + sprintf(buf, dk3pdf_c8_kw[56], xo->objno, xo->objno); + dk3stream_c8_fputs(job->os, buf); + } + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[12]); + dk3pdf_end_object(job); $? ". dictionary finished" + } else { + back = 0; + /* ERROR: Memory */ + } + } + } else { + back = 0; + /* ERROR: Memory */ + } + } else { $? "! failed to start object" + back = 0; + /* ERROR: Memory */ + } +#if DK3_USE_WX + dk3bmj_obj_progress(pcomm,minpb,maxpb,(job->pdf)->nextobject,(cp->objno + 1UL)); +#endif + } $? "- dk3pdf_write_file_pages %d", back + return back; +} + + + +/** Write end of PDF file. + @param job PDF writer job structure. + @return 1 on success, 0 on error. +*/ +static +int +dk3pdf_write_file_end(dk3_pdf_writer_job_t *job) +{ + char buf[64]; /* Conversion buffer. */ + dk3_pdf_position_t *pos; /* Position structure. */ + dk3_um_t startxref; /* Position of xref start. */ + size_t sl; /* Buffer length. */ + size_t i; /* Fill buffer with '0'. */ + int back = 1; + $? "+ dk3pdf_write_file_end" + startxref = dk3stream_bytes_written(job->os); + sprintf(buf, "%lu", (job->largestObjectNumber + 1UL)); + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[18]); + dk3stream_c8_fputs(job->os, buf); + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[0]); + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[19]); + dk3sto_it_reset(job->i_objstart); + while((pos = (dk3_pdf_position_t *)dk3sto_it_next(job->i_objstart)) != NULL) { + if(dk3ma_um_to_c8_string(buf, sizeof(buf), pos->startpos)) { + if((sl = strlen(buf)) <= 10) { + for(i = sl; i < 10; i++) { + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[20]); + } + dk3stream_c8_fputs(job->os, buf); + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[21]); + } else { + back = 0; + /* Object start position too large! */ + } + } else { + back = 0; + /* ERROR: Failed to convert position! */ + } + } + sprintf(buf, "%lu", (job->largestObjectNumber + 1UL)); + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[22]); + dk3stream_c8_fputs(job->os, buf); + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[23]); + if(dk3ma_um_to_c8_string(buf, sizeof(buf), startxref)) { + dk3stream_c8_fputs(job->os, buf); + dk3stream_c8_fputs(job->os, dk3pdf_c8_kw[24]); + } else { + back = 0; + /* ERROR: Failed to convert number! */ + } $? "- dk3pdf_write_file_end %d", back + return back; +} + + + +/** Assign object numbers to pages. +*/ +static +void +dk3pdf_enumerate_pages(dk3_pdf_writer_job_t *job) +{ + dk3_pdf_page_t *pa; /* Current page. */ + unsigned long on; /* Next object number. */ + $? "+ dk3pdf_enumerate_pages" + on = (job->pdf)->nextobject; + dk3sto_it_reset((job->pdf)->i_pages); + while((pa = (dk3_pdf_page_t *)dk3sto_it_next((job->pdf)->i_pages)) != NULL) + { + if(!(job->firstPageObjectNumber)) { + job->firstPageObjectNumber = on; + job->firstPageHeight = pa->mby1; + } + /* + Each page consumes at least two object numbers: + Page object and page content stream object. + */ + pa->objno = on++; + on++; + /* + If the page uses XObjects we must create an + XObject dictionary. + */ + if((pa->s_xobjects) && (pa->i_xobjects)) { on++; } + } + (job->pdf)->nextobject = on; + $? "- dk3pdf_enumerate_pages" +} + + + +int +dk3pdf_write_file_progress( + dk3_pdf_t *pdf, + FILE *ofile, + void *pcomm, + int minpb, + int maxpb +) +{ + dk3_pdf_writer_job_t job; /* Writer job. */ + int back = 0; + $? "+ dk3pdf_write_file" + if((pdf) && (ofile)) { $? ". args ok" + if(pdf->cp) { dk3pdf_close_page(pdf); } + if(dk3pdf_job_init(&job, pdf, ofile)) { + back = 1; + dk3pdf_enumerate_pages(&job); + if(!dk3pdf_write_file_start(&job)) { back = 0; } + if(!dk3pdf_write_file_xobjects(&job, pcomm, minpb, maxpb)) { back = 0; } + if(!dk3pdf_write_file_pages(&job, pcomm, minpb, maxpb)) { back = 0; } + if(!dk3pdf_write_file_end(&job)) { back = 0; } + } + dk3pdf_job_end(&job); + } else { + if(!(pdf)) { $? "! pdf" + } + if(!(ofile)) { $? "! ofile" + } + } $? "- dk3pdf_write_file %d", back + return back; +} + + + +int +dk3pdf_write_file(dk3_pdf_t *pdf, FILE *ofile) +{ + int back; + $? "+ dk3pdf_write_file" + back = dk3pdf_write_file_progress(pdf, ofile, NULL, 0, 1000); + $? "- dk3pdf_write_file %d", back + return back; +} + + + +/** Write point coordinates to output filter. + @param of Output filter. + @param x X value. + @param y Y value. +*/ +static +void +dk3pdf_write_point(dk3_of_t *of, double x, double y) +{ + dk3pdf_write_double(of, x); + dk3of_write_c8_string(of, dk3pdf_c8_kw[1]); + dk3pdf_write_double(of, y); + dk3of_write_c8_string(of, dk3pdf_c8_kw[1]); + $? "= dk3pdf_write_point %lg %lg", x, y +} + + + +int +dk3pdf_newpath_moveto(dk3_pdf_t *pdf, double x, double y) +{ + int back = 0; + $? "+ dk3pdf_newpath_moveto %lg %lg", x, y + if(pdf) { + if(pdf->cp) { + if((pdf->cp)->tempof) { + back = 1; + dk3pdf_write_point((pdf->cp)->tempof, x, y); + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[71]); + } + } + } $? "- dk3pdf_newpath_moveto %d", back + return back; +} + + + +int +dk3pdf_lineto(dk3_pdf_t *pdf, double x, double y) +{ + int back = 0; + $? "+ dk3pdf_lineto %lg %lg", x, y + if(pdf) { + if(pdf->cp) { + if((pdf->cp)->tempof) { + back = 1; + dk3pdf_write_point((pdf->cp)->tempof, x, y); + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[72]); + } + } + } $? "- dk3pdf_lineto %d", back + return back; +} + + + +int +dk3pdf_curveto( + dk3_pdf_t *pdf, + double xcs, double ycs, + double xce, double yce, + double xe, double ye +) +{ + int back = 0; + $? "+ dk3pdf_curveto" + if(pdf) { + if(pdf->cp) { + if((pdf->cp)->tempof) { + back = 1; + dk3pdf_write_point((pdf->cp)->tempof, xcs, ycs); + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[1]); + dk3pdf_write_point((pdf->cp)->tempof, xce, yce); + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[1]); + dk3pdf_write_point((pdf->cp)->tempof, xe, ye); + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[89]); + } + } + } $? "- dk3pdf_curveto %d", back + return back; +} + + +int +dk3pdf_set_nonstroking_gray(dk3_pdf_t *pdf, double g) +{ + int back = 0; + double ng; /* Corrected gray value. */ + $? "+ dk3pdf_set_nonstroking_gray %lg", g + ng = dk3pdf_to_range(0.0, 1.0, g); + if(pdf) { + if(pdf->cp) { + if((pdf->cp)->tempof) { + back = 1; + dk3pdf_write_double((pdf->cp)->tempof, ng); + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[1]); + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[73]); + } + } + } $? "- dk3pdf_set_nonstroking_gray %d", back + return back; +} + + + +int +dk3pdf_set_stroking_gray(dk3_pdf_t *pdf, double g) +{ + int back = 0; + double ng; /* Corrected gray value. */ + $? "+ dk3pdf_set_stroking_gray %lg", g + ng = dk3pdf_to_range(0.0, 1.0, g); + if(pdf) { + if(pdf->cp) { + if((pdf->cp)->tempof) { + back = 1; + dk3pdf_write_double((pdf->cp)->tempof, ng); + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[1]); + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[74]); + } + } + } $? "- dk3pdf_set_stroking_gray %d", back + return back; +} + + + +int +dk3pdf_closepath_fill_stroke_nz(dk3_pdf_t *pdf) +{ + int back = 0; + $? "+ dk3pdf_closepath_fill_stroke_nz" + if(pdf) { + if(pdf->cp) { + if((pdf->cp)->tempof) { + back = 1; + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[75]); + } + } + } $? "- dk3pdf_closepath_fill_stroke_nz %d", back + return back; +} + + + + +int +dk3pdf_closepath_fill_stroke_eo(dk3_pdf_t *pdf) +{ + int back = 0; + $? "+ dk3pdf_closepath_fill_stroke_eo" + if(pdf) { + if(pdf->cp) { + if((pdf->cp)->tempof) { + back = 1; + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[77]); + } + } + } $? "- dk3pdf_closepath_fill_stroke_eo %d", back + return back; +} + + + +int +dk3pdf_closepath(dk3_pdf_t *pdf) +{ + int back = 0; + $? "+ dk3pdf_closepath" + if(pdf) { + if(pdf->cp) { + if((pdf->cp)->tempof) { + back = 1; + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[81]); + } + } + } $? "- dk3pdf_closepath %d", back + return back; +} + + + +int +dk3pdf_fill_nz(dk3_pdf_t *pdf) +{ + int back = 0; + $? "+ dk3pdf_fill_nz" + if(pdf) { + if(pdf->cp) { + if((pdf->cp)->tempof) { + back = 1; + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[79]); + } + } + } $? "- dk3pdf_fill_nz %d", back + return back; +} + + + +int +dk3pdf_fill_eo(dk3_pdf_t *pdf) +{ + int back = 0; + $? "+ dk3pdf_fill_eo" + if(pdf) { + if(pdf->cp) { + if((pdf->cp)->tempof) { + back = 1; + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[80]); + } + } + } $? "- dk3pdf_fill_eo %d", back + return back; +} + + + +int +dk3pdf_clip_eo(dk3_pdf_t *pdf) +{ + int back = 0; + $? "+ dk3pdf_clip_eo" + if(pdf) { + if(pdf->cp) { + if((pdf->cp)->tempof) { + back = 1; + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[88]); + } + } + } $? "- dk3pdf_clip_eo %d", back + return back; +} + + + +int +dk3pdf_clip_nz(dk3_pdf_t *pdf) +{ + int back = 0; + $? "+ dk3pdf_clip_eo" + if(pdf) { + if(pdf->cp) { + if((pdf->cp)->tempof) { + back = 1; + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[97]); + } + } + } $? "- dk3pdf_clip_eo %d", back + return back; +} + + +int +dk3pdf_nonstroking_rgb(dk3_pdf_t *pdf, double r, double g, double b) +{ + int back = 0; + double nr; /* Corrected red. */ + double ng; /* Corrected green. */ + double nb; /* Corrected blue. */ + $? "+ dk3pdf_nonstroking_rgb %lg %lg %lg", r, g, b + nr = dk3pdf_to_range(0.0, 1.0, r); + ng = dk3pdf_to_range(0.0, 1.0, g); + nb = dk3pdf_to_range(0.0, 1.0, b); + if(pdf) { + if(pdf->cp) { + if((pdf->cp)->tempof) { + back = 1; + dk3pdf_write_double((pdf->cp)->tempof, nr); + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[1]); + dk3pdf_write_double((pdf->cp)->tempof, ng); + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[1]); + dk3pdf_write_double((pdf->cp)->tempof, nb); + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[1]); + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[82]); + } + } + } $? "- dk3pdf_nonstroking_rgb %d", back + return back; +} + + + +int +dk3pdf_stroking_rgb(dk3_pdf_t *pdf, double r, double g, double b) +{ + int back = 0; + double nr; /* Corrected red. */ + double ng; /* Corrected green. */ + double nb; /* Corrected blue. */ + $? "+ dk3pdf_stroking_rgb %lg %lg %lg", r, g, b + nr = dk3pdf_to_range(0.0, 1.0, r); + ng = dk3pdf_to_range(0.0, 1.0, g); + nb = dk3pdf_to_range(0.0, 1.0, b); + if(pdf) { + if(pdf->cp) { + if((pdf->cp)->tempof) { + back = 1; + dk3pdf_write_double((pdf->cp)->tempof, nr); + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[1]); + dk3pdf_write_double((pdf->cp)->tempof, ng); + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[1]); + dk3pdf_write_double((pdf->cp)->tempof, nb); + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[1]); + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[83]); + } + } + } $? "- dk3pdf_stroking_rgb %d", back + return back; +} + + + +int +dk3pdf_set_linecap(dk3_pdf_t *pdf, int lc) +{ + int back = 0; + $? "+ dk3pdf_set_linecap %d", lc + if(pdf) { + if(pdf->cp) { + if((pdf->cp)->tempof) { + back = 1; + switch(lc) { + case DK3_LINECAP_SQUARE: { + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[84]); + } break; + case DK3_LINECAP_ROUND: { + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[67]); + } break; + default: { + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[20]); + } break; + } + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[85]); + } + } + } $? "- dk3pdf_set_linecap %d", back + return back; +} + + + +int +dk3pdf_set_linejoin(dk3_pdf_t *pdf, int lj) +{ + int back = 0; + $? "+ dk3pdf_set_linecap %d", lj + if(pdf) { + if(pdf->cp) { + if((pdf->cp)->tempof) { + back = 1; + switch(lj) { + case DK3_LINEJOIN_BEVEL: { + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[84]); + } break; + case DK3_LINEJOIN_ROUND: { + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[67]); + } break; + default: { + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[20]); + } break; + } + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[90]); + } + } + } $? "- dk3pdf_set_linecap %d", back + return back; +} + + +int +dk3pdf_stroke(dk3_pdf_t *pdf) +{ + int back = 0; + $? "+ dk3pdf_stroke" + if(pdf) { + if(pdf->cp) { + if((pdf->cp)->tempof) { + back = 1; + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[94]); + } + } + } $? "- dk3pdf_stroke %d", back + return back; +} + + + + +int +dk3pdf_set_linewidth(dk3_pdf_t *pdf, double lw) +{ + int back = 0; + $? "+ dk3pdf_set_linewidth %lg", lw + if(pdf) { + if(pdf->cp) { + if((pdf->cp)->tempof) { + back = 1; + dk3pdf_write_double((pdf->cp)->tempof, lw); + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[87]); + } + } + } $? "- dk3pdf_set_linewidth %d", back + return back; +} + + + +int +dk3pdf_set_line_dash(dk3_pdf_t *pdf, double *sv, size_t nsv, double ph) +{ + size_t i; + int back = 0; + if((pdf) && (sv)) { + if(pdf->cp) { + if((pdf->cp)->tempof) { + back = 1; + /* [ */ + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[92]); + for(i = 0; i < nsv; i++) { + if(0 < i) { + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[1]); + } + dk3pdf_write_double((pdf->cp)->tempof, sv[i]); + } + /* ] */ + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[93]); + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[1]); + /* phase */ + dk3pdf_write_double((pdf->cp)->tempof, ph); + /* d + newline */ + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[91]); + } + } + } + return back; +} + + + +int +dk3pdf_write_debug_line(dk3_pdf_t *pdf, char const *txt) +{ + int back = 0; + if((pdf) && (txt)) { + if(pdf->cp) { + if((pdf->cp)->tempof) { + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[98]); + dk3of_write_c8_string((pdf->cp)->tempof, txt); + dk3of_write_c8_string((pdf->cp)->tempof, dk3pdf_c8_kw[0]); + back = 1; + } + } + } + return back; +} + |