/* 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 $(trace-include) /** 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) { $? "+ dkfig_eps_image_info_delete %s", TR_PTR(i) if(i) { if(i->filename) { char *ptr; $? ". imagename=\"%s\"", i->filename (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); } $? "- dkfig_eps_image_info_delete" } /** 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; $? "+ dkfig_eps_image_info_new %s", TR_STR(fn) 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; } } } $? "- dkfig_eps_image_info_new %s", TR_PTR(back) 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; $? "+ dkfig_ei_check_separated_strings w=%lu h=%lu", w, h 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; } $? "- dkfig_ei_check_separated_strings %d", back 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) { $? "+ check_separated_strings" if(!dkfig_ei_check_separated_strings(w,h)) { (oi->c)->opt1 &= (~(DKFIG_OPT_SEPARATED_RGB)); $? ". reset flag" } $? "- check_separated_strings" } /** 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; $? "+ dkfig_ei_get_image_type %s", TR_STR(fn) 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++; } } $? "- dkfig_ei_get_image_type %d", back 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; $? "+ create_the_streams" ia->s1 = dkstream_for_file(ia->outf); if(ia->s1) { switch(((ia->oi)->c)->psl) { case 1: { $? ". PS level 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))) { $? ". finalizing off" dkof_set_finalizing(ia->s2, 0); } } } break; case 2: { $? ". PS level 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: { $? ". PS level 3 and above" 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; } } $? "- create_the_streams %d", back 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. */ $!trace-off /** 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; $? "+ ntsc %u %u %u", r,g,b l1 = 54UL * (unsigned long)r; l2 = 183UL * (unsigned long)g; l3 = 19UL * (unsigned long)b; l4 = l1 + l2 + l3; l4 = (l4 >> 8) & 0x000000FFUL; $? "- ntsc %u" (unsigned)l4 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; $? "+ write_one_value" onechar = (unsigned char)(v & 0x00FF); if(dkstream_write(ia->s2, (char *)(&onechar), 1) == 1) { back = 1; } $? "- write_one_value %d", back 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]; $? "+ push_rgb" 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; } } $? "- push_rgb %d", back return back; } #endif /* OK, the functions invoked for each pixel are done now, we can turn tracing back on. */ $!trace-on /** 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; $? "+ apply_eps" ((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 { $? "! Failed to open output file" if(((ia->oi)->c)->app) { dkapp_err_fopenw(((ia->oi)->c)->app, (ia->ii)->filename); } } fclose(ia->inf); ia->inf = NULL; } else { $? "! Failed to read input file" 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; } $? "- apply_eps %d", back 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; $? "+ allocate_png_memory" 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; } } $? "- allocate_png_memory %s", TR_PTR(back) 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; $? "+ new_bit_depth x=%d newbits=%d altbits=%d", alt, newbits, altbits a = alt; nb = newbits; ab = altbits; b = (((2UL ^ nb)-1UL)*(a)) / ((2UL ^ ab) - 1UL); back = b; $? "- new_bit_depth %d", back 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; $? "+ mix_colors fg=%d bg=%d a=%d", fg, bg, alpha a = alpha; f = fg; b = bg; bck = ((a * f) + ((255UL - a) * b)) / 255UL; bck &= 0x000000FFUL; back = (unsigned)bck; $? "- mix_colors %d", back 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; $? "+ write_png_image" channels = (unsigned)(ia->ch); if(ia->fl == 2) { $? ". diagonal flip" if((((ia->oi)->c)->psl > 1) && (ia->ch >= 3)) { $? ". color image" (ia->ii)->colored = 1; if(((ia->oi)->c)->opt1 & DKFIG_OPT_SEPARATED_RGB) { $? ". separated RGB sources" 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 { $? ". combined RGB source" 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 { $? ". grayscaled image" if(ia->ch >= 3) { $? ". convert color to gray" 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 { $? ". use gray from file" 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)) { $? ". color -> color" (ia->ii)->colored = 1; if(((ia->oi)->c)->opt1 & DKFIG_OPT_SEPARATED_RGB) { $? ". separated sources for R, G, B" 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 { $? ". combined source" 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) { $? ". color -> gray" 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; $? ". gray -> gray" 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; } } } } } } $? "- write_png_image %d", back 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; $? "+ apply_png" 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); $? ". w = %lu", (unsigned long)w $? ". h = %lu", (unsigned long)h $? ". bd = %d", bd $? ". ct = %d", ct $? ". it = %d", it $? ". zt = %d", zt $? ". ft = %d", ft ch = png_get_channels(pp, pi); $? ". ch = %d", ch 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) { $? ". need expansion" png_set_expand(pp); } if(need_strip) { $? ". need strip" png_set_strip_16(pp); } if(need_pack) { $? ". 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) { $? ". background chunk" if(ct & PNG_COLOR_MASK_PALETTE) { png_colorp cpptr; int num; $? ". background from palette" 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 { $? ". direct background colors" 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); $? ". ch now %d", ch ct = png_get_color_type(pp, pi); $? ". ct now %d", ct 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) { $? "! while writing output" dkfig_tool2_eps_error_message(ia->oi, 75); } if(!dkof_end_chunk(ia->s2)) { back = 0; $? "! Failed to finish chunk" dkfig_tool2_eps_error_message(ia->oi, 74); } } else { $? "! Failed to start chunk" dkfig_tool2_eps_error_message(ia->oi, 73); } } else { $? "! Failed to create streams" dkfig_tool2_eps_error_message(ia->oi, 72); } destroy_the_streams(ia); fclose(ia->outf); ia->outf = NULL; } else { $? "! Failed to open output file" if(((ia->oi)->c)->app) { dkapp_err_fopenw(((ia->oi)->c)->app,(ia->ii)->filename); } } release_png_memory(array, h); } else { $? "! Memory" dkfig_tool2_eps_error_message(ia->oi, 81); } #if DK_HAVE_SETJMP_H } else { $? "! Error while reading PNG image" 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 { $? "! Failed to create info struct" dkfig_tool2_eps_error_message(ia->oi, 83); } png_destroy_read_struct(&pp, NULL, NULL); pp = NULL; } else { $? "! Failed to create PNG read struct" dkfig_tool2_eps_error_message(ia->oi, 82); } fclose(ia->inf); ia->inf = NULL; } else { $? "! Failed to read input file" if(((ia->oi)->c)->app) { dkapp_err_fopenr(((ia->oi)->c)->app,ia->fn); } } $? "- apply_png %d", back 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) { $? "+ error_exit_replacement" had_error = 1; $? "- error_exit_replacemtn" } /** 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; $? "+ release_jpeg_memory" ptr = p; y = h; while(y--) { if(*ptr) { xptr = *ptr; dkmem_free(xptr); *ptr = NULL; ptr++; } } dkmem_free(p); $? "- release_jpeg_memory" } /** 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; $? "+ read_jpeg_file" sz = cinfo->output_width; sz = sz * cinfo->output_components * sizeof(JSAMPLE); back = allocate_jpeg_memory(sz, cinfo->output_height); if(back) { $? ". memory alloction ok" 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; $? "! Error while reading JPEG" dkfig_tool2_eps_error_message(ia->oi, 80); } } else { $? "! memory allocation failed" $? "! Memory" dkfig_tool2_eps_error_message(ia->oi, 81); } $? "- read_jpeg_file %s", TR_PTR(back) 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) ) { $? ". colored" (ia->ii)->colored = 1; if((((ia->oi)->c)->opt1) & DKFIG_OPT_SEPARATED_RGB) { $? ". 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 { $? ". combined RGB" 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 { $? ". gray" if(cinfo->out_color_space != JCS_GRAYSCALE) { $? ". color to gray" 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 { $? ". use gray from file" 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) ) { $? ". colored" (ia->ii)->colored = 1; if((((ia->oi)->c)->opt1) & DKFIG_OPT_SEPARATED_RGB) { $? ". 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 { $? ". contigous" 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 { $? ". grayscaled" if(cinfo->out_color_space != JCS_GRAYSCALE) { $? ". colored -> gray" 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 { $? ". gray -> gray" 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; $? "+ apply_jpg" 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) { $? ". input file opened successfully" /* 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) { $? ". input file was read successfully" 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) { $? ". output file opened successfully" if(create_the_streams(ia)) { $? ". streams created" if(dkof_start_chunk(ia->s2)) { $? ". chunk started" back = write_jpeg_image_data(ia, &cinfo, array); if(!back) { $? "! While writing data" dkfig_tool2_eps_error_message(ia->oi, 75); } if(!dkof_end_chunk(ia->s2)) { back = 0; $? "! Failed to finish chunk" dkfig_tool2_eps_error_message(ia->oi, 74); } } else { $? "! failed to start chunk" $? "! Failed to start chunk" dkfig_tool2_eps_error_message(ia->oi, 73); } } else { $? "! failed to create streams" $? "! Failed to create streams" dkfig_tool2_eps_error_message(ia->oi, 72); } $? ". going to destroy streams" destroy_the_streams(ia); $? ". going to close output file" fclose(ia->outf); ia->outf = NULL; } else { $? "! Failed to open output file" if(((ia->oi)->c)->app) { dkapp_err_fopenw(((ia->oi)->c)->app,(ia->ii)->filename); } } $? ". going to release jpeg memory" release_jpeg_memory(array, h); array = NULL; } else { $? ". error while reading input file" /* dkfig_tool2_eps_error_message(ia->oi, 80); */ } $? ". going to finish decompress" jpeg_finish_decompress(&cinfo); } else { jpeg_abort((j_common_ptr)(&cinfo)); $? "! While starting JPEG decompression" dkfig_tool2_eps_error_message(ia->oi, 79); } } else { jpeg_abort((j_common_ptr)(&cinfo)); $? "! While reading JPEG header" dkfig_tool2_eps_error_message(ia->oi, 78); } } else { $? "! While assigning file to JPEG decompressor" dkfig_tool2_eps_error_message(ia->oi, 77); jpeg_abort((j_common_ptr)(&cinfo)); } $? ". going to close input file" fclose(ia->inf); ia->inf = NULL; } else { $? ". failed to open input file" $? "! Failed to open input file" if(((ia->oi)->c)->app) { dkapp_err_fopenr(((ia->oi)->c)->app, ia->fn); } } jpeg_destroy_decompress(&cinfo); } else { $? "! While creating JPEG decompress" dkfig_tool2_eps_error_message(ia->oi, 76); } $? "- apply_jpg %d", back return back; } #endif #if DK_HAVE_PNM_H || DK_HAVE_NETPBM_PNM_H $!trace-off /** 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; $? "+ normalize_pnm %d %ld %d", v, (long)mx, max back = v; if((int)mx != max) { l1 = v; l2 = max; l3 = (long)mx; l4 = (l1 * l2) / l3; back = (int)l4; } $? "- normalize_pnm %d", back return back; } $!trace-on /** 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; $? "+ apply_pnm" 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) { $? ". file was read successfully" (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) { $? ". output file opened successfully" if(create_the_streams(ia)) { if(dkof_start_chunk(ia->s2)) { $? ". streams ok" 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)) ) { $? ". colored output" (ia->ii)->colored = 1; if((((ia->oi)->c)->opt1) & DKFIG_OPT_SEPARATED_RGB) { $? ". separated data sources" 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 { $? ". combined data source" 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 { $? ". gray output" if(PPM_TYPE == PNM_FORMAT_TYPE(format)) { $? ". color to gray" 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 { $? ". original gray" 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)) { $? ". color -> gray" 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 { $? ". gray to gray" 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) { $? "! While writing output data" dkfig_tool2_eps_error_message(ia->oi, 75); } if(!dkof_end_chunk(ia->s2)) { back = 0; $? "! While finishing output chunk" dkfig_tool2_eps_error_message(ia->oi, 74); } } else { $? "! Failed to start encoded chunk" dkfig_tool2_eps_error_message(ia->oi, 73); } } else { $? "! Problem while creating output streams" dkfig_tool2_eps_error_message(ia->oi, 72); } destroy_the_streams(ia); fclose(ia->outf); ia->outf = NULL; } else { $? "! Failed to open output file" 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 { $? "! Failed to open image file" if(((ia->oi)->c)->app) { dkapp_err_fopenr(((ia->oi)->c)->app, ia->fn); } } $? "- apply_pnm %d", back 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; $? "+ apply_input" switch(ia->ft) { case 0: { $? ". apply_eps" back = apply_eps(ia); } break; case 1: { #if DK_HAVE_ZLIB_H #if DK_HAVE_PNG_H $? ". apply_png" back = apply_png(ia); #else dkfig_tool2_eps_error_message(ia->oi, 70); #endif #else dkfig_tool2_eps_error_message(ia->oi, 70); $? "! Compiled without zlib library" #endif } break; case 2: { #if DK_HAVE_JPEGLIB_H $? ". apply_jpg" back = apply_jpg(ia); #else $? "! Compiled without JPEG library" dkfig_tool2_eps_error_message(ia->oi, 69); #endif } break; case 3: { #if DK_HAVE_PNM_H || DK_HAVE_NETPBM_PNM_H $? ". apply_pnm" back = apply_pnm(ia); #else $? "! Compiled without NetPBM library" dkfig_tool2_eps_error_message(ia->oi, 68); #endif } break; default: { dkfig_tool2_eps_error_message(ia->oi, 66); } break; } $? "- apply_input %d", back 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; $? "+ create_eps_image_info" sz = (size_t)dksf_get_maxpathlen(); $? ". sz (1) = %lu", (unsigned long)sz sz = ((sz < 128) ? 128 : ((sz > 4096) ? 4096 : sz)); $? ". sz (2) = %lu", (unsigned long)sz filename = dk_new(char,sz); if(filename) { $? ". filename ok" if((ia->oi)->c) { $? ". ->c ok" if(((ia->oi)->c)->app) { $? ". ->c->app ok" if(dkapp_tmpnam(((ia->oi)->c)->app, filename, sz)) { $? ". temorary name ok" ia->ii = back = dkfig_eps_image_info_new(filename); if(back) { back->type = ia->ft; $? ". ia->fl = %d", ia->fl $? ". ia->ii->fl = %d", ia->ii->fl back->fl = ia->fl; if(!apply_input(ia)) { $? "! apply_input failed" 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 { $? "! failed to create temporary file name" dkfig_tool2_eps_error_message(ia->oi, 67); } } } dk_delete(filename); filename = NULL; } else { $? "! no file name" $? "! Memory" if(((ia->oi)->c)->app) { dkapp_err_memory( ((ia->oi)->c)->app, 1, sz); } } $? "- create_eps_image_info %s", TR_PTR(back) 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; $? "+ dkfig_eps_attach_image_info" null_iai(&ia); if(oi && o) { ia.oi = oi; ia.o = o; p = (dk_fig_polyline *)(o->data); if(p) { $? ". polyline ok" if(p->imagename) { $? ". image name ok" 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) { $? ". driver extension created" back = 1; } else { $? "! no driver extension" } } else { $? "! unknown suffix" $? "! Unknown file type suffix" dkfig_tool2_eps_error_message(oi, 66); } } else { $? "! internal setup error" } } else { $? "! internal setup error" } } $? "- dkfig_eps_attach_image_info %d", back return back; }