/* Copyright (c) 2003-2005, Dirk Krause All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above opyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Dirk Krause nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #define DK_PNG2PDF_C 1 #include "png2pdf.h" #if HAVE_SETJMP_H #include #endif $(trace-include) #define WRITE_CLIPPATH 1 typedef struct { char *key; char *value; } key_value_pair; $* Keys for strings in string table and default values. $* static key_value_pair for_messages[] = { { "/m/00", "on" }, { "/m/01", "off" }, { "/m/02", "Mix against a given background" }, { "/m/03", "Background from command line overwrites background chunk" }, { "/m/04", "Create image mask" }, { "/m/05", "Inverted image mask levels" }, { "/m/06", "Fill draw area before image writing" }, { "/m/07", "PDF format version" }, { "/m/08", "Write transparency data to PDF" }, { "/m/09", "Alpha channel specifies transparency" }, { "/m/10", "Current configuration:" }, { "/m/11", "Check file times when running on directory" }, { "/m/12", "Processing input file \"" }, { "/m/13", "\"." }, { "/m/14", "Image interpolation (smooth transitions)" }, { "/m/15", "Too many file names!" }, { "/m/16", "Failed to obtain color palette from file!" }, { "/m/17", "Not enough memory (RAM/swap space) for image data!" }, { "/m/18", "Failed to read PNG image from file \"" }, { "/m/19", "Failed to create PNG info structure, not enough memory!" }, { "/m/20", "Failed to create PNG read structure, not enough memory!" }, { "/m/21", "Failed to set up encoding, not enough memory!" }, { "/m/22", "Failed to create encoding stream, not enough memory!" }, { "/m/23", "Failed to create output stream, not enough memory!" }, { "/m/24", "Internal error: Failed to find name for directory entry!"}, { "/m/25", "File name \""}, { "/m/26", "\" is too long for buffer!"}, { "/m/27", "\" (file corrupted or not a PNG?)!"}, }; static size_t sz_for_messages = sizeof(for_messages)/sizeof(key_value_pair); static char *versions[] = { "1.2", "1.3", "1.4", NULL }; static char str_minus[] = { "-" }; static char str_threespc[] = { " " }; static void simple_msg DK_P3(Png2PdfCmd *,c, int,l, size_t,nr) { if(c) { if((c->a) && (c->msgptr)) { if(nr < sz_for_messages) { char *logmsg[2]; logmsg[0] = (c->msgptr)[nr]; logmsg[1] = NULL; dkapp_log_msg(c->a,l,logmsg,1); } } } } static void combined_msg DK_P5(Png2PdfCmd *,c, int,l, size_t,n1, size_t,n2, char *,fn) { if(c) { if((c->a) && (c->msgptr)) { if((n1 < sz_for_messages) && (n2 < sz_for_messages)) { if(fn) { char *logmsg[4]; logmsg[0] = (c->msgptr)[n1]; logmsg[1] = fn; logmsg[2] = (c->msgptr)[n2]; logmsg[3] = NULL; dkapp_log_msg(c->a,l,logmsg,3); } } } } } static int mix_colors DK_P3(int,fg, int,bg, int,a) { int back = 0; unsigned long f, b, bck; $? "+ mix_colors fg=%d bg=%d a=%d", fg, bg, a f = fg; b = bg; bck = ((a * f) + ((255UL - a) * b)) / 255UL; back = bck; $? "- mix_colors %d", back return back; } static int ntsc DK_P3(int,red,int,green,int,blue) { int back = 0; unsigned long r, g, b, bck; $? "+ ntsc %d %d %d", red, green, blue r = red; g = green; b = blue; bck = ((54UL * r) + (183UL * g) + (19UL * b)) / 256UL; back = bck; $? "- ntsc %d", back return back; } $* Clean up the cmd structure after we are done. Release memory needed by msgptr $* void png2pdf_uninitialize_cmd DK_P1(Png2PdfCmd *,c) { void *ptr; $? "+ png2pdf_uninitialize_cmd %s", TR_PTR(c) if(c) { if(c->msgptr) { ptr = (void *)(c->msgptr); dk_delete(ptr); c->msgptr = NULL; } DK_MEMRES(c,sizeof(Png2PdfCmd)); } $? "- png2pdf_uninitialize_cmd" } $* Reset all command line options except file names. $* void png2pdf_reset_cmd DK_P1(Png2PdfCmd *,c) { $? "+ png2pdf_reset_cmd %s", TR_PTR(c) /* mixing against white background by default */ (c->bg_file).r = (c->bg_file).g = (c->bg_file).b = 255; (c->bg_cmdl).r = (c->bg_cmdl).g = (c->bg_cmdl).b = 255; (c->bg_file).gray = (c->bg_cmdl).gray = 255; c->pdf_version = PNG2PDF_PDF_VERSION_14; c->options = 0; c->cmd = PNG2PDF_CMD_RUN; $? "- png2pdf_reset_cmd" } $* Completely reset the cmd structure during initialization. $* static void cmd_reset_completely DK_P1(Png2PdfCmd *,c) { $? "+ cmd_reset_completely %s", TR_PTR(c) png2pdf_reset_cmd(c); c->a = NULL; c->inputfilename = NULL; c->outputfilename = NULL; c->realfilename = NULL; c->msgptr = NULL; c->error_code = 0; $? "- cmd_reset_completely" } typedef char *CPTR; $* Initialize the command structure. Return 1 on success, 0 on error. The msgptr array for the messages is allocated dynamically. $* int png2pdf_initialize_cmd DK_P2(Png2PdfCmd *,c,dk_app_t *,a) { int back = 0; dk_string_finder_t *sf; size_t i; $? "+ png2pdf_initialize_cmd %s %s", TR_PTR(c), TR_PTR(a) if(c) { cmd_reset_completely(c); c->a = a; sf = dk_new(dk_string_finder_t,(1+sz_for_messages)); c->msgptr = dk_new(CPTR,sz_for_messages); if(sf && (c->msgptr)) { back = 1; for(i = 0; i < sz_for_messages; i++) { sf[i].key = for_messages[i].key; sf[i].default_value = for_messages[i].value; sf[i].value_pointer = &((c->msgptr)[i]); } i = sz_for_messages; sf[i].key = NULL; sf[i].default_value = NULL; sf[i].value_pointer = NULL; if(a) { dkapp_find_multi(a, sf, "png2pdf"); } else { for(i = 0; i < sz_for_messages; i++) { (c->msgptr)[i] = for_messages[i].value; } } $!trace-code if(dktrace_file()) { $!trace-code for(i = 0; i < sz_for_messages; i++) { $!trace-code fprintf(dktrace_file(), "i=%03u s=\"%s\"\n", i, (c->msgptr)[i]); $!trace-code } $!trace-code } dk_delete(sf); } else { if(sf) { dk_delete(sf); } else { if(a) { dkapp_err_memory(a,sizeof(dk_string_finder_t),sz_for_messages); } } if(c->msgptr) { dk_delete(c->msgptr); c->msgptr = NULL; } else { if(a) { dkapp_err_memory(a,sizeof(CPTR),sz_for_messages); } } } if(!back) { png2pdf_uninitialize_cmd(c); } } $? "- png2pdf_initialize_cmd %d", back return back; } static char seps[] = { " \t:," }; static int correct_range DK_P3(int,orig,int,min,int,max) { int back = orig; if(orig < min) back = min; if(orig > max) back = max; return back; } static void extract_background DK_P3(Png2PdfCmd *,c,char *,ptr,int,noisy) { char buffer[128], *s1, *s2, *s3; int success = 0, i1, i2, i3, have_dot; $? "+ extract_background %s %s", TR_PTR(c), TR_PTR(ptr) if(strlen(ptr) < sizeof(buffer)) { strcpy(buffer, ptr); s1 = dkstr_start(buffer, NULL); if(s1) { s2 = dkstr_next(s1, seps); if(s2) { s3 = dkstr_next(s2, seps); if(s3) { have_dot = 0; if(dkstr_chr(s1, '.')) have_dot = 1; if(dkstr_chr(s1, '.')) have_dot = 1; if(dkstr_chr(s1, '.')) have_dot = 1; if(have_dot) { double d1, d2, d3; if(sscanf(s1, "%lf", &d1) == 1) success++; if(sscanf(s2, "%lf", &d2) == 2) success++; if(sscanf(s3, "%lf", &d3) == 3) success++; i1 = (int)dkma_double_to_ul( dkma_mul_double(d1, 255.0) ); i2 = (int)dkma_double_to_ul( dkma_mul_double(d2, 255.0) ); i3 = (int)dkma_double_to_ul( dkma_mul_double(d3, 255.0) ); } else { if(sscanf(s1, "%d", &i1) == 1) success++; if(sscanf(s2, "%d", &i2) == 1) success++; if(sscanf(s3, "%d", &i3) == 1) success++; } i1 = correct_range(i1,0,255); i2 = correct_range(i2,0,255); i3 = correct_range(i3,0,255); if(success != 3) success = 0; if(success) { (c->bg_cmdl).r = i1; (c->bg_cmdl).g = i2; (c->bg_cmdl).b = i3; (c->bg_cmdl).gray = ntsc(i1,i2,i3); c->options |= PNG2PDF_OPT_MIX; $? ". set mix" $? ". cmd background = %d %d %d", i1, i2, i3 } } } } } if(!success) { c->options &= (~PNG2PDF_OPT_MIX); $? ". reset mix" if(dkstr_is_bool(ptr) || (*ptr == '-') || (*ptr == '+')) { switch(*ptr) { case '+': c->options |= PNG2PDF_OPT_MIX; $? ". set mix" break; case '-': c->options &= (~PNG2PDF_OPT_MIX); $? ". reset mix" break; default: { if(dkstr_is_on(ptr)) { c->options |= PNG2PDF_OPT_MIX; $? ". set mix" } else { c->options &= (~PNG2PDF_OPT_MIX); $? ". reset mix" } } break; } } else { if(noisy) { $? "! set errorcode" c->error_code = PNG2PDF_ERR_BACKGROUND_WRONG; } } } $? "- extract_background %d %d", success, ((c->options) & PNG2PDF_OPT_MIX) } static char pk_mix_bg[] = { "/mix" }; static char pk_bg_spec[] = { "/bg/cmd" }; static char pk_image_mask[] = { "/image-mask" }; static char pk_inverted_levels[] = { "/invert-levels" }; static char pk_fill_background[] = { "/fill-background" }; static char pk_pdf_level[] = { "/pdf-level" }; static char pk_transparency[] = { "/transparency" }; static char pk_alphatrans[] = { "/alpha-transparency" }; static char pk_file_time_check[] = { "/file-time-check" }; static char pk_interpolate[] = { "/image/interpolate" }; static char str_on[] = { "on" }; static char str_off[] = { "off" }; static void save_bool_to_pref DK_P3(Png2PdfCmd *,c,int,v,char *,k) { char *t; $? "+ save_bool_to_pref %s %d %s", TR_PTR(c), v, TR_STR(k) t = str_off; if((c->options) & v) { t = str_on; } dkapp_set_pref(c->a, k, t); $? "- save_bool_to_pref %s %s", TR_STR(k), TR_STR(t) } void png2pdf_save_configuration DK_P1(Png2PdfCmd *,c) { char buffer[128]; $? "+ png2pdf_save_configuration %s", TR_PTR(c) if(c->a) { $? ". application ok" strcpy(buffer, str_minus); if((c->options) & PNG2PDF_OPT_MIX) { sprintf( buffer, "%d,%d,%d", (c->bg_cmdl).r, (c->bg_cmdl).g, (c->bg_cmdl).b ); } dkapp_set_pref(c->a, pk_mix_bg, buffer); dkapp_set_pref(c->a, pk_pdf_level, versions[c->pdf_version]); save_bool_to_pref(c, PNG2PDF_OPT_BGCMD, pk_bg_spec); save_bool_to_pref(c, PNG2PDF_OPT_IMAGEMASK, pk_image_mask); save_bool_to_pref(c, PNG2PDF_OPT_INVERTLEVELS, pk_inverted_levels); save_bool_to_pref(c, PNG2PDF_OPT_FILLBACKGROUND, pk_fill_background); save_bool_to_pref(c, PNG2PDF_OPT_TRANSPARENCY, pk_transparency); save_bool_to_pref(c, PNG2PDF_OPT_ALPHA_TRANS, pk_alphatrans); save_bool_to_pref(c, PNG2PDF_OPT_MAKE, pk_file_time_check); save_bool_to_pref(c, PNG2PDF_OPT_INTERPOLATE, pk_interpolate); } $? "- png2pdf_save_configuration" } static void print_right_aligned DK_P2(char *,str,size_t,sz) { size_t x = 0; if(str) x = strlen(str); while(x++ < sz) fputc(' ', stdout); if(str) fputs(str, stdout); } void png2pdf_print_configuration DK_P1(Png2PdfCmd *,c) { char buffer[128]; size_t sz, sz1; $? "+ png2pdf_print_configuration %s %d", TR_PTR(c), ((c->options) & PNG2PDF_OPT_MIX) strcpy(buffer, str_minus); if((c->options) & PNG2PDF_OPT_MIX) { sprintf(buffer, "%d,%d,%d", (c->bg_cmdl).r, (c->bg_cmdl).g, (c->bg_cmdl).b ); } sz = strlen(buffer); sz1 = strlen((c->msgptr)[0]); if(sz1 > sz) sz = sz1; sz1 = strlen((c->msgptr)[1]); if(sz1 > sz) sz = sz1; fputs((c->msgptr)[10], stdout); fputc('\n', stdout); fputs("-p", stdout); fputs(str_threespc, stdout); print_right_aligned(versions[c->pdf_version], sz); fputs(str_threespc, stdout); fputs((c->msgptr)[7], stdout); fputc('\n', stdout); fputs("-m", stdout); fputs(str_threespc, stdout); print_right_aligned(buffer, sz); fputs(str_threespc, stdout); fputs((c->msgptr)[2], stdout); fputc('\n', stdout); fputs("-s", stdout); fputs(str_threespc, stdout); print_right_aligned((c->msgptr)[((c->options) & PNG2PDF_OPT_BGCMD)?0:1], sz); fputs(str_threespc, stdout); fputs((c->msgptr)[3], stdout); fputc('\n', stdout); fputs("-i", stdout); fputs(str_threespc, stdout); print_right_aligned((c->msgptr)[((c->options) & PNG2PDF_OPT_IMAGEMASK)?0:1], sz); fputs(str_threespc, stdout); fputs((c->msgptr)[4], stdout); fputc('\n', stdout); fputs("-a", stdout); fputs(str_threespc, stdout); print_right_aligned((c->msgptr)[((c->options) & PNG2PDF_OPT_TRANSPARENCY)?0:1], sz); fputs(str_threespc, stdout); fputs((c->msgptr)[8], stdout); fputc('\n', stdout); fputs("-l", stdout); fputs(str_threespc, stdout); print_right_aligned((c->msgptr)[((c->options) & PNG2PDF_OPT_INVERTLEVELS)?0:1], sz); fputs(str_threespc, stdout); fputs((c->msgptr)[5], stdout); fputc('\n', stdout); fputs("-t", stdout); fputs(str_threespc, stdout); print_right_aligned((c->msgptr)[((c->options) & PNG2PDF_OPT_ALPHA_TRANS)?0:1], sz); fputs(str_threespc, stdout); fputs((c->msgptr)[9], stdout); fputc('\n', stdout); fputs("-b", stdout); fputs(str_threespc, stdout); print_right_aligned((c->msgptr)[((c->options) & PNG2PDF_OPT_FILLBACKGROUND)?0:1], sz); fputs(str_threespc, stdout); fputs((c->msgptr)[6], stdout); fputc('\n', stdout); fputs("-n", stdout); fputs(str_threespc, stdout); print_right_aligned((c->msgptr)[((c->options) & PNG2PDF_OPT_INTERPOLATE)?0:1], sz); fputs(str_threespc, stdout); fputs((c->msgptr)[14], stdout); fputc('\n', stdout); fputs("-f", stdout); fputs(str_threespc, stdout); print_right_aligned((c->msgptr)[((c->options) & PNG2PDF_OPT_MAKE)?0:1], sz); fputs(str_threespc, stdout); fputs((c->msgptr)[11], stdout); fputc('\n', stdout); $? "- png2pdf_print_configuration" } static void flag_from_pref DK_P3(Png2PdfCmd *,c,int,v,char *,pk) { char buffer[128], *s1; $? "+ flag_from_pref %s %d %s", TR_PTR(c), v, TR_STR(pk) if(c->a) { $? ". app ok" if(dkapp_get_pref(c->a,pk,buffer,sizeof(buffer),0)) { s1 = dkstr_start(buffer, NULL); $? ". \"%s\"=\"%s\"", TR_STR(pk), TR_STR(s1) if(s1) { dkstr_chomp(s1, NULL); if(dkstr_is_on(s1)) { $? ". on" c->options |= v; } else { $? ". off" c->options &= (~v); } } else { $? ". off" c->options &= (~v); } } } $? "- flag_from_pref" } static void set_pdf_version DK_P2(Png2PdfCmd *,c,char *,ptr) { char *s1; int back; $? "+ set_pdf_version %s %s", TR_PTR(c), TR_STR(ptr) s1 = dkstr_start(ptr, NULL); if(s1) { dkstr_chomp(s1, NULL); back = dkstr_array_index(versions, s1, 0); if(back < 0) back = 0; if(back > PNG2PDF_PDF_VERSION_MAX) back = PNG2PDF_PDF_VERSION_MAX; c->pdf_version = back; } $? "- set_pdf_version %d", back } static void configure_from_app DK_P1(Png2PdfCmd *,c) { char buffer[128]; $? "+ configure_from_app %s", TR_PTR(c) if(c->a) { $? ". app ok" if(dkapp_get_pref(c->a, pk_mix_bg, buffer, sizeof(buffer), 0)) { extract_background(c, buffer, 0); } if(dkapp_get_pref(c->a, pk_pdf_level, buffer, sizeof(buffer), 0)) { set_pdf_version(c, buffer); } flag_from_pref(c, PNG2PDF_OPT_BGCMD, pk_bg_spec); flag_from_pref(c, PNG2PDF_OPT_IMAGEMASK, pk_image_mask); flag_from_pref(c, PNG2PDF_OPT_TRANSPARENCY, pk_transparency); flag_from_pref(c, PNG2PDF_OPT_INVERTLEVELS, pk_inverted_levels); flag_from_pref(c, PNG2PDF_OPT_FILLBACKGROUND, pk_fill_background); flag_from_pref(c, PNG2PDF_OPT_ALPHA_TRANS, pk_alphatrans); flag_from_pref(c, PNG2PDF_OPT_MAKE, pk_file_time_check); flag_from_pref(c, PNG2PDF_OPT_INTERPOLATE, pk_interpolate); } $? "- configure_from_app" } static void flag_from_opt_inv DK_P3(Png2PdfCmd *,c,int,v,char *,ptr) { int back = 0; $? "+ flag_from_opt_inv %s %d %s", TR_PTR(c), v, TR_STR(ptr) if(ptr) { if(*ptr) { switch(*ptr) { case '+': back = 1; break; case '-': back = 0; break; default : back = dkstr_is_on(ptr); break; } } else { back = 1; } } else { back = 1; } back = (back ? 0 : 1); if(back) { c->options |= v; } else { c->options &= (~v); } $? "- flag_from_opt_inv %d", back } static void flag_from_opt DK_P3(Png2PdfCmd *,c,int,v,char *,ptr) { int back = 0; $? "+ flag_from_opt %s %d %s", TR_PTR(c),v,TR_STR(ptr) if(ptr) { if(*ptr) { switch(*ptr) { case '+': back = 1; break; case '-': back = 0; break; default : back = dkstr_is_on(ptr); break; } } else { back = 1; } } else { back = 1; } if(back) { c->options |= v; } else { c->options &= (~v); } $? "- flag_from_opt %d", back } static char *long_option_keywords[] = { /* 0 */ "v$ersion", /* 1 */ "h$elp", /* 2 */ "c$onfigure", /* 3 */ "s$how-configuration", /* 4 */ "u$nconfigure", /* 5 */ "r$eset", /* 6 */ "mix-b$ackground", /* 7 */ "mix-s$pecified", /* 8 */ "im$age-mask", /* 9 */ "inv$ert-levels", /* 10 */ "fill$-background", /* 11 */ "p$df-level", /* 12 */ "t$ransparency", /* 13 */ "a$lpha-transparency", /* 14 */ "file$-time-check", /* 15 */ "int$erpolation", NULL }; $* Process the command line arguments. $* void png2pdf_process_args DK_P3(Png2PdfCmd *,c,int,argc,char **,argv) { char *ptr, *valptr, **lfdptr; int i; $? "+ png2pdf_process_args %s %d %s", TR_PTR(c),argc,TR_PTR(argv) if(c->a) { $? ". app ok" configure_from_app(c); } lfdptr = argv; lfdptr++; i = 1; while(i < argc) { ptr = *lfdptr; if(*ptr == '-') { $? ". option" ptr++; switch(*ptr) { case '-' : { $? ". long option" ptr++; valptr = dkstr_chr(ptr, '='); if(valptr) { *(valptr++) = '\0'; } switch(dkstr_array_abbr(long_option_keywords, ptr, '$', 1)) { case 0: { c->cmd |= PNG2PDF_CMD_VERSION; } break; case 1: { c->cmd |= PNG2PDF_CMD_HELP; } break; case 2: { c->cmd |= PNG2PDF_CMD_CONFIGURE; } break; case 3: { c->cmd |= PNG2PDF_CMD_SHOWCONF; } break; case 4: { c->cmd |= PNG2PDF_CMD_UNCONFIGURE; } break; case 5: { png2pdf_reset_cmd(c); } break; case 6: { if(valptr) { extract_background(c, valptr, 1); } else { c->options |= PNG2PDF_OPT_MIX; } } break; case 7: { flag_from_opt(c, PNG2PDF_OPT_BGCMD, valptr); } break; case 8: { flag_from_opt(c, PNG2PDF_OPT_IMAGEMASK, valptr); } break; case 9: { flag_from_opt(c, PNG2PDF_OPT_IMAGEMASK, valptr); } break; case 10: { flag_from_opt(c, PNG2PDF_OPT_FILLBACKGROUND, valptr); } break; case 11: { set_pdf_version(c, valptr); } break; case 12: { flag_from_opt(c, PNG2PDF_OPT_TRANSPARENCY, valptr); } break; case 13: { flag_from_opt(c, PNG2PDF_OPT_ALPHA_TRANS, valptr); } break; case 14: { flag_from_opt(c, PNG2PDF_OPT_MAKE, valptr); } break; case 15: { flag_from_opt(c, PNG2PDF_OPT_INTERPOLATE, valptr); } break; } } break; case 'v' : { $? ". version" c->cmd |= PNG2PDF_CMD_VERSION; } break; case 'h' : { $? ". help" c->cmd |= PNG2PDF_CMD_HELP; } break; case 'c' : { $? ". configure" c->cmd |= PNG2PDF_CMD_CONFIGURE; } break; case 'C' : { $? ". show configuration" c->cmd |= PNG2PDF_CMD_SHOWCONF; } break; case 'r' : { $? ". reset" png2pdf_reset_cmd(c); } break; case 'u' : { $? ". unconfigure" c->cmd |= PNG2PDF_CMD_UNCONFIGURE; } break; case 'm' : { $? ". mix against background" ptr++; if(!(*ptr)) { lfdptr++; i++; ptr = NULL; if(i < argc) { ptr = *lfdptr; } } if(ptr) { if(*ptr) { extract_background(c, ptr, 1); } } } break; case 's' : { $? ". specified background" flag_from_opt(c, PNG2PDF_OPT_BGCMD, ++ptr); } break; case 'i' : { $? ". create image mask" flag_from_opt(c, PNG2PDF_OPT_IMAGEMASK, ++ptr); } break; case 'l' : { $? ". levels inverted" flag_from_opt(c, PNG2PDF_OPT_INVERTLEVELS, ++ptr); } break; case 'b' : { $? ". background filling" flag_from_opt(c, PNG2PDF_OPT_FILLBACKGROUND, ++ptr); } break; case 'p' : { $? ". PDF format version" ptr++; if(!(*ptr)) { ptr = NULL; lfdptr++; i++; if(i < argc) { ptr = *lfdptr; } } if(ptr) { if(*ptr) { set_pdf_version(c, ptr); } } } break; case 'a' : { $? ". write transparency" flag_from_opt(c, PNG2PDF_OPT_TRANSPARENCY, ++ptr); } break; case 't' : { $? ". alpha=opacity" flag_from_opt(c, PNG2PDF_OPT_ALPHA_TRANS, ++ptr); } break; case 'f' : { $? ". file time check" flag_from_opt(c, PNG2PDF_OPT_MAKE, ++ptr); } break; case 'n' : { flag_from_opt(c, PNG2PDF_OPT_INTERPOLATE, ++ptr); } break; } } else { $? ". file name" if(c->inputfilename) { if(c->outputfilename) { /* ERROR: Too many file names */ c->error_code = PNG2PDF_ERR_TOO_MANY_FILENAMES; simple_msg(c, DK_LOG_LEVEL_ERROR, 15); } else { c->outputfilename = ptr; } } else { c->inputfilename = ptr; } } lfdptr++; i++; } $? "- png2pdf_process_args" } static int correct_bd DK_P2(int,v,int,bd) { unsigned long a, b, back; $? "+ correct_bd %d (%d)", v, bd a = v; b = bd; back = (255UL * a) / ((2UL ^ b) - 1UL); $? "- correct_bd %d", (int)back return (int)back; } #ifndef VERSNUMB #define VERSNUMB "developer" #endif static char str_eol[] = { "\r\n" }; static char str_spc[] = { " " }; static char str_obj[] = { "obj" }; static char str_endobj[] = { "endobj" }; static char str_dictopen[] = { "<<" }; static char str_dictclose[] = { ">>" }; static char str_bropen[] = { "(" }; static char str_brclose[] = { ")" }; static char str_ropen[] = { "[" }; static char str_rclose[] = { "]" }; static char str_producer[] = { "/Producer (png2pdf" VERSNUMB ")" }; static char str_0[] = { "0" }; static char str_R[] = { "R" }; static char str_type_catalog[] = { "/Type /Catalog" }; static char str_pages[] = { "/Pages" }; static char str_type_pages[] = { "/Type /Pages" }; static char str_type_page[] = { "/Type /Page" }; static char str_kids[] = { "/Kids" }; static char str_count[] = { "/Count" }; static char str_mediabox[] = { "/MediaBox" }; static char str_cropbox[] = { "/CropBox" }; static char str_rotate[] = { "/Rotate" }; static char str_parent[] = { "/Parent" }; static char str_resources[] = { "/Resources" }; static char str_procset[] = { "/ProcSet" }; static char str_pdf[] = { "/PDF" }; static char str_imagec[] = { "/ImageC" }; static char str_imageb[] = { "/ImageB" }; static char str_xobject[] = { "/XObject" }; static char str_imagemask_true[] = { "/ImageMask true" }; static char str_contents[] = { "/Contents" }; static char str_length[] = { "/Length" }; static char str_stream[] = { "stream" }; static char str_endstream[] = { "endstream" }; static char str_subtype[] = { "/Subtype" }; static char str_image[] = { "/Image" }; static char str_colorspace[] = { "/ColorSpace" }; static char str_matte[] = { "/Matte" }; static char str_g[] = { "g" }; static char str_rgb[] = { "rg" }; static char str_hf[] = { "re f" }; static char str_devicergb[] = { "/DeviceRGB" }; static char str_devicegray[] = { "/DeviceGray" }; static char str_width[] = { "/Width" }; static char str_height[] = { "/Height" }; static char str_slashH[] = { "/H" }; static char str_slashW[] = { "/W" }; static char str_bpc8[] = { "/BPC 8" }; static char str_slashCS[] = { "/CS" }; static char str_slashG[] = { "/G" }; static char str_slashRGB[] = { "/RGB" }; static char str_filter_short[] = { "/F [/A85 /Fl]" }; static char str_ID[] = { "ID" }; static char str_BI[] = { "BI" }; static char str_EI[] = { "EI" }; static char str_bitspercomponent[] = { "/BitsPerComponent" }; static char str_filtera85flate[]={ "/Filter [ /ASCII85Decode /FlateDecode ]" }; static char str_slash[] = { "/" }; static char str_mask[] = { "/Mask" }; static char str_smask[] = { "/SMask" }; static char str_type[] = { "/Type" }; static char str_n[] = { "n" }; static char str_f[] = { "f" }; static char str_xref[] = { "xref" }; static char str_trailer[] = { "trailer" }; static char str_startxref[] = { "startxref" }; static char str_eof[] = { "%%EOF" }; static char str_size[] = { "/Size" }; static char str_info[] = { "/Info" }; static char str_root[] = { "/Root" }; static char str_q[] = { "q" }; static char str_Q[] = { "Q" }; static char str_cm[] = { "cm" }; static char str_do[] = { "Do" }; static char str_interpolate[] = { "/Interpolate true" }; static char str_moveto[] = { "m" }; static char str_lineto[] = { "l" }; static char str_clip[] = { "h W n" }; #define NEXTOBJECT xr[xru++] = dkstream_get_bytes_written(c->os1) static void putdouble DK_P2(Png2PdfCmd *,c,double,d) { char buffer[32]; sprintf(buffer, "%lf", d); dkstream_puts(c->os1, buffer); } static void putul5 DK_P2(Png2PdfCmd *,c,unsigned long,x) { char buffer[32]; sprintf(buffer, "%05lu", x); dkstream_puts(c->os1, buffer); } static void putul10 DK_P2(Png2PdfCmd *,c,unsigned long,x) { char buffer[32]; sprintf(buffer, "%010lu", x); dkstream_puts(c->os1, buffer); } static void putul DK_P2(Png2PdfCmd *,c,unsigned long,x) { char buffer[32]; sprintf(buffer, "%lu", x); dkstream_puts(c->os1, buffer); } static void open_object DK_P2(Png2PdfCmd *,c,unsigned long,x) { putul(c,x); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_0); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_obj); dkstream_puts(c->os1,str_eol); } static int encoded_contents DK_P1(Png2PdfCmd *,c) { int back = 1; int fr, fg, fb, br, bg, bb, t; char buffer[4]; unsigned long x, y; png_bytep row, *rowp; $? "+ encoded_contents" if(!dkof_start_chunk(c->os2)) { back = 0; } rowp = c->rows; br = (c->bg_used).r; bg = (c->bg_used).g; bb = (c->bg_used).b; for(y = 0UL; y < (c->he); y++) { row = *(rowp++); for(x = 0UL; x < (c->wi); x++) { switch(c->ch) { case 4: { fr = row[x*((unsigned long)(c->ch))]; fg = row[1UL+x*((unsigned long)(c->ch))]; fb = row[2UL+x*((unsigned long)(c->ch))]; t = row[3UL+x*((unsigned long)(c->ch))]; if((c->options) & PNG2PDF_OPT_ALPHA_TRANS) { t = 255 -t; } if((c->options) & PNG2PDF_OPT_TRANSPARENCY) { buffer[0] = fr; buffer[1] = fg; buffer[2] = fb; } else { buffer[0] = mix_colors(fr, br, t); buffer[1] = mix_colors(fg, bg, t); buffer[2] = mix_colors(fb, bb, t); } if(dkstream_write(c->os2, buffer, 3) != 3) { back = 0; } } break; case 3: { fr = row[x*((unsigned long)(c->ch))]; fg = row[1UL+x*((unsigned long)(c->ch))]; fb = row[2UL+x*((unsigned long)(c->ch))]; buffer[0] = fr; buffer[1] = fg; buffer[2] = fb; if(dkstream_write(c->os2, buffer, 3) != 3) { back = 0; } } break; case 2: { fr = row[x*((unsigned long)(c->ch))]; t = row[1UL+x*((unsigned long)(c->ch))]; if((c->options) & PNG2PDF_OPT_ALPHA_TRANS) { t = 255 - t; } if((c->options) & PNG2PDF_OPT_TRANSPARENCY) { buffer[0] = fr; } else { buffer[0] = mix_colors(fr, (c->bg_used).gray, t); } if(dkstream_write(c->os2, buffer, 1) != 1) { back = 0; } } break; case 1: { fr = row[x*((unsigned long)(c->ch))]; buffer[0] = fr; if(dkstream_write(c->os2, buffer, 1) != 1) { back = 0; } } break; } } } if(!dkof_end_chunk(c->os2)) { back = 0; } $? "- encoded_contents %d", back return back; } static unsigned char bits[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 }; static int encoded_image_mask_or_transparency DK_P1(Png2PdfCmd *,c) { int back = 1; unsigned char uc; size_t bitno; png_bytep row, *rowp; unsigned long x, y, t; $? "+ encoded_image_mask_or_transparency" uc = 0; bitno = 0; rowp = c->rows; if(!dkof_start_chunk(c->os2)) { back = 0; $? "! failed to start chunk" } if((c->options) & PNG2PDF_OPT_TRANSPARENCY) { for(y = 0UL; y < (c->he); y++) { row = *(rowp++); for(x = 0UL; x < (c->wi); x++) { t = row[((unsigned long)(c->ch))*(x+1UL)-1UL]; if((c->options) & PNG2PDF_OPT_ALPHA_TRANS) { t = 255 - t; } uc = (unsigned char)t; if(dkstream_write(c->os2, (void *)(&uc), 1) != 1) { back = 0; $? "! write failed" } } } } else { for(y = 0UL; y < (c->he); y++) { row = *(rowp++); for(x = 0UL; x < (c->wi); x++) { t = row[((unsigned long)(c->ch))*(x+1UL)-1UL]; if((c->options) & PNG2PDF_OPT_ALPHA_TRANS) { t = 255 - t; } if((c->options) & PNG2PDF_OPT_INVERTLEVELS) { if(t < 255) { t = 0; } } if(!t) { uc |= bits[bitno]; } bitno++; if(bitno >= 8) { if(dkstream_write(c->os2, (void *)(&uc), 1) != 1) { back = 0; $? "! write ffailed" } bitno = 0; uc = 0; } } /* padding here */ if(bitno) { if(dkstream_write(c->os2, (void *)(&uc), 1) != 1) { back = 0; $? "! write failed" } } bitno = 0; uc = 0; } } if(!dkof_end_chunk(c->os2)) { back = 0; $? "! error while ending chunk" } $? "- encoded_image_mask_or_transparency %d", back return back; } static int write_output DK_P1(Png2PdfCmd *,c) { int back = 1; unsigned long xr[20]; size_t xru; unsigned long x, y, rootxru, infoxru, l1, l2, xobjxru; unsigned long xrefxru, i; int mix, torc, createxobject; double matter, matteg, matteb; $? "+ write_output" torc = 0; createxobject = 0; x = (c->options) & PNG2PDF_OPT_HAVE_FILE_BG; y = (c->options) & PNG2PDF_OPT_BGCMD; if(x && (!y)) { DK_MEMCPY(&(c->bg_used), &(c->bg_file), sizeof(Png2PdfRGB)); } else { DK_MEMCPY(&(c->bg_used), &(c->bg_cmdl), sizeof(Png2PdfRGB)); } matter = dkma_ul_to_double((unsigned long)((c->bg_used).r)) / 255.0; matteg = dkma_ul_to_double((unsigned long)((c->bg_used).g)) / 255.0; matteb = dkma_ul_to_double((unsigned long)((c->bg_used).b)) / 255.0; if((c->options) & PNG2PDF_OPT_TRANSPARENCY) torc = 1; if((c->options) & PNG2PDF_OPT_IMAGEMASK) torc = 1; if((c->options) & PNG2PDF_OPT_INTERPOLATE) createxobject = 1; mix = 0; if(((c->ch) == 2) || ((c->ch) == 4)) { mix = 1; } else { torc = 0; } xru = 0; dkstream_puts(c->os1, "%PDF-"); dkstream_puts(c->os1, versions[c->pdf_version]); dkstream_puts(c->os1,str_eol); /* Info */ NEXTOBJECT ; infoxru = xru; open_object(c, xru); dkstream_puts(c->os1, str_dictopen); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_producer); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_dictclose); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_endobj); dkstream_puts(c->os1,str_eol); /* Catalog */ NEXTOBJECT ; rootxru = xru; open_object(c, xru); dkstream_puts(c->os1, str_dictopen); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_type_catalog); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_pages); dkstream_puts(c->os1, str_spc); putul(c, (xru+1)); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_0); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_R); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_dictclose); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_endobj); dkstream_puts(c->os1,str_eol); /* Pages tree */ NEXTOBJECT ; open_object(c, xru); dkstream_puts(c->os1, str_dictopen); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_type_pages); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_kids); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_ropen); dkstream_puts(c->os1, str_spc); putul(c, (xru+1)); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_0); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_R); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_rclose); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_count); dkstream_puts(c->os1, str_spc); putul(c, 1UL); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_dictclose); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_endobj); dkstream_puts(c->os1,str_eol); /* Page */ NEXTOBJECT ; open_object(c, xru); dkstream_puts(c->os1, str_dictopen); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_type_page); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_mediabox); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_ropen); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_0); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_0); dkstream_puts(c->os1, str_spc); putul(c, c->wi); dkstream_puts(c->os1, str_spc); putul(c, c->he); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_rclose); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_cropbox); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_ropen); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_0); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_0); dkstream_puts(c->os1, str_spc); putul(c, c->wi); dkstream_puts(c->os1, str_spc); putul(c, c->he); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_rclose); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_rotate); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_0); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_parent); dkstream_puts(c->os1, str_spc); putul(c, (xru-1)); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_0); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_R); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_resources); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_dictopen); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_procset); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_ropen); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_pdf); dkstream_puts(c->os1, str_spc); switch(c->ch) { case 1: case 2: { dkstream_puts(c->os1, str_imageb); } break; default: { dkstream_puts(c->os1, str_imagec); } break; } dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_rclose); dkstream_puts(c->os1,str_eol); if(torc || createxobject) { dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_xobject); dkstream_puts(c->os1, str_spc); putul(c, (xru+3)); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_0); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_R); dkstream_puts(c->os1,str_eol); } dkstream_puts(c->os1, str_dictclose); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_contents); dkstream_puts(c->os1, str_spc); putul(c, (xru+1)); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_0); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_R); dkstream_puts(c->os1, str_eol); dkstream_puts(c->os1, str_dictclose); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_endobj); dkstream_puts(c->os1,str_eol); /* Page contents */ NEXTOBJECT ; open_object(c, xru); dkstream_puts(c->os1, str_dictopen); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_length); dkstream_puts(c->os1, str_spc); putul(c, (xru+1)); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_0); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_R); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_dictclose); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_stream); dkstream_puts(c->os1,str_eol); l1 = dkstream_get_bytes_written(c->os1); dkstream_puts(c->os1, str_q); dkstream_puts(c->os1,str_eol); #if WRITE_CLIPPATH putul(c, 0UL); dkstream_puts(c->os1, str_spc); putul(c, 0UL); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_moveto); dkstream_puts(c->os1, str_spc); putul(c, c->wi); dkstream_puts(c->os1, str_spc); putul(c, 0UL); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_lineto); dkstream_puts(c->os1, str_spc); putul(c, c->wi); dkstream_puts(c->os1, str_spc); putul(c, c->he); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_lineto); dkstream_puts(c->os1, str_spc); putul(c, 0UL); dkstream_puts(c->os1, str_spc); putul(c, c->he); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_lineto); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_clip); dkstream_puts(c->os1, str_eol); #endif if((c->options) & (PNG2PDF_OPT_IMAGEMASK|PNG2PDF_OPT_TRANSPARENCY)) { if((c->options) & PNG2PDF_OPT_FILLBACKGROUND) { switch(c->ch) { case 1: case 2: { putdouble(c, 0.3*matter+0.59*matteg+0.11*matteb); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_g); } break; default: { putdouble(c, matter); dkstream_puts(c->os1, str_spc); putdouble(c, matteg); dkstream_puts(c->os1, str_spc); putdouble(c, matteb); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_rgb); } break; } dkstream_puts(c->os1, str_eol); putul(c, 0UL); dkstream_puts(c->os1, str_spc); putul(c, 0UL); dkstream_puts(c->os1, str_spc); putul(c, c->wi); dkstream_puts(c->os1, str_spc); putul(c, c->he); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_hf); dkstream_puts(c->os1, str_eol); } } putul(c, c->wi); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_0); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_0); dkstream_puts(c->os1, str_spc); putul(c, c->he); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_0); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_0); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_cm); dkstream_puts(c->os1,str_eol); if(torc || createxobject) { dkstream_puts(c->os1, str_slash); dkstream_puts(c->os1, str_R); xobjxru = xru + 3; putul(c, (xru+3)); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_do); dkstream_puts(c->os1,str_eol); } else { /* Bild direkt hier schreiben */ dkstream_puts(c->os1, str_BI); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_slashW); dkstream_puts(c->os1, str_spc); putul(c, c->wi); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_slashH); dkstream_puts(c->os1, str_spc); putul(c, c->he); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_bpc8); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_slashCS); dkstream_puts(c->os1, str_spc); switch(c->ch) { case 1: case 2: { dkstream_puts(c->os1, str_slashG); } break; default: { dkstream_puts(c->os1, str_slashRGB); } break; } dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_filter_short); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_ID); dkstream_puts(c->os1,str_eol); if(!encoded_contents(c)) { $? "! encoded_contents failed" back = 0; } dkstream_puts(c->os1, str_EI); dkstream_puts(c->os1,str_eol); } dkstream_puts(c->os1, str_Q); dkstream_puts(c->os1,str_eol); l2 = dkstream_get_bytes_written(c->os1); dkstream_puts(c->os1, str_endstream); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_endobj); dkstream_puts(c->os1,str_eol); /* Stream length */ NEXTOBJECT ; open_object(c, xru); putul(c, (l2-l1)); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_endobj); dkstream_puts(c->os1,str_eol); if(torc || createxobject) { /* XObject name */ NEXTOBJECT ; open_object(c, xru); dkstream_puts(c->os1, str_dictopen); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_slash); dkstream_puts(c->os1, str_R); putul(c, xobjxru); dkstream_puts(c->os1, str_spc); putul(c, xobjxru); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_0); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_R); dkstream_puts(c->os1,str_eol); if(torc) { dkstream_puts(c->os1, str_slash); dkstream_puts(c->os1, str_R); putul(c, (2UL+xobjxru)); dkstream_puts(c->os1, str_spc); putul(c, (2UL+xobjxru)); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_0); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_R); dkstream_puts(c->os1,str_eol); } dkstream_puts(c->os1, str_dictclose); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_endobj); dkstream_puts(c->os1,str_eol); /* Image XObject */ NEXTOBJECT ; open_object(c, xru); dkstream_puts(c->os1, str_dictopen); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_subtype); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_image); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_colorspace); dkstream_puts(c->os1, str_spc); switch(c->ch) { case 1: case 2: { dkstream_puts(c->os1, str_devicegray); } break; default: { dkstream_puts(c->os1, str_devicergb); } break; } dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_width); dkstream_puts(c->os1, str_spc); putul(c, c->wi); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_height); dkstream_puts(c->os1, str_spc); putul(c, c->he); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_bitspercomponent); dkstream_puts(c->os1, str_spc); putul(c, 8UL); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_filtera85flate); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_length); dkstream_puts(c->os1, str_spc); putul(c, (xru+1)); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_0); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_R); dkstream_puts(c->os1,str_eol); if((c->options) & PNG2PDF_OPT_INTERPOLATE) { dkstream_puts(c->os1, str_interpolate); dkstream_puts(c->os1, str_eol); } if(torc) { if((c->options) & PNG2PDF_OPT_TRANSPARENCY) { dkstream_puts(c->os1, str_smask); } else { dkstream_puts(c->os1, str_mask); } dkstream_puts(c->os1, str_spc); putul(c, (xru+2)); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_0); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_R); dkstream_puts(c->os1,str_eol); } dkstream_puts(c->os1, str_dictclose); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_stream); dkstream_puts(c->os1,str_eol); l1 = dkstream_get_bytes_written(c->os1); if(!encoded_contents(c)) { back = 0; $? "! encoded_contents failed" } l2 = dkstream_get_bytes_written(c->os1); dkstream_puts(c->os1, str_endstream); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_endobj); dkstream_puts(c->os1,str_eol); /* Image XObject stream length */ NEXTOBJECT ; open_object(c, xru); putul(c, (l2-l1)); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_endobj); dkstream_puts(c->os1,str_eol); } if(torc) { /* image mask */ NEXTOBJECT ; open_object(c, xru); dkstream_puts(c->os1, str_dictopen); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_type); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_xobject); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_subtype); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_image); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_width); dkstream_puts(c->os1, str_spc); putul(c, c->wi); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_height); dkstream_puts(c->os1, str_spc); putul(c, c->he); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_filtera85flate); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_length); dkstream_puts(c->os1, str_spc); putul(c, (xru+1UL)); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_0); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_R); dkstream_puts(c->os1,str_eol); if((c->options) & PNG2PDF_OPT_TRANSPARENCY) { dkstream_puts(c->os1, str_bitspercomponent); dkstream_puts(c->os1, str_spc); putul(c, 8UL); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_colorspace); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_devicegray); dkstream_puts(c->os1,str_eol); } else { dkstream_puts(c->os1, str_imagemask_true); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_bitspercomponent); dkstream_puts(c->os1, str_spc); putul(c, 1UL); dkstream_puts(c->os1,str_eol); } dkstream_puts(c->os1, str_dictclose); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_stream); dkstream_puts(c->os1,str_eol); l1 = dkstream_get_bytes_written(c->os1); if(!encoded_image_mask_or_transparency(c)) { back = 0; $? "! encoded_image_mask_or_transparency failed" } l2 = dkstream_get_bytes_written(c->os1); dkstream_puts(c->os1, str_endstream); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_endobj); dkstream_puts(c->os1,str_eol); /* length */ NEXTOBJECT ; open_object(c, xru); putul(c, (l2-l1)); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_endobj); dkstream_puts(c->os1,str_eol); } /* xref section */ xrefxru = dkstream_get_bytes_written(c->os1); dkstream_puts(c->os1, str_xref); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_0); dkstream_puts(c->os1, str_spc); putul(c, (xru+1)); dkstream_puts(c->os1,str_eol); putul10(c, 0UL); dkstream_puts(c->os1, str_spc); putul5(c, 65535UL); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_f); dkstream_puts(c->os1,str_eol); for(i = 0UL; i < xru; i++) { putul10(c, xr[i]); dkstream_puts(c->os1, str_spc); putul5(c, 0UL); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_n); dkstream_puts(c->os1,str_eol); } /* trailer */ dkstream_puts(c->os1, str_trailer); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_dictopen); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_size); dkstream_puts(c->os1, str_spc); putul(c, (1UL+xru)); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_info); dkstream_puts(c->os1, str_spc); putul(c, 1UL); dkstream_puts(c->os1, str_spc); putul(c, 0UL); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_R); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_root); dkstream_puts(c->os1, str_spc); putul(c, 2UL); dkstream_puts(c->os1, str_spc); putul(c, 0UL); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_R); dkstream_puts(c->os1, str_spc); dkstream_puts(c->os1, str_dictclose); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_startxref); dkstream_puts(c->os1,str_eol); putul(c, xrefxru); dkstream_puts(c->os1,str_eol); dkstream_puts(c->os1, str_eof); dkstream_puts(c->os1,str_eol); $? "- write_output %d", back return back; } static char str_stdin[] = { "" }; static int run_conversion DK_P1(Png2PdfCmd *,c) { int back = 0; int ne, ns, np, alpha; unsigned long y; png_bytep *rowp; $? "+ run_conversion" ne = ns = np = alpha = 0; c->options &= (~PNG2PDF_OPT_HAVE_FILE_BG); /* correct command */ if((c->pdf_version) < PNG2PDF_PDF_VERSION_13) { c->options &= (~PNG2PDF_OPT_IMAGEMASK); c->options &= (~PNG2PDF_OPT_TRANSPARENCY); c->options &= (~PNG2PDF_OPT_INVERTLEVELS); c->options &= (~PNG2PDF_OPT_ALPHA_TRANS); } else { if((c->pdf_version) < PNG2PDF_PDF_VERSION_14) { if((c->options) & PNG2PDF_OPT_TRANSPARENCY) { c->options |= PNG2PDF_OPT_IMAGEMASK; } c->options &= (~PNG2PDF_OPT_TRANSPARENCY); } } if((c->options) & PNG2PDF_OPT_MIX) { alpha = 1; } if((c->options) & PNG2PDF_OPT_IMAGEMASK) { alpha = 1; } if((c->options) & PNG2PDF_OPT_TRANSPARENCY) { alpha = 1; } c->bd = c->ct = c->cu = c->it = c->zt = c->ft = c->ch = 0; c->bgp = &(c->bg); c->pp = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if(c->pp) { c->pi = png_create_info_struct(c->pp); if(c->pi) { c->rows = NULL; #if HAVE_SETJMP_H if(setjmp((c->pp)->jmpbuf) == 0) { #endif png_init_io(c->pp, c->inf); png_read_info(c->pp, c->pi); png_get_IHDR( c->pp, c->pi, &(c->wi), &(c->he), &(c->bd), &(c->ct), &(c->it), &(c->zt), &(c->ft) ); c->ch = png_get_channels(c->pp, c->pi); c->cu = c->ct; $? ". width = %lu", c->wi $? ". height = %lu", c->he $? ". bitdepth = %d", c->bd $? ". colortype = %d", c->ct $? ". interlace = %d", c->it $? ". compressiontype = %d", c->zt $? ". filtertype = %d", c->ft $? ". channels = %d", c->ch if(((c->ct) == PNG_COLOR_TYPE_PALETTE) && ((c->bd) <= 8)) { ne = 1; } if(((c->ct) == PNG_COLOR_TYPE_GRAY) && ((c->bd) < 8)) { ne = 1; } if(png_get_valid(c->pp, c->pi, PNG_INFO_tRNS)) { ne = 1; } if((c->bd) > 8) { ns = 1; } else { if((c->bd) < 8) { np = 1; } } if(ne) { png_set_expand(c->pp); } if(ns) { png_set_strip_16(c->pp); } if(np) { png_set_packing(c->pp); } if(alpha) { if(png_get_bKGD(c->pp, c->pi, &(c->bgp))) { c->options |= PNG2PDF_OPT_HAVE_FILE_BG; if((c->ct) & PNG_COLOR_MASK_PALETTE) { png_colorp ptr; int num; $? ". paletted PNG" if(png_get_PLTE(c->pp, c->pi, &ptr, &num)) { if((c->bgp)->index < num) { if((c->bd) != 8) { (c->bg_file).r = correct_bd(ptr[(c->bgp)->index].red, (c->bd)); (c->bg_file).g = correct_bd(ptr[(c->bgp)->index].green, (c->bd)); (c->bg_file).b = correct_bd(ptr[(c->bgp)->index].blue, (c->bd)); } else { (c->bg_file).r = ptr[(c->bgp)->index].red; (c->bg_file).g = ptr[(c->bgp)->index].green; (c->bg_file).b = ptr[(c->bgp)->index].blue; } } else { /* ##### ERROR: Index out of range */ c->options &= (~PNG2PDF_OPT_HAVE_FILE_BG); } } else { /* ERROR: Failed to obtain color palette */ c->options &= (~PNG2PDF_OPT_HAVE_FILE_BG); simple_msg(c, DK_LOG_LEVEL_WARNING, 16); } } else { if((c->bd) != 8) { (c->bg_file).r = correct_bd((c->bgp)->red, (c->bd)); (c->bg_file).g = correct_bd((c->bgp)->green, (c->bd)); (c->bg_file).b = correct_bd((c->bgp)->blue, (c->bd)); } else { (c->bg_file).r = (c->bgp)->red; (c->bg_file).g = (c->bgp)->green; (c->bg_file).b = (c->bgp)->blue; } } } } else { if(png_get_bKGD(c->pp, c->pi, &(c->bgp))) { png_set_background(c->pp, c->bgp, PNG_BACKGROUND_GAMMA_FILE,1,1.0); } else { png_set_background(c->pp, &(c->bg), PNG_BACKGROUND_GAMMA_SCREEN,0,1.0); } } /* gamma correction and interlace handling would go here */ png_read_update_info(c->pp, c->pi); c->ch = png_get_channels(c->pp, c->pi); c->ct = png_get_color_type(c->pp, c->pi); $? ". colortype now %d", c->ct $? ". channels now %d", c->ch c->rowbytes = png_get_rowbytes(c->pp, c->pi); c->rows = dk_new(png_bytep,(c->he)); if(c->rows) { back = 1; rowp = c->rows; for(y = 0; y < c->he; y++) { *rowp = dk_new(png_byte,(c->rowbytes)); if(!(*rowp)) { back = 0; } rowp++; } if(back) { png_read_image(c->pp, c->rows); back = write_output(c); } rowp = c->rows; for(y = 0; y < c->he; y++) { if(*rowp) { dk_delete((*rowp)); } rowp++; } dk_delete((c->rows)); } else { /* ERROR: Failed to allocate memory for rows */ simple_msg(c, DK_LOG_LEVEL_ERROR, 17); } #if HAVE_SETJMP_H } else { char *fn; fn = c->realfilename; if(!fn) { fn = str_stdin; } /* ERROR: Problem while reading PNG */ combined_msg(c, DK_LOG_LEVEL_ERROR, 18, 27, fn); if(c->rows) { rowp = c->rows; for(y = 0; y < c->he; y++) { if(*rowp) { dk_delete((*rowp)); } rowp++; } dk_delete((c->rows)); } } #endif png_destroy_info_struct(c->pp, &(c->pi)); } else { /* ERROR: Failed to create PNG info */ simple_msg(c, DK_LOG_LEVEL_ERROR, 19); } png_destroy_read_struct(&(c->pp), NULL, NULL); } else { /* ERROR: Failed to create PNG reader struct */ simple_msg(c, DK_LOG_LEVEL_ERROR, 20); } $? "- run_conversion %d", back return back; } int png2pdf_for_files DK_P1(Png2PdfCmd *,c) { int back = 0; c->os1 = dkstream_for_file(c->of); if(c->os1) { c->os2 = dkof_open(c->os1, 3); if(c->os2) { dkof_set_crnl(c->os2, 1); back = 1; if(!dkof_set(c->os2,0,DK_OF_TYPE_BUFFERED)) { back = 0; } if(!dkof_set(c->os2,1,DK_OF_TYPE_ASCII85)) { back = 0; } if(!dkof_set(c->os2,2,DK_OF_TYPE_FLATE)) { back = 0; } if(back) { back = run_conversion(c); } else { /* ERROR: Failed to set up encoding */ simple_msg(c, DK_LOG_LEVEL_ERROR, 21); } dkstream_close(c->os2); c->os2 = NULL; } else { /* ERROR: Failed to create encoding stream */ simple_msg(c, DK_LOG_LEVEL_ERROR, 22); } dkstream_close(c->os1); c->os1 = NULL; } else { /* ERROR: Failed to allocate stream */ simple_msg(c, DK_LOG_LEVEL_ERROR, 23); } return back; } #ifndef LINT static char sccs_id[] = { "@(#)png2pdf.ctr 1.25 07/18/06 (krause)\tPNG to PDF converter" }; #endif