%% options copyright owner = Dirk Krause copyright year = 2011-2014 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 */ "<< /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 >>", /* 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", }; /** 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 %s", TR_PTR(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 %s", TR_PTR(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 %s", TR_PTR(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 %s min=%d max=%d", TR_PTR(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); pc = vc; } #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); pc = vc; } #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); pc = vc; } #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 %s min=%d max=%d", TR_PTR(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 %s min=%d max=%d", TR_PTR(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 %s", TR_PTR(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 %s", TR_PTR(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 %s min=%d max=%d", TR_PTR(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 %s", TR_PTR(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 %s", TR_PTR(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. */ 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]); 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" 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; }