/* Copyright (c) 2004-2010, 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 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. */ /** @file dkfigei.c Image information support for the EPS driver. */ /** Inside the dkfigei module. */ #define DKFIGEI_C 1 #include "dkfig.h" #if DK_HAVE_SETJMP_H #include #endif #line 59 "dkfigei.ctr" /** Image attached information structure. */ typedef struct { int ec; /**< Error code. */ dkfig_eps_output_instruction *oi; /**< Output instruction. */ dk_fig_object *o; /**< Object. */ dkfig_eps_image_info *ii; /**< Image info. */ int ft; /**< File type. */ char *fn; /**< File name. */ FILE *inf; /**< Input file (the image). */ FILE *outf; /**< Output file (PS data). */ dk_stream_t *s1; /**< Directly writing to file. */ dk_stream_t *s2; /**< Output filtering stream. */ int fl; /**< Flag: Flipped. */ int r; /**< Background color red component. */ int g; /**< Background color green component. */ int b; /**< Background color blue component. */ /* for PNG conversion */ dk_fig_dcc dcc; /**< Color cell. */ unsigned long w; /**< Image width. */ unsigned long h; /**< Image height. */ int ch; /**< Number of color channels. */ int ct; /**< Color type. */ int bd; /**< Base driver. */ int have_bg; /**< Flag: Background color known. */ } iai; /** File type/file name suffix pair. */ typedef struct { int tp; /**< File type. */ char *sfx; /**< File name suffix. */ } ft_suffix_t; /** File type and suffix table. */ static ft_suffix_t ftsuffix[] = { { 0, (char *)".eps" }, { 0, (char *)".ps" }, { 1, (char *)".png" }, { 2, (char *)".jpg" }, { 2, (char *)".jpeg" }, { 3, (char *)".pbm" }, { 3, (char *)".pnm" }, { 3, (char *)".ppm" }, { 3, (char *)".pgm" } }; /** Number of entries in the table. */ static size_t nftsuffix = sizeof(ftsuffix)/sizeof(ft_suffix_t); /** File open mode: Write binary. */ static char str_wb[] = { "wb" }; /** File open mode: Read binary. */ static char str_rb[] = { "rb" }; /** File open mode: Write. */ static char str_w[] = { "w" }; /** Search string to find bounding box in an embedded PS/EPS image. */ static char bb_search[] = { "%%BoundingBox:" }; /** Initialize iai structure. @param ia IAI structure to initialize. */ static void null_iai DK_P1(iai *,ia) { if(ia) { ia->ec = 0; ia->oi = NULL; ia->o = NULL; ia->ii = NULL; ia->ft = 0; ia->fn = NULL; ia->inf = NULL; ia->outf = NULL; ia->s1 = NULL; ia->s2 = NULL; ia->fl = 0; ia->r = 0; ia->g = 0; ia->b = 0; (ia->dcc).red = 255; (ia->dcc).green = 255; (ia->dcc).blue = 255; ia->ch = 0; ia->ct = 0; ia->bd = 0; ia->have_bg = 0; } } /** Delete image information used by EPS driver. @param i Image information. */ void dkfig_eps_image_info_delete DK_P1(dkfig_eps_image_info *,i) { if(i) { if(i->filename) { char *ptr; (void)dksf_remove_file(i->filename); ptr = i->filename; dk_delete(ptr); } i->xmin = 0L; i->width = 0L; i->ymin = 0L; i->height = 0L; i->type = 0; i->filename = NULL; dk_delete(i); } } /** Create image information used by EPS driver. @param fn Name of image file. @return Pointer to new image information on success, NULL on error. */ dkfig_eps_image_info * dkfig_eps_image_info_new DK_P1(char *,fn) { dkfig_eps_image_info *back = NULL; if(fn) { back = dk_new(dkfig_eps_image_info,1); if(back) { back->xmin = 0L; back->width = 0L; back->ymin = 0L; back->height = 0L; back->type = -1; /* unknown type */ back->colored = 0; back->binary = 0; back->filename = dkstr_dup(fn); if(!(back->filename)) { dkfig_eps_image_info_delete(back); back = NULL; } } } return back; } /** Check whether or not we can use separated color streams for an image. @param w Image width. @param h Image height. @return 1=Yes, we can 0=No we can't. */ int dkfig_ei_check_separated_strings DK_P2(unsigned long,w, unsigned long,h) { int back = 1, me = 0; double xw, xh, pr; xw = dkma_l_to_double(w); xh = dkma_l_to_double(h); pr = dkma_mul_double_ok(xw, xh, &me); if(me || (pr >= 65535.0)) { back = 0; } return back; } /** Check whether or not to create separated strings for R, G and B. @param oi EPS output instruction. @param w Image width. @param h Image height. */ static void check_separated_strings DK_P3(dkfig_eps_output_instruction *,oi, unsigned long,w, unsigned long,h) { if(!dkfig_ei_check_separated_strings(w,h)) { (oi->c)->opt1 &= (~(DKFIG_OPT_SEPARATED_RGB)); } } /** Get image type. @param fn Image file name. @return 0=ps/eps, 1=png, 2=jpg, 3=NetPBM. */ int dkfig_ei_get_image_type DK_P1(char *,fn) { int back = -1; char *sfx = NULL; size_t lfd = 0; sfx = dksf_get_file_type_dot(fn); if(sfx) { lfd = 0; while((lfd < nftsuffix) && (back == -1)) { #if DK_HAVE_FNCASEINS if(dkstr_casecmp(sfx, ftsuffix[lfd].sfx) == 0) { #else if(strcmp(sfx, ftsuffix[lfd].sfx) == 0) { #endif back = ftsuffix[lfd].tp; } lfd++; } } return back; } /** Open streams to write color data. @param ia IAI structure. @return 1 on success, 0 on error. */ static int create_the_streams DK_P1(iai *,ia) { int back = 0; ia->s1 = dkstream_for_file(ia->outf); if(ia->s1) { switch(((ia->oi)->c)->psl) { case 1: { ia->s2 = dkof_open(ia->s1, 1); if(ia->s2) { dkof_set_crnl(ia->s2, 1); if(dkof_set(ia->s2, 0, DK_OF_TYPE_ASCIIHEX)) { back = 1; } if(!((((ia->oi)->c)->psl > 1) && ((ia->ii)->colored))) { dkof_set_finalizing(ia->s2, 0); } } } break; case 2: { if((((ia->oi)->c)->opt1) & DKFIG_OPT_ALLOW_PSRL) { ia->s2 = dkof_open(ia->s1, 2); if(ia->s2) { dkof_set_crnl(ia->s2, 1); if(dkof_set(ia->s2, 0, DK_OF_TYPE_ASCII85)) { if(dkof_set(ia->s2, 1, DK_OF_TYPE_PSRL)) { back = 1; } } } } else { ia->s2 = dkof_open(ia->s1, 1); if(ia->s2) { dkof_set_crnl(ia->s2, 1); if(dkof_set(ia->s2, 0, DK_OF_TYPE_ASCII85)) { back = 1; } } } } break; default: { ia->s2 = dkof_open(ia->s1, 2); if(ia->s2) { dkof_set_crnl(ia->s2, 1); if(dkof_set(ia->s2, 0, DK_OF_TYPE_ASCII85)) { if(dkof_set(ia->s2, 1, DK_OF_TYPE_FLATE)) { back = 1; } } } } break; } } return back; } /** Close the output streams. @param ia IAI structure. @return 0. */ static int destroy_the_streams DK_P1(iai *,ia) { int back = 0; if(ia->s2) { dkstream_close(ia->s2); ia->s2 = NULL; } if(ia->s1) { dkstream_close(ia->s1); ia->s1 = NULL; } return back; } /* The functions below are run w*h time for an image, we turn off debug message printing here as it slows down the application too much. */ #line 386 "dkfigei.ctr" /** Convert RGB to gray. @param r Red. @param g Green. @param b Blue. @return Gray. */ static unsigned ntsc DK_P3(unsigned, r, unsigned, g, unsigned, b) { unsigned long l1, l2, l3, l4; l1 = 54UL * (unsigned long)r; l2 = 183UL * (unsigned long)g; l3 = 19UL * (unsigned long)b; l4 = l1 + l2 + l3; l4 = (l4 >> 8) & 0x000000FFUL; return((unsigned)l4); } /** Write one value. @param ia IAI structure. @param v Value to write. @return 1 on success, 0 on error. */ static int write_one_value DK_P2(iai *,ia, unsigned,v) { int back = 0; unsigned char onechar; onechar = (unsigned char)(v & 0x00FF); if(dkstream_write(ia->s2, (char *)(&onechar), 1) == 1) { back = 1; } return back; } #if 0 /* really not needed? */ static int push_rgb DK_P1(iai *,ia) { int back = 0; unsigned r, g, b; unsigned char buffer[4]; r = ia->r; g = ia->g; b = ia->b; if((((ia->oi)->c)->psl > 1) && ((ia->ii)->colored)) { buffer[0] = (unsigned char)(r & 0x00FF); buffer[1] = (unsigned char)(g & 0x00FF); buffer[2] = (unsigned char)(b & 0x00FF); buffer[3] = '\0'; if(dkstream_write(ia->s2, buffer, 3) == 3) { back = 1; } } else { if(write_one_value(ia, ntsc(r,g,b))) { back = 1; } } return back; } #endif /* OK, the functions invoked for each pixel are done now, we can turn tracing back on. */ #line 465 "dkfigei.ctr" /** Transfer PS/EPS image data to temporary data stream. @param ia IAI structure. @return 1 on success, 0 on error. */ static int apply_eps DK_P1(iai *,ia) { int back = 0, state = 0; size_t minlgt; long llx = 0L, lly = 0L, urx = 0L, ury = 0L; char inputline[1024]; /* 256 should be sufficient */ char *ptr; ((ia->oi)->c)->opt1 &= (~(DKFIG_OPT_SEPARATED_RGB)); ia->inf = (((ia->oi)->c)->app) ? dkapp_fopen(((ia->oi)->c)->app, ia->fn, str_rb) : dksf_fopen(ia->fn, str_rb) ; if(ia->inf) { ia->outf = (((ia->oi)->c)->app) ? dkapp_fopen(((ia->oi)->c)->app, (ia->ii)->filename, str_wb) : dksf_fopen((ia->ii)->filename, str_w); if(ia->outf) { minlgt = strlen(bb_search); while(fgets(inputline, sizeof(inputline), ia->inf)) { fputs(inputline, ia->outf); ptr = inputline; while(*ptr) { if(isascii(*ptr)) { if(!isprint(*ptr)) { switch(*ptr) { case ' ': case '\t': case '\r': case '\n': { } break; default: { (ia->ii)->binary = 1; } break; } } } else { (ia->ii)->binary = 1; } ptr++; } if(state < 2) { if(strlen(inputline) > minlgt) { if(strncmp(inputline, bb_search, minlgt) == 0) { ptr = dkstr_start(&(inputline[minlgt]), NULL); if(ptr) { if(sscanf(ptr, "%ld %ld %ld %ld", &llx, &lly, &urx, &ury) == 4) { back = 1; if(state == 0) { state = 2; } } else { state = 1; } } } } } } fclose(ia->outf); ia->outf = NULL; } else { if(((ia->oi)->c)->app) { dkapp_err_fopenw(((ia->oi)->c)->app, (ia->ii)->filename); } } fclose(ia->inf); ia->inf = NULL; } else { if(((ia->oi)->c)->app) { dkapp_err_fopenr(((ia->oi)->c)->app, ia->fn); } } if(back) { (ia->ii)->xmin = llx; (ia->ii)->ymin = lly; (ia->ii)->width = urx - llx; (ia->ii)->height = ury - lly; } if(state == 0) { dkfig_tool2_msg3((ia->oi)->c, DK_LOG_LEVEL_ERROR, 84, 61, ia->fn); back = 0; } return back; } #if DK_HAVE_ZLIB_H #if DK_HAVE_PNG_H /** Release memory used by a PNG image. @param array Pixel data array. @apram he Height (number of lines in the array). */ static void release_png_memory DK_P2(png_byte **,array, png_uint_32,he) { png_byte *xptr, **ptr; png_uint_32 y; if(array) { ptr = array; for(y = 0; y < he; y++) { xptr = *ptr; if(xptr) { dkmem_free(xptr); } *(ptr++) = NULL; } dkmem_free(array); } } /** Allocate memory to read PNG image. @param h Height (number of lines). @param rowbytes Number of bytes in a line. @return Pointer to lines array or NULL. */ static png_byte ** allocate_png_memory DK_P2(png_uint_32,h, png_uint_32,rowbytes) { png_byte **back = NULL, **ptr; png_uint_32 y; int ok; back = (png_byte **)dkmem_alloc(sizeof(png_bytep),h); if(back) { ptr = back; for(y = 0; y < h; y++) { *(ptr++) = NULL; } ptr = back; ok = 1; for(y = 0; y < h; y++) { *ptr = (png_bytep)dkmem_alloc(sizeof(png_byte),rowbytes); if(!(*ptr)) { ok = 0; } ptr++; } if(!ok) { release_png_memory(back, h); back = NULL; } } return back; } /** Convert value to a new bit depth. @param alt Value to convert. @param newbits New number of bits. @param altbits Original number of bits. @return The converted value. */ static int new_bit_depth DK_P3(int,alt, int,newbits, int,altbits) { int back = 0; unsigned long a, b, nb, ab; a = alt; nb = newbits; ab = altbits; b = (((2UL ^ nb)-1UL)*(a)) / ((2UL ^ ab) - 1UL); back = b; return back; } /** Mix foreground and background color. @param fg Foreground color value. @param bg Background color value. @param alpha Opacity (0=use background, 255=use foreground). @return Color mix result. */ static unsigned mix_colors DK_P3(unsigned,fg, unsigned,bg, unsigned,alpha) { unsigned back = 0; unsigned long f, b, a, bck; a = alpha; f = fg; b = bg; bck = ((a * f) + ((255UL - a) * b)) / 255UL; bck &= 0x000000FFUL; back = (unsigned)bck; return back; } /** Write PNG image data to the temporary stream. @param ia IAI structure. @param pp PNG structure. @param pi PNG information structure. @param array Memory to read PNG. @return 1 on success, 0 on error. */ static int write_png_image DK_P4(iai *,ia, png_structp,pp, png_infop,pi, png_byte **,array) { int back = 1; unsigned r, g, b, channels; png_uint_32 x, y, not_the_x; channels = (unsigned)(ia->ch); if(ia->fl == 2) { if((((ia->oi)->c)->psl > 1) && (ia->ch >= 3)) { (ia->ii)->colored = 1; if(((ia->oi)->c)->opt1 & DKFIG_OPT_SEPARATED_RGB) { for(x = 0; x < ia->w; x++) { for(y = 0; y < ia->h; y++) { r = (unsigned)((array[y])[x*channels]); if(channels == 4) { r = mix_colors( r, (ia->dcc).ired, (unsigned)((array[y])[(x+1UL)*channels-1UL]) ); } if(!write_one_value(ia,r)) { back = 0; } } } for(x = 0; x < ia->w; x++) { for(y = 0; y < ia->h; y++) { r = (unsigned)((array[y])[x*channels+1UL]); if(channels == 4) { r = mix_colors( r, (ia->dcc).igreen, (unsigned)((array[y])[(x+1UL)*channels-1UL]) ); } if(!write_one_value(ia,r)) { back = 0; } } } for(x = 0; x < ia->w; x++) { for(y = 0; y < ia->h; y++) { r = (unsigned)((array[y])[x*channels+2UL]); if(channels == 4) { r = mix_colors( r, (ia->dcc).iblue, (unsigned)((array[y])[(x+1UL)*channels-1UL]) ); } if(!write_one_value(ia,r)) { back = 0; } } } } else { for(x = 0; x < ia->w; x++) { for(y = 0; y < ia->h; y++) { r = (unsigned)((array[y])[x*channels]); g = (unsigned)((array[y])[x*channels+1UL]); b = (unsigned)((array[y])[x*channels+2UL]); if(channels == 4) { r = mix_colors( r, (ia->dcc).ired, (unsigned)((array[y])[(x+1UL)*channels-1UL]) ); g = mix_colors( g, (ia->dcc).igreen, (unsigned)((array[y])[(x+1UL)*channels-1UL]) ); b = mix_colors( b, (ia->dcc).iblue, (unsigned)((array[y])[(x+1UL)*channels-1UL]) ); } if(!write_one_value(ia,r)) { back = 0; } if(!write_one_value(ia,g)) { back = 0; } if(!write_one_value(ia,b)) { back = 0; } } } } } else { if(ia->ch >= 3) { for(x = 0; x < ia->w; x++) { for(y = 0; y < ia->h; y++) { r = (unsigned)((array[y])[x*channels]); g = (unsigned)((array[y])[x*channels+1UL]); b = (unsigned)((array[y])[x*channels+2UL]); if(channels == 4) { r = mix_colors( r, (ia->dcc).ired, (unsigned)((array[y])[(x+1UL)*channels-1UL]) ); g = mix_colors( g, (ia->dcc).igreen, (unsigned)((array[y])[(x+1UL)*channels-1UL]) ); b = mix_colors( b, (ia->dcc).iblue, (unsigned)((array[y])[(x+1UL)*channels-1UL]) ); } if(!write_one_value(ia,ntsc(r,g,b))) { back = 0; } } } } else { int bggray = 0; if(channels == 2) { bggray = ntsc((ia->dcc).ired, (ia->dcc).igreen, (ia->dcc).iblue); } for(x = 0; x < ia->w; x++) { for(y = 0; y < ia->h; y++) { r = (unsigned)((array[y])[x*channels]); if(channels == 2) { r = mix_colors( r, bggray, (unsigned)((array[y])[(x+1UL)*channels-1UL]) ); } if(!write_one_value(ia,r)) { back = 0; } } } } } } else { if((((ia->oi)->c)->psl > 1) && (ia->ch >= 3)) { (ia->ii)->colored = 1; if(((ia->oi)->c)->opt1 & DKFIG_OPT_SEPARATED_RGB) { for(y = 0; y < ia->h; y++) { for(not_the_x = 0; not_the_x < ia->w; not_the_x++) { x = not_the_x; if(ia->fl) { x = ia->w - 1 - not_the_x; } r = (unsigned)((array[y])[x*channels]); if(channels == 4) { r = mix_colors( r, (ia->dcc).ired, (unsigned)((array[y])[(x+1UL)*channels-1UL]) ); } if(!write_one_value(ia,r)) { back = 0; } } } for(y = 0; y < ia->h; y++) { for(not_the_x = 0; not_the_x < ia->w; not_the_x++) { x = not_the_x; if(ia->fl) { x = ia->w - 1 - not_the_x; } g = (unsigned)((array[y])[x*channels+1UL]); if(channels == 4) { g = mix_colors( g, (ia->dcc).igreen, (unsigned)((array[y])[(x+1UL)*channels-1UL]) ); } if(!write_one_value(ia,g)) { back = 0; } } } for(y = 0; y < ia->h; y++) { for(not_the_x = 0; not_the_x < ia->w; not_the_x++) { x = not_the_x; if(ia->fl) { x = ia->w - 1 - not_the_x; } b = (unsigned)((array[y])[x*channels+2UL]); if(channels == 4) { b = mix_colors( b, (ia->dcc).iblue, (unsigned)((array[y])[(x+1UL)*channels-1UL]) ); } if(!write_one_value(ia,b)) { back = 0; } } } } else { for(y = 0; y < ia->h; y++) { for(not_the_x = 0; not_the_x < ia->w; not_the_x++) { x = not_the_x; if(ia->fl) { x = ia->w - 1 - not_the_x; } r = (unsigned)((array[y])[x*channels]); g = (unsigned)((array[y])[x*channels+1UL]); b = (unsigned)((array[y])[x*channels+2UL]); if(channels == 4) { r = mix_colors( r, (ia->dcc).ired, (unsigned)((array[y])[(x+1UL)*channels-1UL]) ); g = mix_colors( g, (ia->dcc).igreen, (unsigned)((array[y])[(x+1UL)*channels-1UL]) ); b = mix_colors( b, (ia->dcc).iblue, (unsigned)((array[y])[(x+1UL)*channels-1UL]) ); } if(!write_one_value(ia,r)) { back = 0; } if(!write_one_value(ia,g)) { back = 0; } if(!write_one_value(ia,b)) { back = 0; } } } } } else { if(ia->ch >= 3) { for(y = 0; y < ia->h; y++) { for(not_the_x = 0; not_the_x < ia->w; not_the_x++) { x = not_the_x; if(ia->fl) { x = ia->w - 1 - not_the_x; } r = (unsigned)((array[y])[x*channels]); g = (unsigned)((array[y])[x*channels+1UL]); b = (unsigned)((array[y])[x*channels+2UL]); if(channels == 4) { r = mix_colors( r, (ia->dcc).ired, (unsigned)((array[y])[(x+1UL)*channels-1UL]) ); g = mix_colors( g, (ia->dcc).igreen, (unsigned)((array[y])[(x+1UL)*channels-1UL]) ); b = mix_colors( b, (ia->dcc).iblue, (unsigned)((array[y])[(x+1UL)*channels-1UL]) ); } if(!write_one_value(ia,ntsc(r,g,b))) { back = 0; } } } } else { int bggray = 0; if(channels == 2) { bggray = ntsc((ia->dcc).ired, (ia->dcc).igreen, (ia->dcc).iblue); } for(y = 0; y < ia->h; y++) { for(not_the_x = 0; not_the_x < ia->w; not_the_x++) { x = not_the_x; if(ia->fl) { x = ia->w - 1 - not_the_x; } r = (unsigned)((array[y])[x*channels]); if(channels == 2) { r = mix_colors( r, bggray, (unsigned)((array[y])[(x+1UL)*channels-1UL]) ); } if(!write_one_value(ia,r)) { back = 0; } } } } } } return back; } /** Handle PNG image. @param ia IAI structure. @return 1 on success, 0 on error. */ static int apply_png DK_P1(iai *,ia) { int back = 0; dk_fig_dcc dcc; int have_bg = 0; png_structp pp = NULL; png_infop pi = NULL; png_uint_32 ui32 = 0, w = 0, h = 0, rowbytes = 0; png_byte **array = NULL; png_byte ch = 0; /* PNG channels info */ int bd = 0; /* bit depth */ int ct = 0; /* color type */ int it = 0; /* interlace type */ int zt = 0; /* compression method */ int ft = 0; /* filter type */ int need_expansion, need_strip, need_pack; png_color_16 bg; png_color_16p bgp; ia->inf = (((ia->oi)->c)->app) ? dkapp_fopen(((ia->oi)->c)->app, ia->fn, str_rb) : dksf_fopen(ia->fn, str_rb) ; if(ia->inf) { dcc.ired = dcc.igreen = dcc.iblue = 255; dcc.red = dcc.green = dcc.blue = 1.0; if(dkfig_tool_must_fill(((ia->o)->fpd).af, ((ia->oi)->c)->opt1) || dkfig_tool_must_pattern(((ia->o)->fpd).af, ((ia->oi)->c)->opt1)) { if(((ia->o)->fpd).fc != ((ia->oi)->d)->transparent) { dkfig_tool_fill_dcc((ia->oi)->d, &dcc, ((ia->o)->fpd).fc); dkfig_tool_correct_dcc(&dcc, ((ia->o)->fpd).fc, ((ia->o)->fpd).af); dkfig_eps_correct_for_palette(&dcc); have_bg = 1; } } pp = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if(pp) { pi = png_create_info_struct(pp); if(pi) { #if DK_HAVE_SETJMP_H if(setjmp(pp->jmpbuf) == 0) { #endif png_init_io(pp, ia->inf); png_read_info(pp, pi); need_expansion = need_strip = need_pack = 0; ui32 = png_get_IHDR(pp, pi, &w, &h, &bd, &ct, &it, &zt, &ft); ch = png_get_channels(pp, pi); if((ct == PNG_COLOR_TYPE_PALETTE) && (bd <= 8)) { need_expansion = 1; } if((ct == PNG_COLOR_TYPE_GRAY) && (bd < 8)) { need_expansion = 1; } if(png_get_valid(pp, pi, PNG_INFO_tRNS)) { need_expansion = 1; } if(bd > 8) { need_strip = 1; } else { if(bd < 8) { need_pack = 1; } } if(need_expansion) { png_set_expand(pp); } if(need_strip) { png_set_strip_16(pp); } if(need_pack) { png_set_packing(pp); } bgp = &bg; bg.red = 255; bg.green = 255; bg.blue = 255; bg.gray = 255; bg.index = 0; if(png_get_bKGD(pp, pi, &bgp)) { if(!have_bg) { if(ct & PNG_COLOR_MASK_PALETTE) { png_colorp cpptr; int num; if(png_get_PLTE(pp, pi, &cpptr, &num)) { if(bgp->index < num) { dcc.ired = cpptr[bgp->index].red; dcc.igreen = cpptr[bgp->index].green; dcc.iblue = cpptr[bgp->index].blue; if(bd != 8) { dcc.ired = new_bit_depth(dcc.ired, 8, bd); dcc.igreen = new_bit_depth(dcc.igreen, 8, bd); dcc.iblue = new_bit_depth(dcc.iblue, 8, bd); } } } } else { dcc.ired = bg.red; dcc.igreen = bg.green; dcc.iblue = bg.blue; if(bd != 8) { dcc.ired = new_bit_depth(dcc.ired, 8, bd); dcc.igreen = new_bit_depth(dcc.igreen, 8, bd); dcc.iblue = new_bit_depth(dcc.iblue, 8, bd); } } } } dcc.red = dkma_l_to_double(dcc.ired) / 255.0; dcc.green = dkma_l_to_double(dcc.igreen) / 255.0; dcc.blue = dkma_l_to_double(dcc.iblue) / 255.0; png_read_update_info(pp, pi); ch = png_get_channels(pp, pi); ct = png_get_color_type(pp, pi); rowbytes = png_get_rowbytes(pp, pi); array = allocate_png_memory(h, rowbytes); if(array) { png_read_image(pp, array); DK_MEMCPY(&(ia->dcc), &dcc, sizeof(dk_fig_dcc)) ; ia->w = w; ia->h = h; ia->ch = ch; ia->ct = ct; ia->bd = bd; ia->have_bg = have_bg; (ia->ii)->height = h; (ia->ii)->width = w; (ia->ii)->xmin = 0L; (ia->ii)->ymin = 0L; check_separated_strings(ia->oi, w, h); ia->outf = (((ia->oi)->c)->app) ? dkapp_fopen(((ia->oi)->c)->app, (ia->ii)->filename, str_wb) : dksf_fopen((ia->ii)->filename, str_wb); if(ia->outf) { if(create_the_streams(ia)) { if(dkof_start_chunk(ia->s2)) { back = write_png_image(ia, pp, pi, array); if(!back) { dkfig_tool2_eps_error_message(ia->oi, 75); } if(!dkof_end_chunk(ia->s2)) { back = 0; dkfig_tool2_eps_error_message(ia->oi, 74); } } else { dkfig_tool2_eps_error_message(ia->oi, 73); } } else { dkfig_tool2_eps_error_message(ia->oi, 72); } destroy_the_streams(ia); fclose(ia->outf); ia->outf = NULL; } else { if(((ia->oi)->c)->app) { dkapp_err_fopenw(((ia->oi)->c)->app,(ia->ii)->filename); } } release_png_memory(array, h); } else { dkfig_tool2_eps_error_message(ia->oi, 81); } #if DK_HAVE_SETJMP_H } else { dkfig_tool2_combined_error_message((ia->oi)->c, 96, 97, ia->fn); if(array) { release_png_memory(array, h); } } #endif png_destroy_info_struct(pp, &pi); pi = NULL; } else { dkfig_tool2_eps_error_message(ia->oi, 83); } png_destroy_read_struct(&pp, NULL, NULL); pp = NULL; } else { dkfig_tool2_eps_error_message(ia->oi, 82); } fclose(ia->inf); ia->inf = NULL; } else { if(((ia->oi)->c)->app) { dkapp_err_fopenr(((ia->oi)->c)->app,ia->fn); } } return back; } #endif #endif #if DK_HAVE_JPEGLIB_H /** Flag: Error occured. */ static int had_error = 0; /** Replacement for the error exit function. @param cinfo JPEG image structure. */ static void error_exit_replacement DK_P1(j_common_ptr,cinfo) { had_error = 1; } /** JPEG image pixel. */ typedef JSAMPLE *jsptr; /** Release memory used for JPEG. @param p Pixel data array. @param h Image height (number of lines in array). */ static void release_jpeg_memory DK_P2(JSAMPLE **,p, JDIMENSION,h) { JSAMPLE *xptr, **ptr; JDIMENSION y; ptr = p; y = h; while(y--) { if(*ptr) { xptr = *ptr; dkmem_free(xptr); *ptr = NULL; ptr++; } } dkmem_free(p); } /** Allocate memory to read JPEG file. @param rl Length of one image row. @param h Height (number of rows). @return Pointer to memory or NULL. */ static JSAMPLE ** allocate_jpeg_memory DK_P2(size_t,rl, size_t,h) { int ok = 1; JSAMPLE **back = NULL, **ptr = NULL; JDIMENSION y; back = (JSAMPLE **)dkmem_alloc(sizeof(jsptr),h); if(back) { ptr = back; y = h; while(y--) { *ptr = (JSAMPLE *)dkmem_alloc(1,rl); if(!(*ptr)) { ok = 0; } ptr++; } if(!ok) { release_jpeg_memory(back,h); back = NULL; } } return back; } /** Read JPEG file contents. @param ia IAI structure. @param cinfo JPEG decompression structure. @return Pointer to new memory containing the image data. */ static JSAMPLE ** read_jpeg_file DK_P2(iai *,ia, j_decompress_ptr,cinfo) { JSAMPLE **back = NULL, **ptr; JDIMENSION w, h, y; size_t sz; int ok; sz = cinfo->output_width; sz = sz * cinfo->output_components * sizeof(JSAMPLE); back = allocate_jpeg_memory(sz, cinfo->output_height); if(back) { w = cinfo->output_width; h = cinfo->output_height; ptr = back; ok = 1; while(h && ok) { y = jpeg_read_scanlines(cinfo, ptr, h); if(!had_error) { if(y > 0) { ptr = &(ptr[y]); h = h - y; } else { ok = 0; } } else { ok = 0; } } if(!ok) { release_jpeg_memory(back, cinfo->output_height); back = NULL; dkfig_tool2_eps_error_message(ia->oi, 80); } } else { dkfig_tool2_eps_error_message(ia->oi, 81); } return back; } #if BITS_IN_JSAMPLE == 12 /** Reduce number of bits to not more than 8. @param i Value. @return Corrected value. */ static int get_value(int i) { int back; back = (i >> 4) & 0xFF; return back; } #else #if BITS_IN_JSAMPLE > 8 /** Reduce number of bits to not more than 8. */ #define get_value(i) (((i) >> (BITS_IN_JSAMPLE-8)) & 0xFF) #else /** Reduce number of bits to not more than 8. */ #define get_value(i) (((int)i) & 0xFF) #endif #endif /** Write JPEG image data to temporary stream. @param ia IAI structure. @param cinfo JPEG decompression structure. @param array Memory for JPEG data. @return 1 on success, 0 on error. */ static int write_jpeg_image_data DK_P3(iai *,ia, j_decompress_ptr,cinfo, JSAMPLE **,array) { int back = 1, what_to_do = 0, r, g, b; JDIMENSION w, h, x, y, i; JSAMPROW color_map0, color_map1, color_map2; color_map0 = color_map1 = color_map2 = NULL; if(cinfo->quantize_colors) { what_to_do = 1; color_map0 = (cinfo->colormap)[0]; if(cinfo->out_color_space == JCS_GRAYSCALE) { what_to_do = 2; } else { color_map1 = (cinfo->colormap)[1]; color_map2 = (cinfo->colormap)[2]; } } w = cinfo->output_width; h = cinfo->output_height; if(ia->fl == 2) { if( (((ia->oi)->c)->psl > 1) && (cinfo->out_color_space != JCS_GRAYSCALE) ) { (ia->ii)->colored = 1; if((((ia->oi)->c)->opt1) & DKFIG_OPT_SEPARATED_RGB) { for(x = 0; x < ia->w; x++) { for(y = 0; y < ia->h; y++) { r = (array[y])[3UL*(unsigned long)x]; if(what_to_do) { r = color_map0[r & 0xFF]; } r = get_value(r); if(!write_one_value(ia, r)) { back = 0; } } } for(x = 0; x < ia->w; x++) { for(y = 0; y < ia->h; y++) { r = (array[y])[3UL*(unsigned long)x+1UL]; if(what_to_do) { r = color_map1[r & 0xFF]; } r = get_value(r); if(!write_one_value(ia, r)) { back = 0; } } } for(x = 0; x < ia->w; x++) { for(y = 0; y < ia->h; y++) { r = (array[y])[3UL*(unsigned long)x+2UL]; if(what_to_do) { r = color_map2[r & 0xFF]; } r = get_value(r); if(!write_one_value(ia, r)) { back = 0; } } } } else { for(x = 0; x < ia->w; x++) { for(y = 0; y < ia->h; y++) { r = (array[y])[3UL*(unsigned long)x]; g = (array[y])[3UL*(unsigned long)x+1UL]; b = (array[y])[3UL*(unsigned long)x+2UL]; if(what_to_do) { r = color_map0[r & 0xFF]; g = color_map1[g & 0xFF]; b = color_map2[b & 0xFF]; } r = get_value(r); g = get_value(g); b = get_value(b); if(!write_one_value(ia, r)) { back = 0; } if(!write_one_value(ia, g)) { back = 0; } if(!write_one_value(ia, b)) { back = 0; } } } } } else { if(cinfo->out_color_space != JCS_GRAYSCALE) { for(x = 0; x < ia->w; x++) { for(y = 0; y < ia->h; y++) { r = (array[y])[3UL*(unsigned long)x]; g = (array[y])[3UL*(unsigned long)x+1UL]; b = (array[y])[3UL*(unsigned long)x+2UL]; if(what_to_do) { r = color_map0[r & 0xFF]; g = color_map1[g & 0xFF]; b = color_map2[b & 0xFF]; } r = get_value(r); g = get_value(g); b = get_value(b); if(!write_one_value(ia, ntsc(r,g,b))) { back = 0; } } } } else { for(x = 0; x < ia->w; x++) { for(y = 0; y < ia->h; y++) { r = (array[y])[x]; if(what_to_do) { r = color_map0[r & 0xFF]; } r = get_value(r); if(!write_one_value(ia, r)) { back = 0; } } } } } } else { if( (((ia->oi)->c)->psl > 1) && (cinfo->out_color_space != JCS_GRAYSCALE) ) { (ia->ii)->colored = 1; if((((ia->oi)->c)->opt1) & DKFIG_OPT_SEPARATED_RGB) { for(y = 0; y < h; y++) { for(i = 0; i < w; i++) { x = ((ia->fl) ? (w - 1 - i) : i); r = (array[y])[3UL*(unsigned long)x]; if(what_to_do) { r = color_map0[r & 0xFF]; } r = get_value(r); if(!write_one_value(ia, r)) { back = 0; } } } for(y = 0; y < h; y++) { for(i = 0; i < w; i++) { x = ((ia->fl) ? (w - 1 - i) : i); g = (array[y])[3UL*(unsigned long)x+1UL]; if(what_to_do) { g = color_map1[g & 0xFF]; } g = get_value(g); if(!write_one_value(ia, g)) { back = 0; } } } for(y = 0; y < h; y++) { for(i = 0; i < w; i++) { x = ((ia->fl) ? (w - 1 - i) : i); b = (array[y])[3UL*(unsigned long)x+2UL]; if(what_to_do) { b = color_map2[b & 0xFF]; } b = get_value(b); if(!write_one_value(ia, b)) { back = 0; } } } } else { for(y = 0; y < h; y++) { for(i = 0; i < w; i++) { x = ((ia->fl) ? (w - 1 - i) : i); r = (array[y])[3UL*(unsigned long)x]; g = (array[y])[3UL*(unsigned long)x+1UL]; b = (array[y])[3UL*(unsigned long)x+2UL]; if(what_to_do) { r = color_map0[r & 0xFF]; g = color_map1[g & 0xFF]; b = color_map2[b & 0xFF]; } r = get_value(r); g = get_value(g); b = get_value(b); if(!write_one_value(ia, r)) { back = 0; } if(!write_one_value(ia, g)) { back = 0; } if(!write_one_value(ia, b)) { back = 0; } } } } } else { if(cinfo->out_color_space != JCS_GRAYSCALE) { for(y = 0; y < h; y++) { for(i = 0; i < w; i++) { x = ((ia->fl) ? (w - 1 - i) : i); r = (array[y])[3UL*(unsigned long)x]; g = (array[y])[3UL*(unsigned long)x+1UL]; b = (array[y])[3UL*(unsigned long)x+2UL]; if(what_to_do) { r = color_map0[r & 0xFF]; g = color_map1[g & 0xFF]; b = color_map2[b & 0xFF]; } r = get_value(r); g = get_value(g); b = get_value(b); if(!write_one_value(ia, ntsc(r,g,b))) { back = 0; } } } } else { for(y = 0; y < h; y++) { for(i = 0; i < w; i++) { x = ((ia->fl) ? (w - 1 - i) : i); r = (array[y])[x]; if(what_to_do) { r = color_map0[r & 0xFF]; } r = get_value(r); if(!write_one_value(ia, r)) { back = 0; } } } } } } return back; } /** Use a JPEG file. @param ia IAI structure. @return 1 on success, 0 on error. */ static int apply_jpg DK_P1(iai *,ia) { int back = 0; JSAMPLE **array; JDIMENSION w, h; struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr jerr; had_error = 0; cinfo.err = jpeg_std_error(&jerr); jerr.error_exit = error_exit_replacement; jpeg_create_decompress(&cinfo); if(!had_error) { ia->inf = (((ia->oi)->c)->app) ? dkapp_fopen(((ia->oi)->c)->app, ia->fn, str_rb) : dksf_fopen(ia->fn, str_rb) ; if(ia->inf) { /* array = read_jpeg_file(ia, &cinfo); */ array = NULL; jpeg_stdio_src(&cinfo, ia->inf); if(!had_error) { jpeg_read_header(&cinfo, TRUE); if(!had_error) { jpeg_start_decompress(&cinfo); if(!had_error) { w = cinfo.output_width; h = cinfo.output_height; (ia->ii)->xmin = 0L; (ia->ii)->ymin = 0L; ia->w = (ia->ii)->width = w; ia->h = (ia->ii)->height = h; check_separated_strings(ia->oi, w, h); array = read_jpeg_file(ia, &cinfo); if(array) { ia->outf = (((ia->oi)->c)->app) ? dkapp_fopen(((ia->oi)->c)->app, (ia->ii)->filename, str_wb) : dksf_fopen((ia->ii)->filename, str_wb); if(ia->outf) { if(create_the_streams(ia)) { if(dkof_start_chunk(ia->s2)) { back = write_jpeg_image_data(ia, &cinfo, array); if(!back) { dkfig_tool2_eps_error_message(ia->oi, 75); } if(!dkof_end_chunk(ia->s2)) { back = 0; dkfig_tool2_eps_error_message(ia->oi, 74); } } else { dkfig_tool2_eps_error_message(ia->oi, 73); } } else { dkfig_tool2_eps_error_message(ia->oi, 72); } destroy_the_streams(ia); fclose(ia->outf); ia->outf = NULL; } else { if(((ia->oi)->c)->app) { dkapp_err_fopenw(((ia->oi)->c)->app,(ia->ii)->filename); } } release_jpeg_memory(array, h); array = NULL; } else { /* dkfig_tool2_eps_error_message(ia->oi, 80); */ } jpeg_finish_decompress(&cinfo); } else { jpeg_abort((j_common_ptr)(&cinfo)); dkfig_tool2_eps_error_message(ia->oi, 79); } } else { jpeg_abort((j_common_ptr)(&cinfo)); dkfig_tool2_eps_error_message(ia->oi, 78); } } else { dkfig_tool2_eps_error_message(ia->oi, 77); jpeg_abort((j_common_ptr)(&cinfo)); } fclose(ia->inf); ia->inf = NULL; } else { if(((ia->oi)->c)->app) { dkapp_err_fopenr(((ia->oi)->c)->app, ia->fn); } } jpeg_destroy_decompress(&cinfo); } else { dkfig_tool2_eps_error_message(ia->oi, 76); } return back; } #endif #if DK_HAVE_PNM_H || DK_HAVE_NETPBM_PNM_H #line 1654 "dkfigei.ctr" /** Normalize NetPBM value. @param v Value to normalize. @param mx Old maximum value. @param max New maximum value. @return Normalization result. */ static int normalize_pnm DK_P3(int,v, xelval,mx, int,max) { int back; long l1, l2, l3, l4; back = v; if((int)mx != max) { l1 = v; l2 = max; l3 = (long)mx; l4 = (l1 * l2) / l3; back = (int)l4; } return back; } #line 1678 "dkfigei.ctr" /** Use NetPBM file. @param ia IAI structure. @return 1 on success, 0 on error. */ static int apply_pnm DK_P1(iai *,ia) { int back = 0; int cols = 0, rows = 0, format = 0; int x, y, r, g, b; xel xe, **array; xelval maxxelval = 0; dkfig_tool_init_netpbm((ia->oi)->c); ia->inf = (((ia->oi)->c)->app) ? dkapp_fopen(((ia->oi)->c)->app, ia->fn, str_rb) : dksf_fopen(ia->fn, str_rb) ; if(ia->inf) { array = pnm_readpnm(ia->inf,&cols,&rows,&maxxelval,&format); if(array) { (ia->ii)->height = rows; (ia->ii)->width = cols; (ia->ii)->xmin = 0L; (ia->ii)->ymin = 0L; check_separated_strings(ia->oi, cols, rows); ia->outf = (((ia->oi)->c)->app) ? dkapp_fopen(((ia->oi)->c)->app, (ia->ii)->filename, str_wb) : dksf_fopen((ia->ii)->filename, str_wb); if(ia->outf) { if(create_the_streams(ia)) { if(dkof_start_chunk(ia->s2)) { back = 1; (ia->ii)->height = rows; (ia->ii)->width = cols; check_separated_strings(ia->oi, cols, rows); if(ia->fl == 2) { if( (((ia->oi)->c)->psl > 1) && (PPM_TYPE == PNM_FORMAT_TYPE(format)) ) { (ia->ii)->colored = 1; if((((ia->oi)->c)->opt1) & DKFIG_OPT_SEPARATED_RGB) { for(x = 0; x < cols; x++) { for(y = 0; y < rows; y++) { xe = (array[y])[x]; r = (int)(PPM_GETR(xe)); r = normalize_pnm(r, maxxelval, 255); if(!write_one_value(ia, r)) { back = 0; } } } for(x = 0; x < cols; x++) { for(y = 0; y < rows; y++) { xe = (array[y])[x]; r = (int)(PPM_GETG(xe)); r = normalize_pnm(r, maxxelval, 255); if(!write_one_value(ia, r)) { back = 0; } } } for(x = 0; x < cols; x++) { for(y = 0; y < rows; y++) { xe = (array[y])[x]; r = (int)(PPM_GETB(xe)); r = normalize_pnm(r, maxxelval, 255); if(!write_one_value(ia, r)) { back = 0; } } } } else { for(x = 0; x < cols; x++) { for(y = 0; y < rows; y++) { xe = (array[y])[x]; r = (int)(PPM_GETR(xe)); r = normalize_pnm(r, maxxelval, 255); g = (int)(PPM_GETG(xe)); g = normalize_pnm(g, maxxelval, 255); b = (int)(PPM_GETB(xe)); b = normalize_pnm(b, maxxelval, 255); if(!write_one_value(ia, r)) { back = 0; } if(!write_one_value(ia, g)) { back = 0; } if(!write_one_value(ia, b)) { back = 0; } } } } } else { if(PPM_TYPE == PNM_FORMAT_TYPE(format)) { for(x = 0; x < cols; x++) { for(y = 0; y < rows; y++) { xe = (array[y])[x]; r = (int)(PPM_GETR(xe)); r = normalize_pnm(r, maxxelval, 255); g = (int)(PPM_GETG(xe)); g = normalize_pnm(g, maxxelval, 255); b = (int)(PPM_GETB(xe)); b = normalize_pnm(b, maxxelval, 255); if(!write_one_value(ia, ntsc(r,g,b))) { back = 0; } } } } else { for(x = 0; x < cols; x++) { for(y = 0; y < rows; y++) { xe = (array[y])[x]; r = (int)(PNM_GET1(xe)); r = normalize_pnm(r, maxxelval, 255); if(!write_one_value(ia, r)) { back = 0; } } } } } } else { if( (((ia->oi)->c)->psl > 1) && (PPM_TYPE == PNM_FORMAT_TYPE(format)) ) { (ia->ii)->colored = 1; if((((ia->oi)->c)->opt1) & DKFIG_OPT_SEPARATED_RGB) { for(y = 0; y < rows; y++) { for(x = 0; x < cols; x++) { xe = (array[y])[(ia->fl) ? (cols - 1 - x) : x]; r = (int)(PPM_GETR(xe)); r = normalize_pnm(r, maxxelval, 255); if(!write_one_value(ia, r)) { back = 0; } } } for(y = 0; y < rows; y++) { for(x = 0; x < cols; x++) { xe = (array[y])[(ia->fl) ? (cols - 1 - x) : x]; g = (int)(PPM_GETG(xe)); g = normalize_pnm(g, maxxelval, 255); if(!write_one_value(ia, g)) { back = 0; } } } for(y = 0; y < rows; y++) { for(x = 0; x < cols; x++) { xe = (array[y])[(ia->fl) ? (cols - 1 - x) : x]; b = (int)(PPM_GETB(xe)); b = normalize_pnm(b, maxxelval, 255); if(!write_one_value(ia, b)) { back = 0; } } } } else { for(y = 0; y < rows; y++) { for(x = 0; x < cols; x++) { xe = (array[y])[(ia->fl) ? (cols - 1 - x) : x]; r = (int)(PPM_GETR(xe)); r = normalize_pnm(r, maxxelval, 255); g = (int)(PPM_GETG(xe)); g = normalize_pnm(g, maxxelval, 255); b = (int)(PPM_GETB(xe)); b = normalize_pnm(b, maxxelval, 255); if(!write_one_value(ia, r)) { back = 0; } if(!write_one_value(ia, g)) { back = 0; } if(!write_one_value(ia, b)) { back = 0; } } } } } else { if(PPM_TYPE == PNM_FORMAT_TYPE(format)) { for(y = 0; y < rows; y++) { for(x = 0; x < cols; x++) { xe = (array[y])[(ia->fl) ? (cols - 1 - x) : x]; r = (int)(PPM_GETR(xe)); r = normalize_pnm(r, maxxelval, 255); g = (int)(PPM_GETG(xe)); g = normalize_pnm(g, maxxelval, 255); b = (int)(PPM_GETB(xe)); b = normalize_pnm(b, maxxelval, 255); if(!write_one_value(ia, ntsc(r,g,b))) { back = 0; } } } } else { for(y = 0; y < rows; y++) { for(x = 0; x < cols; x++) { xe = (array[y])[(ia->fl) ? (cols - 1 - x) : x]; r = (int)(PNM_GET1(xe)); r = normalize_pnm(r, maxxelval, 255); if(!write_one_value(ia, r)) { back = 0; } } } } } } if(!back) { dkfig_tool2_eps_error_message(ia->oi, 75); } if(!dkof_end_chunk(ia->s2)) { back = 0; dkfig_tool2_eps_error_message(ia->oi, 74); } } else { dkfig_tool2_eps_error_message(ia->oi, 73); } } else { dkfig_tool2_eps_error_message(ia->oi, 72); } destroy_the_streams(ia); fclose(ia->outf); ia->outf = NULL; } else { if(((ia->oi)->c)->app) { dkapp_err_fopenw(((ia->oi)->c)->app, (ia->ii)->filename); } } pnm_freearray(array, rows); } else { dkfig_tool2_msg3((ia->oi)->c, DK_LOG_LEVEL_ERROR, 71, 61, ia->fn); } fclose(ia->inf); ia->inf = NULL; } else { if(((ia->oi)->c)->app) { dkapp_err_fopenr(((ia->oi)->c)->app, ia->fn); } } return back; } #endif /** Create EPS representation of image data into temporary stream. @param ia IAI structure. @return 1 on success, 0 on error. */ static int apply_input DK_P1(iai *,ia) { int back = 0; switch(ia->ft) { case 0: { back = apply_eps(ia); } break; case 1: { #if DK_HAVE_ZLIB_H #if DK_HAVE_PNG_H back = apply_png(ia); #else dkfig_tool2_eps_error_message(ia->oi, 70); #endif #else dkfig_tool2_eps_error_message(ia->oi, 70); #endif } break; case 2: { #if DK_HAVE_JPEGLIB_H back = apply_jpg(ia); #else dkfig_tool2_eps_error_message(ia->oi, 69); #endif } break; case 3: { #if DK_HAVE_PNM_H || DK_HAVE_NETPBM_PNM_H back = apply_pnm(ia); #else dkfig_tool2_eps_error_message(ia->oi, 68); #endif } break; default: { dkfig_tool2_eps_error_message(ia->oi, 66); } break; } return back; } /** Create dkfig_eps_image_info structure for an image. @param ia IAI structure. @return Pointer to new dkfig_eps_image_info or NULL. */ static dkfig_eps_image_info * create_eps_image_info DK_P1(iai *,ia) { dkfig_eps_image_info *back = NULL; char *filename = NULL; size_t sz; sz = (size_t)dksf_get_maxpathlen(); sz = ((sz < 128) ? 128 : ((sz > 4096) ? 4096 : sz)); filename = dk_new(char,sz); if(filename) { if((ia->oi)->c) { if(((ia->oi)->c)->app) { if(dkapp_tmpnam(((ia->oi)->c)->app, filename, sz)) { ia->ii = back = dkfig_eps_image_info_new(filename); if(back) { back->type = ia->ft; back->fl = ia->fl; if(!apply_input(ia)) { dkfig_eps_image_info_delete(back); ia->ii = back = NULL; dkfig_tool2_msg3((ia->oi)->c, DK_LOG_LEVEL_ERROR, 65, 61, ia->fn); } } else { if(((ia->oi)->c)->app) { dkapp_err_memory(((ia->oi)->c)->app, sizeof(dkfig_eps_image_info), 1); } } } else { dkfig_tool2_eps_error_message(ia->oi, 67); } } } dk_delete(filename); filename = NULL; } else { if(((ia->oi)->c)->app) { dkapp_err_memory( ((ia->oi)->c)->app, 1, sz); } } return back; } /** Attach an information to an object. For each object showing an image we have to store width/height/colors/bits per components. @param oi EPS output instruction structure. @param o Current object. @return 1 on success, 0 on error. */ int dkfig_eps_attach_image_info DK_P2(dkfig_eps_output_instruction *,oi, dk_fig_object *,o) { int back = 0; iai ia; dk_fig_polyline *p; null_iai(&ia); if(oi && o) { ia.oi = oi; ia.o = o; p = (dk_fig_polyline *)(o->data); if(p) { if(p->imagename) { if(p->flipped) { ia.fl = 1; if(((oi->c)->opt2) & DKFIG_OPT_FLIP_DIAGONAL) { ia.fl = 2; } } ia.fn = p->imagename; ia.ft = dkfig_ei_get_image_type(p->imagename); if(ia.ft > -1) { o->drve = (void *)create_eps_image_info(&ia); if(o->drve) { back = 1; } else { } } else { dkfig_tool2_eps_error_message(oi, 66); } } else { } } else { } } return back; }