/* Copyright (c) 2000-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 dkbif.c Bitmap image file API module. */ /** Inside the dkbif module. */ #define DKBIF_C 1 #include "dkbifi.h" #include "dkbif.h" #include "dkstr.h" #line 56 "dkbif.ctr" /** Version text and used libraries. */ char *dkbif_version_text[] = { #if DK_HAVE_PNG_H "libpng The official PNG reference library", " http://www.libpng.org/pub/png/libpng.html", #endif #if DK_HAVE_JPEGLIB_H "jpegsrc The Independent JPEG Group's free JPEG software", " http://www.ijg.org/", #endif #if DK_HAVE_PNM_H || DK_HAVE_NETPBM_PNM_H "netpbm The image conversion toolkit", " http://netpbm.sourceforge.net/", #endif #if DK_HAVE_TIFF_H "libtiff The TIFF library.", " http://www.remotesensing.org/libtiff/", #endif NULL }; char **dkbif_lic_get DK_P0() { return dkbif_version_text; } /** Flag: File names case-insensitive. */ static int fncaseins = #if DK_HAVE_FNCASEINS 1 #else 0 #endif ; /** Connect file name suffix to image type. */ typedef struct { char *s; /**< File name suffix. */ int t; /**< Image type. */ } image_type; /** Suffix for PNG files. */ static char str_png[] = { "png" }; /** Suffix for JPEG files. */ static char str_jpg[] = { "jpg" }; /** Suffix for JPEG files. */ static char str_jpeg[] = { "jpeg" }; /** Suffix for NetPBM files. */ static char str_pbm[] = { "pbm" }; /** Suffix for NetPBM files. */ static char str_ppm[] = { "ppm" }; /** Suffix for NetPBM files. */ static char str_pgm[] = { "pgm" }; /** Suffix for NetPBM files. */ static char str_pnm[] = { "pnm" }; /** Suffix for TIFF files. */ static char str_tif[] = { "tif" }; /** Suffix for TIFF files. */ static char str_tiff[] = { "tiff" }; /** Bits for mask operations. */ static unsigned short bits[] = { 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080, 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000 }; /** Image type table. */ static image_type image_types[] = { { str_png, DKBIF_TYPE_PNG }, { str_jpg, DKBIF_TYPE_JPG }, { str_jpeg, DKBIF_TYPE_JPG }, { str_pbm, DKBIF_TYPE_NETPBM }, { str_ppm, DKBIF_TYPE_NETPBM }, { str_pgm, DKBIF_TYPE_NETPBM }, { str_pnm, DKBIF_TYPE_NETPBM }, { str_tif, DKBIF_TYPE_TIFF }, { str_tiff, DKBIF_TYPE_TIFF }, { NULL, DKBIF_TYPE_UNKNOWN } }; /** Get background red value. @param p Image. @return The background red value. */ static double getbgr DK_P1(dk_bif_t *,p) { double back = 1.0; if(p->cf) { back = (p->cf)->mr; if((back < 0.0) || (p->m == 2)) { back = p->mr; } } return back; } /** Get background green value. @param p Image. @return The background green value. */ static double getbgg DK_P1(dk_bif_t *,p) { double back = 1.0; if(p->cf) { back = (p->cf)->mg; if((back < 0.0) || (p->m == 2)) { back = p->mg; } } return back; } /** Get background blue value. @param p Image. @return The background blue value. */ static double getbgb DK_P1(dk_bif_t *,p) { double back = 1.0; if(p->cf) { back = (p->cf)->mb; if((back < 0.0) || (p->m == 2)) { back = p->mb; } } return back; } unsigned short dkbif_max_for_bpc DK_P1(unsigned short,b) { unsigned short back = 0; unsigned short i; for(i = 1; i <= b; i++) { back |= bits[i-1]; } return back; } /** Get alpha value. @param p Image. @param x X position. @param y Y position. @return The alpha value. */ static unsigned short get_alpha DK_P3(dk_bif_t *,p, unsigned long,x, unsigned long,y) { unsigned short back = 0; /* ----- additional file types require modifications here ----- */ switch(p->t) { case DKBIF_TYPE_PNG: { #if DK_HAVE_ZLIB_H && DK_HAVE_PNG_H back = dkbifpng_alpha(p, x, y); #else #endif } break; case DKBIF_TYPE_JPG: { #if DK_HAVE_JPEGLIB_H back = dkbifjpg_alpha(p, x, y); #else #endif } break; case DKBIF_TYPE_NETPBM: { #if DK_HAVE_PNM_H || DK_HAVE_NETPBM_PNM_H back = dkbifpbm_alpha(p, x, y); #else #endif } break; case DKBIF_TYPE_TIFF: { #if DK_HAVE_TIFF_H back = dkbiftif_alpha(p, x, y); #else #endif } break; } return back; } /** Get red value. @param p Image. @param x X position. @param y Y position. @return The red value. */ static unsigned short get_red DK_P3(dk_bif_t *,p, unsigned long,x, unsigned long,y) { unsigned short back = 0; int ec = 0; double value, avalue; /* ----- additional file types require modifications here ----- */ switch(p->t) { case DKBIF_TYPE_PNG: { #if DK_HAVE_ZLIB_H && DK_HAVE_PNG_H back = dkbifpng_red(p, x, y); #else #endif } break; case DKBIF_TYPE_JPG: { #if DK_HAVE_JPEGLIB_H back = dkbifjpg_red(p, x, y); #else #endif } break; case DKBIF_TYPE_NETPBM: { #if DK_HAVE_PNM_H || DK_HAVE_NETPBM_PNM_H back = dkbifpbm_red(p, x, y); #else #endif } break; case DKBIF_TYPE_TIFF: { #if DK_HAVE_TIFF_H back = dkbiftif_red(p, x, y); #else #endif } break; } switch((p->cf)->ch) { case 4: case 2: { if(p->m) { value = dkma_ul_to_double((unsigned long)back); avalue = dkma_ul_to_double(get_alpha(p,x,y)); value = dkma_div_double_ok(value, (p->cf)->vmax, &ec); avalue = dkma_div_double_ok(avalue, (p->cf)->vmax, &ec); /* value = value * avalue + (1.0 - avalue) * p->mr; */ value = dkma_add_double_ok( dkma_mul_double_ok(value, avalue, &ec), dkma_mul_double_ok( dkma_sub_double_ok(1.0, avalue, &ec), getbgr(p), &ec ), &ec ); value = dkma_mul_double_ok(value, (p->cf)->vmax, &ec); value = dkma_rint(value); back = (unsigned short)dkma_double_to_ul_ok(value, &ec); if(ec) { p->ec = DK_ERR_MATH_OOR; } } } break; } return back; } /** Get green value. @param p Image. @param x X position. @param y Y position. @return The green value. */ static unsigned short get_green DK_P3(dk_bif_t *,p, unsigned long,x, unsigned long,y) { unsigned short back = 0; int ec = 0; double value, avalue; /* ----- additional file types require modifications here ----- */ switch(p->t) { case DKBIF_TYPE_PNG: { #if DK_HAVE_ZLIB_H && DK_HAVE_PNG_H back = dkbifpng_green(p, x, y); #else #endif } break; case DKBIF_TYPE_JPG: { #if DK_HAVE_JPEGLIB_H back = dkbifjpg_green(p, x, y); #else #endif } break; case DKBIF_TYPE_NETPBM: { #if DK_HAVE_PNM_H || DK_HAVE_NETPBM_PNM_H back = dkbifpbm_green(p, x, y); #else #endif } break; case DKBIF_TYPE_TIFF: { #if DK_HAVE_TIFF_H back = dkbiftif_green(p, x, y); #else #endif } break; } switch((p->cf)->ch) { case 4: case 2: { if(p->m) { value = dkma_ul_to_double((unsigned long)back); avalue = dkma_ul_to_double(get_alpha(p,x,y)); value = dkma_div_double_ok(value, (p->cf)->vmax, &ec); avalue = dkma_div_double_ok(avalue, (p->cf)->vmax, &ec); /* value = value * avalue + (1.0 - avalue) * p->mg; */ value = dkma_add_double_ok( dkma_mul_double_ok(value, avalue, &ec), dkma_mul_double_ok( dkma_sub_double_ok(1.0, avalue, &ec), getbgg(p), &ec ), &ec ); value = dkma_mul_double_ok(value, (p->cf)->vmax, &ec); value = dkma_rint(value); back = (unsigned short)dkma_double_to_ul_ok(value, &ec); if(ec) { p->ec = DK_ERR_MATH_OOR; } } } break; } return back; } /** Get blue value. @param p Image. @param x X position. @param y Y position. @return The blue value. */ static unsigned short get_blue DK_P3(dk_bif_t *,p, unsigned long,x, unsigned long,y) { unsigned short back = 0; int ec = 0; double value, avalue; /* ----- additional file types require modifications here ----- */ switch(p->t) { case DKBIF_TYPE_PNG: { #if DK_HAVE_ZLIB_H && DK_HAVE_PNG_H back = dkbifpng_blue(p, x, y); #else #endif } break; case DKBIF_TYPE_JPG: { #if DK_HAVE_JPEGLIB_H back = dkbifjpg_blue(p, x, y); #else #endif } break; case DKBIF_TYPE_NETPBM: { #if DK_HAVE_PNM_H || DK_HAVE_NETPBM_PNM_H back = dkbifpbm_blue(p, x, y); #else #endif } break; case DKBIF_TYPE_TIFF: { #if DK_HAVE_TIFF_H back = dkbiftif_blue(p, x, y); #else #endif } break; } switch((p->cf)->ch) { case 4: case 2: { if(p->m) { value = dkma_ul_to_double((unsigned long)back); avalue = dkma_ul_to_double(get_alpha(p,x,y)); value = dkma_div_double_ok(value, (p->cf)->vmax, &ec); avalue = dkma_div_double_ok(avalue, (p->cf)->vmax, &ec); /* value = value * avalue + (1.0 - avalue) * p->mb; */ value = dkma_add_double_ok( dkma_mul_double_ok(value, avalue, &ec), dkma_mul_double_ok( dkma_sub_double_ok(1.0, avalue, &ec), getbgb(p), &ec ), &ec ); value = dkma_mul_double_ok(value, (p->cf)->vmax, &ec); value = dkma_rint(value); back = (unsigned short)dkma_double_to_ul_ok(value, &ec); if(ec) { p->ec = DK_ERR_MATH_OOR; } } } break; } return back; } /** Get gray value. @param p Image. @param x X position. @param y Y position. @return The gray value. */ static unsigned short get_gray DK_P3(dk_bif_t *,p, unsigned long,x, unsigned long,y) { unsigned short back = 0; int ec = 0; double value, avalue, bgg; /* ----- additional file types require modifications here ----- */ switch(p->t) { case DKBIF_TYPE_PNG: { #if DK_HAVE_ZLIB_H && DK_HAVE_PNG_H back = dkbifpng_gray(p, x, y); #else #endif } break; case DKBIF_TYPE_JPG: { #if DK_HAVE_JPEGLIB_H back = dkbifjpg_gray(p, x, y); #else #endif } break; case DKBIF_TYPE_NETPBM: { #if DK_HAVE_PNM_H || DK_HAVE_NETPBM_PNM_H back = dkbifpbm_gray(p, x, y); #else #endif } break; case DKBIF_TYPE_TIFF: { #if DK_HAVE_TIFF_H back = dkbiftif_gray(p, x, y); #else #endif } break; } switch((p->cf)->ch) { case 2: { if(p->m) { value = dkma_ul_to_double((unsigned long)back); avalue = dkma_ul_to_double(get_alpha(p,x,y)); value = dkma_div_double_ok(value, (p->cf)->vmax, &ec); avalue = dkma_div_double_ok(avalue, (p->cf)->vmax, &ec); bgg = 0.3 * getbgr(p) + 0.59 * getbgg(p) + 0.11 * getbgb(p); /* value = value * avalue + (1.0 - avalue) * bgg; */ value = dkma_add_double_ok( dkma_mul_double_ok(value, avalue, &ec), dkma_mul_double_ok(dkma_sub_double_ok(1.0, avalue, &ec), bgg, &ec), &ec ); value = dkma_mul_double_ok(value, (p->cf)->vmax, &ec); value = dkma_rint(value); back = (unsigned short)dkma_double_to_ul_ok(value, &ec); if(ec) { p->ec = DK_ERR_MATH_OOR; } } } break; } return back; } /** Correct unsigned short value. @param omax Factor (output maximum). @param imax Divisor (input maximum). @param v Value to correct. @param ec Pointer to error code variable. @return Corrected value. */ static unsigned short correct_unsigned_short DK_P4(\ double,omax, double,imax, unsigned short,v, int *,ec) { unsigned short back = 0; back = (unsigned short)dkma_double_to_ul_ok( dkma_rint( dkma_mul_double_ok( dkma_div_double_ok( dkma_ul_to_double((unsigned long)v), imax, ec ), omax, ec ) ), ec ); return back; } int dkbif_get_type DK_P1(char *,infname) { char *s = NULL; image_type *ptr; int back = DKBIF_TYPE_UNKNOWN; if(infname) { s = dksf_get_file_type_dot(infname); if(s) { s++; } else { s = infname; } } if(s) { ptr = image_types; while((back == DKBIF_TYPE_UNKNOWN) && (ptr->s)) { if(fncaseins) { if(dkstr_casecmp(ptr->s, s)) { ptr++; } else { back = ptr->t; } } else { if(strcmp(ptr->s, s)) { ptr++; } else { back = ptr->t; } } } } return back; } /** Release frame. @param b Image. @param f Frame to release. */ static void frame_release DK_P2(dk_bif_t *,b, dk_bif_frame_t *,f) { if(f) { /* ----- additional file types require modifications here ----- */ switch(b->t) { case DKBIF_TYPE_PNG: { #if DK_HAVE_ZLIB_H && DK_HAVE_PNG_H dkbifpng_frame_release(b, f); #else #endif } break; case DKBIF_TYPE_JPG: { #if DK_HAVE_JPEGLIB_H dkbifjpg_frame_release(b, f); #else #endif } break; case DKBIF_TYPE_NETPBM: { #if DK_HAVE_PNM_H || DK_HAVE_NETPBM_PNM_H dkbifpbm_frame_release(b, f); #else #endif } break; case DKBIF_TYPE_TIFF: { #if DK_HAVE_TIFF_H dkbiftif_frame_release(b, f); #else #endif } break; } } } /* Create empty frame dataset. */ dk_bif_frame_t * dkbif_frame_new DK_P2(dk_bif_t *,b, unsigned long,n) { dk_bif_frame_t *back = NULL; back = dk_new(dk_bif_frame_t,1); if(back) { back->n = n; if(dksto_add(b->f, (void *)back)) { back->w = 0UL; back->h = 0UL; back->bpc = 0; back->ch = 0; back->xdpi = -1.0; back->ydpi = -1.0; back->vmax = 1.0; back->mr = back->mg = back->mb = -1.0; } else { frame_release(b, back); back = NULL; } } if(!(back)) { b->ec = DK_ERR_NOMEM; } return back; } /** Compare two frames. @param l Left frame. @param r Right frame. @param cr Comparison criteria (0=frame/frame, 1=frame/number). @return Comparison result. */ static int frame_compare DK_P3(void *,l, void *,r, int,cr) { int back = 0; dk_bif_frame_t *pl, *pr; pl = (dk_bif_frame_t *)l; pr = (dk_bif_frame_t *)r; if(l) { if(r) { switch(cr) { case 1: { if(pl->n > (*((unsigned long *)r))) { back = 1; } else { if(pl->n < (*((unsigned long *)r))) { back = -1; } } } break; default: { if(pl->n > pr->n) { back = 1; } else { if(pl->n < pr->n) { back = -1; } } } break; } } else { back = 1; } } else { if(r) { back = -1; } } return back; } void dkbif_close DK_P1(dk_bif_ptr,p) { dk_bif_t *ptr; dk_bif_frame_t *fptr; ptr = (dk_bif_t *)p; if(ptr) { if(ptr->f) { if(ptr->fi) { dksto_it_reset(ptr->fi); while((fptr = (dk_bif_frame_t *)dksto_it_next(ptr->fi)) != NULL) { frame_release(ptr, fptr); } dksto_it_close(ptr->fi); ptr->fi = NULL; } dksto_close(ptr->f); ptr->f = NULL; } /* ----- additional file types require modifications here ----- */ switch(ptr->t) { case DKBIF_TYPE_PNG: { #if DK_HAVE_ZLIB_H && DK_HAVE_PNG_H dkbifpng_release(ptr); #else #endif } break; case DKBIF_TYPE_JPG: { #if DK_HAVE_JPEGLIB_H dkbifjpg_release(ptr); #else #endif } break; case DKBIF_TYPE_NETPBM: { #if DK_HAVE_PNM_H || DK_HAVE_NETPBM_PNM_H dkbifpbm_release(ptr); #else #endif } break; case DKBIF_TYPE_TIFF: { #if DK_HAVE_TIFF_H dkbiftif_release(ptr); #else #endif } break; } dk_delete(ptr); } } dk_bif_ptr dkbif_open DK_P0() { int ok = 0; dk_bif_t *back = NULL; back = dk_new(dk_bif_t,1); if(back) { back->nof = 0UL; back->f = NULL; back->fi = NULL; back->ec = 0; back->t = DKBIF_TYPE_UNKNOWN; back->w_all = 0UL; back->h_all = 0UL; back->cf = NULL; back->vmax = 1.0; back->obpc = 0; back->mtl = 0.000001; back->mr = 1.0; back->mg = 1.0; back->mb = 1.0; back->tmpfilename = NULL; back->whs = 0x00; back->f = dksto_open(0); if(back->f) { dksto_set_comp(back->f, frame_compare, 0); back->fi = dksto_it_open(back->f); if(back->fi) { ok = 1; } } if(!ok) { dkbif_close(back); back = NULL; } } return ((dk_bif_ptr)back); } /* Read header information from file. tp ... DKBIF_TYPE... fn ... file name, used if tp==DKBIF_TYPE_UNKNOWN */ int dkbif_read_header DK_P5(dk_bif_ptr,p, FILE *,f, char *,fn, int,tp, char *,tmpfilename) { int back = 0; dk_bif_t *ptr = NULL; char *sptr; if((p) && (f)) { ptr = (dk_bif_t *)p; ptr->tmpfilename = tmpfilename; /* ----- additional file types require modifications here ----- */ ptr->t = tp; if(ptr->t == DKBIF_TYPE_UNKNOWN) { if(fn) { sptr = dksf_get_file_type_dot(fn); if(sptr) { sptr++; } else { sptr = fn; } ptr->t = dkbif_get_type(sptr); } } switch(ptr->t) { case DKBIF_TYPE_PNG: { #if DK_HAVE_ZLIB_H && DK_HAVE_PNG_H back = dkbifpng_header(p, f); #else #endif } break; case DKBIF_TYPE_JPG: { #if DK_HAVE_JPEGLIB_H back = dkbifjpg_header(p, f); #else #endif } break; case DKBIF_TYPE_NETPBM: { #if DK_HAVE_PNM_H || DK_HAVE_NETPBM_PNM_H back = dkbifpbm_header(p, f); #else #endif } break; case DKBIF_TYPE_TIFF: { #if DK_HAVE_TIFF_H back = dkbiftif_header(p, f); #else #endif } break; default: { ptr->ec = DK_ERR_SYNTAX; } break; } } return back; } int dkbif_read_data DK_P2(dk_bif_ptr,p, FILE *,f) { int back = 0; dk_bif_t *ptr = NULL; dk_bif_frame_t *fptr; if((p) && (f)) { ptr = (dk_bif_t *)p; /* ----- additional file types require modifications here ----- */ switch(ptr->t) { case DKBIF_TYPE_PNG: { #if DK_HAVE_ZLIB_H && DK_HAVE_PNG_H back = dkbifpng_data(p, f); #else #endif } break; case DKBIF_TYPE_JPG: { #if DK_HAVE_JPEGLIB_H back = dkbifjpg_data(p, f); #else #endif } break; case DKBIF_TYPE_NETPBM: { #if DK_HAVE_PNM_H || DK_HAVE_NETPBM_PNM_H back = dkbifpbm_data(p, f); #else #endif } break; case DKBIF_TYPE_TIFF: { #if DK_HAVE_TIFF_H back = dkbiftif_data(p, f); #else #endif } break; } /* calculate vmax values */ dksto_it_reset(ptr->fi); while((fptr = dksto_it_next(ptr->fi)) != NULL) { fptr->vmax = dkma_ul_to_double((unsigned long)dkbif_max_for_bpc(fptr->bpc)); } } else { } return back; } /* Return number of frames in file. */ unsigned long dkbif_number_of_frames DK_P1(dk_bif_ptr,p) { unsigned long back = 0UL; dk_bif_t *ptr = NULL; ptr =(dk_bif_t *)p; if(ptr) { back = ptr->nof; } return back; } /* Select a frame. */ int dkbif_set_frame DK_P2(dk_bif_ptr,ptr, unsigned long,fno) { int back = 0; unsigned long ul; dk_bif_t *p = NULL; if(ptr) { p = (dk_bif_t *)ptr; ul = fno; if((p->f) && (p->fi)) { p->cf = dksto_it_find_like(p->fi, (void *)(&ul), 1); if(p->cf) { back = 1; } } if(!back) { p->ec = DK_ERR_NO_SUCH_OBJECT; } } return back; } /* Return number of channels 1 = gray 2 = gray + alpha 3 = RGB 4 = RGB + alpha */ int dkbif_get_channels DK_P1(dk_bif_ptr,ptr) { int back = 0; dk_bif_t *p = NULL; if(ptr) { p = (dk_bif_t *)ptr; if(p->cf) { back = (p->cf)->ch; } } return back; } /* Return number of bits per component. */ unsigned short dkbif_get_bits_per_component DK_P1(dk_bif_ptr,ptr) { unsigned short back = 0; dk_bif_t *p = NULL; if(ptr) { p = (dk_bif_t *)ptr; if(p->cf) { back = (p->cf)->bpc; } } return back; } /* Set bits per component for output operations. */ int dkbif_set_bits_per_component DK_P2(dk_bif_ptr,ptr, unsigned short,bpc) { int back = 0; dk_bif_t *p = NULL; if(ptr) { p = (dk_bif_t *)ptr; p->obpc = bpc; p->vmax = dkma_ul_to_double((unsigned long)dkbif_max_for_bpc(p->obpc)); } return back; } /* Allow/deny mixing of pixels against background f = 0 ... no mixing f = 1 ... mixing against background color from bg chunk f = 2 ... mixing, always use background as specified */ int dkbif_set_mixing DK_P5(dk_bif_ptr,ptr,int,f,double,r,double,g,double,b) { int back = 0; dk_bif_t *p = NULL; if(ptr) { p = (dk_bif_t *)ptr; p->m = f; p->mr = r; p->mg = g; p->mb = b; back = 0; } return back; } /* Set trigger level for conversion of alpha channel to image masks. */ int dkbif_set_mask_trigger_level DK_P2(dk_bif_ptr,ptr, double,tl) { int back = 0; dk_bif_t *p = NULL; if(ptr) { p = (dk_bif_t *)ptr; p->mtl = tl; back = 1; } return back; } unsigned short dkbif_get_red DK_P3(dk_bif_ptr,ptr, unsigned long,x, unsigned long,y) { unsigned short back = 0; dk_bif_t *p = NULL; int ec = 0; if(ptr) { p = (dk_bif_t *)ptr; if(p->cf) { if((x < (p->cf)->w) && (y < (p->cf)->h)) { switch((p->cf)->ch) { case 1: case 2: { back = get_gray(p, x, y); } break; default: { back = get_red(p, x, y); } break; } if(p->obpc) { if(p->obpc != (p->cf)->bpc) { back = correct_unsigned_short(p->vmax, (p->cf)->vmax, back, &ec); if(ec) { p->ec = DK_ERR_MATH_OOR; } } } } } } return back; } unsigned short dkbif_get_green DK_P3(dk_bif_ptr,ptr, unsigned long,x, unsigned long,y) { unsigned short back = 0; dk_bif_t *p = NULL; int ec = 0; if(ptr) { p = (dk_bif_t *)ptr; if(p->cf) { if((x < (p->cf)->w) && (y < (p->cf)->h)) { switch((p->cf)->ch) { case 1: case 2: { back = get_gray(p, x, y); } break; default: { back = get_green(p, x, y); } break; } if(p->obpc) { if(p->obpc != (p->cf)->bpc) { back = correct_unsigned_short(p->vmax, (p->cf)->vmax, back, &ec); if(ec) { p->ec = DK_ERR_MATH_OOR; } } } } } } return back; } unsigned short dkbif_get_blue DK_P3(dk_bif_ptr,ptr, unsigned long,x, unsigned long,y) { unsigned short back = 0; dk_bif_t *p = NULL; int ec = 0; if(ptr) { p = (dk_bif_t *)ptr; if(p->cf) { if((x < (p->cf)->w) && (y < (p->cf)->h)) { switch((p->cf)->ch) { case 1: case 2: { back = get_gray(p, x, y); } break; default: { back = get_blue(p, x, y); } break; } if(p->obpc) { if(p->obpc != (p->cf)->bpc) { back = correct_unsigned_short(p->vmax, (p->cf)->vmax, back, &ec); if(ec) { p->ec = DK_ERR_MATH_OOR; } } } } } } return back; } unsigned short dkbif_get_gray DK_P3(dk_bif_ptr,ptr, unsigned long,x, unsigned long,y) { unsigned short back = 0, r = 0, g = 0, b = 0; dk_bif_t *p = NULL; int ec = 0; if(ptr) { p = (dk_bif_t *)ptr; if(p->cf) { if((x < (p->cf)->w) && (y < (p->cf)->h)) { switch((p->cf)->ch) { case 1: case 2: { back = get_gray(p, x, y); } break; default: { r = get_red(p, x, y); g = get_green(p, x, y); b = get_blue(p, x, y); if(p->fntsc) { back = (unsigned short)( ( dkma_add_ulong_ok( dkma_add_ulong_ok( dkma_mul_ulong_ok(54UL,(unsigned long)r,&ec), dkma_mul_ulong_ok(183UL,(unsigned long)g,&ec), &ec ), dkma_mul_ulong_ok(19UL,(unsigned long)b,&ec), &ec ) >> 8 ) & 0xFFFF ); } else { back = (unsigned short)dkma_double_to_ul_ok( dkma_rint( dkma_add_double_ok( dkma_add_double_ok( dkma_mul_double_ok( 0.3,dkma_ul_to_double((unsigned long)r),&ec ), dkma_mul_double_ok( 0.59,dkma_ul_to_double((unsigned long)g),&ec ), &ec ), dkma_mul_double_ok( 0.11,dkma_ul_to_double((unsigned long)g),&ec ), &ec ) ), &ec ); } if(ec) { p->ec = DK_ERR_MATH_OOR; } } break; } if(p->obpc) { if(p->obpc != (p->cf)->bpc) { back = correct_unsigned_short(p->vmax, (p->cf)->vmax, back, &ec); if(ec) { p->ec = DK_ERR_MATH_OOR; } } } } } } return back; } unsigned short dkbif_get_alpha DK_P3(dk_bif_ptr,ptr, unsigned long,x, unsigned long,y) { unsigned short back = 0; dk_bif_t *p = NULL; int ec = 0; if(ptr) { p = (dk_bif_t *)ptr; if(p->cf) { if((x < (p->cf)->w) && (y < (p->cf)->h)) { back = get_alpha(p, x, y); if(p->obpc) { if(p->obpc != (p->cf)->bpc) { back = correct_unsigned_short(p->vmax, (p->cf)->vmax, back, &ec); if(ec) { p->ec = DK_ERR_MATH_OOR; } } } } } } return back; } unsigned short dkbif_get_mask DK_P3(dk_bif_ptr,ptr, unsigned long,x, unsigned long,y) { int back = 1; dk_bif_t *p = NULL; int ec = 0; double v; if(ptr) { p = (dk_bif_t *)ptr; if(p->cf) { if((x < (p->cf)->w) && (y < (p->cf)->h)) { switch((p->cf)->ch) { case 2: case 4: { v = dkma_div_double_ok( dkma_ul_to_double((unsigned long)get_alpha(p,x,y)), (p->cf)->vmax, &ec ); if(v > p->mtl) { back = 0; } else { back = (p->cf)->vmask; } } break; } } } if(ec) { p->ec = DK_ERR_MATH_OOR; } } return back; } void dkbif_allow_fast_ntsc DK_P2(dk_bif_ptr,ptr, int,f) { dk_bif_t *p; p = (dk_bif_t *)ptr; if(p) { p->fntsc = (f ? 0x01 : 0x00); } } unsigned long dkbif_get_width DK_P1(dk_bif_ptr,ptr) { unsigned long back = 0UL; dk_bif_t *p; p = (dk_bif_t *)ptr; if(p) { if(p->cf) { back = (p->cf)->w; } } return back; } unsigned long dkbif_get_height DK_P1(dk_bif_ptr,ptr) { unsigned long back = 0UL; dk_bif_t *p; p = (dk_bif_t *)ptr; if(p) { if(p->cf) { back = (p->cf)->h; } } return back; } double dkbif_get_real_width DK_P1(dk_bif_ptr,ptr) { double back = 0.0; unsigned long ul; dk_bif_t *p; int ec = 0; p = (dk_bif_t *)ptr; if(p) { if(p->cf) { ul = (p->cf)->w; back = dkma_ul_to_double(ul); if((p->cf)->xdpi > 0.0) { back = dkma_mul_double_ok( dkma_div_double_ok(back, (p->cf)->xdpi, &ec), 72.0, &ec ); if(ec) { p->ec = DK_ERR_MATH_OOR; } } } } return back; } double dkbif_get_real_height DK_P1(dk_bif_ptr,ptr) { double back = 0.0; unsigned long ul; dk_bif_t *p; int ec = 0; p = (dk_bif_t *)ptr; if(p) { if(p->cf) { ul = (p->cf)->h; back = dkma_ul_to_double(ul); if((p->cf)->ydpi > 0.0) { back = dkma_mul_double_ok( dkma_div_double_ok(back, (p->cf)->ydpi, &ec), 72.0, &ec ); if(ec) { p->ec = DK_ERR_MATH_OOR; } } } } return back; } int dkbif_get_must_scale DK_P1(dk_bif_ptr,ptr) { int back = 0; dk_bif_t *p; p = (dk_bif_t *)ptr; if(p) { if(p->cf) { if((p->cf)->ydpi > 0.0) { back = 1; } if((p->cf)->xdpi > 0.0) { back = 1; } } } return back; } double dkbif_get_sf_x DK_P1(dk_bif_ptr,ptr) { double back = -1.0; int me = 0; dk_bif_t *p; p = (dk_bif_t *)ptr; if(p) { if(p->cf) { if((p->cf)->xdpi > 0.0) { back = dkma_div_double_ok(72.0, (p->cf)->xdpi, &me); } } } return back; } double dkbif_get_sf_y DK_P1(dk_bif_ptr,ptr) { double back = -1.0; int me = 0; dk_bif_t *p; p = (dk_bif_t *)ptr; if(p) { if(p->cf) { if((p->cf)->ydpi > 0.0) { back = dkma_div_double_ok(72.0, (p->cf)->ydpi, &me); } } } return back; } void dkbif_set_width_height_sufficient DK_P2(dk_bif_ptr,ptr, int,flagvalue) { dk_bif_t *p; if(ptr) { p = (dk_bif_t *)ptr; p->whs = (flagvalue ? 0x01 : 0x00); } } int dkbif_can_handle DK_P1(int,t) { int back = 0; switch(t) { case DKBIF_TYPE_PNG: { #if DK_HAVE_PNG_H back = 1; #endif } break; case DKBIF_TYPE_JPG: { #if DK_HAVE_JPEGLIB_H back = 1; #endif } break; case DKBIF_TYPE_NETPBM: { #if DK_HAVE_PNM_H || DK_HAVE_NETPBM_PNM_H back = 1; #endif } break; case DKBIF_TYPE_TIFF: { #if DK_HAVE_TIFF_H back = 1; #endif } break; } return back; } int dkbif_can_handle_name DK_P1(char *,filename) { int back = 0; int t = -1; t = dkbif_get_type(filename); back = dkbif_can_handle(t); return back; } int dkbif_get_predictor DK_P1(dk_bif_ptr,p) { int back = DKBIF_PREDICTOR_NONE; dk_bif_t *ptr; ptr = (dk_bif_t *)p; if(ptr) { switch(ptr->t) { case DKBIF_TYPE_PNG: { #if DK_HAVE_PNG_H int ft = 0; ft = png_get_filter_type((ptr->d).png.pp, (ptr->d).png.pi); #endif } break; case DKBIF_TYPE_TIFF: { #if DK_HAVE_TIFF_H uint16 res; if(TIFFGetField((ptr->d).tif.tiff, TIFFTAG_PREDICTOR, &res) == 1) { if(res == PREDICTOR_HORIZONTAL) { back = DKBIF_PREDICTOR_PIXEL_SUB; } } #endif } break; } } return back; }