/* WARNING: This file was generated by dkct. Changes you make here will be lost if dkct is run again! You should modify the original source and run dkct on it. Original source: dk3bif.ctr */ /* Copyright (C) 2011-2017, Dirk Krause 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 author 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 dk3bif.c The dk3bif module. */ #line 393 "dk3bif.ctr" #include "dk3conf.h" #include #if DK3_HAVE_PNG_H #include #else #if DK3_HAVE_SETJMP_H #include #endif #endif #if DK3_HAVE_SYS_TYPES_H #include #endif #if DK3_HAVE_STDLIB_H #include #endif #if DK3_HAVE_UNISTD_H #include #endif #if DK3_HAVE_PROCESS_H #include #endif #if DK3_HAVE_JPEGLIB_H #include #endif #if DK3_HAVE_TIFF_H #include #include #endif #if DK3_HAVE_STRING_H #include #endif #if DK3_HAVE_STRINGS_H #include #endif #if 0 #include "dk3all.h" #endif #include "dk3const.h" #include "dk3mem.h" #include "dk3str.h" #include "dk3sf.h" #include "dk3sto.h" #include "dk3bif.h" #include "dk3bifa.h" #include "dk3pixre.h" #include "dk3ma.h" #include "dk3numco.h" #include "dk3bits.h" #include "dk3app.h" #line 453 "dk3bif.ctr" #line 456 "dk3bif.ctr" /** File suffixes for images. */ static dkChar const * const dk3bif_dk_type_names[] = { dkT("png"), dkT("jpeg"), dkT("jpg"), dkT("tiff"), dkT("tif"), NULL #line 468 "dk3bif.ctr" }; /** File suffixes for images. Note: Order must correpsond to the order of dk3bif_dk_type_names. */ static char const * const dk3bif_c8_type_names[] = { "png", "jpeg", "jpg", "tiff", "tif", NULL #line 483 "dk3bif.ctr" }; /** Keywords used by the module (dkChar). */ static dkChar const * const dk3bif_kw_dk[] = { /* 0 */ dkT("rb"), NULL }; /** Keywords and texts used by the module (8-bit). */ static char const * const dk3bif_kw_c8[] = { /* 0 */ "dk3bif-%lu-%lu.tmp", /* PID, index */ /* 1 */ "dk3bif-%d-%lu.tmp", /* PID, index */ NULL }; /** Number of current temporary file within this process. */ static unsigned long dk3bif_temp_number = 0UL; static dk3_bif_frame_t * dk3bif_frame_new(dk3_bif_t *bp); #if DK3_HAVE_PNG_H /** Per frame data, PNG-specific. */ typedef struct { png_bytep *rows; png_colorp palp; png_size_t rowbytes; dk3_bif_coord_t h; dk3_bif_pixel_t bgred; dk3_bif_pixel_t bggreen; dk3_bif_pixel_t bgblue; int paln; } dk3_bif_frame_png_t; /** Per file data, PNG-specific. */ typedef struct { png_structp pp; /* Read structure. */ png_infop pi; /* PNG information. */ int ct; /* Color type. */ int im; /* Interlace method. */ int cm; /* Compression method. */ int fm; /* Filter method. */ int ch; /* Number of channels. */ int np; /* Number of interlace passes. */ } dk3_bif_png_t; /** Release type-specific information for PNG file. @param is Bitmap-type specific data. */ static void dk3bif_frame_release_implspec_png(void *is) { dk3_bif_frame_png_t *fdis; dk3_bif_coord_t i; #line 555 "dk3bif.ctr" fdis = (dk3_bif_frame_png_t *)is; if(fdis->rows) { #line 557 "dk3bif.ctr" for(i = 0L; i < fdis->h; i++) { #line 558 "dk3bif.ctr" dk3_delete((fdis->rows)[i]); } dk3_delete(fdis->rows); } dk3_release(fdis); #line 564 "dk3bif.ctr" } /** Release type specific information for PNG file (image). @param is Bitmap-type specific data. */ static void dk3bif_release_implspec_png(void *is) { dk3_bif_png_t *dis; #line 575 "dk3bif.ctr" dis = (dk3_bif_png_t *)is; if(dis->pp) { if(dis->pi) { #line 578 "dk3bif.ctr" png_destroy_info_struct(dis->pp, &(dis->pi)); } #line 580 "dk3bif.ctr" png_destroy_read_struct(&(dis->pp), (png_infopp)NULL, (png_infopp)NULL); } dis->pp = NULL; dis->pi = NULL; dk3_release(dis); #line 585 "dk3bif.ctr" } /** Read header for PNG image. @param bp Bitmap image file. @return 1 on success, 0 on error. */ static int dk3bif_read_png_header(dk3_bif_t *bp) { unsigned char header[9]; /* Test for PNG file header. */ dk3_bif_png_t *dis; dk3_bif_frame_png_t *fdis; #if 0 double gamma; /* Gamma value. */ #endif double dbldpi = 0.0; double dblxdpi = 0.0; double dblydpi = 0.0; png_uint_32 w; /* Image width. */ png_uint_32 h; /* Image height. */ png_uint_32 xdpi; /* X resolution. */ png_uint_32 ydpi; /* Y resolution. */ png_uint_32 dpi; /* Resolution. */ int bd; /* Bit depth. */ int ct; /* Color type. */ int im; /* Interlace method. */ int cm; /* Compression method. */ int fm; /* Filter method. */ int ch; /* Number of channels. */ int np = 1; /* Number of interlace passes. */ size_t szh; /* Number of header bytes read. */ int back = 0; #line 619 "dk3bif.ctr" szh = fread(header, 1, 8, bp->tmpfipo); if(szh > 0) { #line 621 "dk3bif.ctr" if(png_sig_cmp(header, 0, szh) == 0) { dis = dk3_new_app(dk3_bif_png_t,1,bp->app); if(dis) { #line 624 "dk3bif.ctr" bp->implspec = (void *)dis; dis->pp = NULL; dis->pi = NULL; dis->ct = 0; dis->pp = png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL, /* user error data */ NULL, /* user error function */ NULL /* user warning function */ ); if(dis->pp) { #line 633 "dk3bif.ctr" #if DK3_HAVE_SETJMP_H if(setjmp(png_jmpbuf(dis->pp)) == 0) { #endif dis->pi = png_create_info_struct(dis->pp); if(dis->pi) { #line 638 "dk3bif.ctr" bp->cf = dk3bif_frame_new(bp); if(bp->cf) { #line 640 "dk3bif.ctr" fdis = dk3_new_app(dk3_bif_frame_png_t,1,bp->app); if(fdis) { #line 642 "dk3bif.ctr" fdis->rows = NULL; fdis->rowbytes = 0; fdis->palp = NULL; fdis->paln = 0; fdis->bgred = 255; fdis->bggreen = 255; fdis->bgblue = 255; fdis->h = 0L; (bp->cf)->implspec = (void *)fdis; /* Prepare reading. */ png_init_io(dis->pp, bp->tmpfipo); png_set_sig_bytes(dis->pp, (int)szh); /* Read file information. */ png_read_info(dis->pp, dis->pi); /* Read information about the image. */ png_get_IHDR(dis->pp,dis->pi,&w,&h,&bd,&ct,&im,&cm,&fm); /* Static code analysis: Dead assignement. */ /* Needed for traceing, not for normal build. */ #if TRACE_DEBUG || VERSION_BEFORE_20150821 ch = png_get_channels(dis->pp, dis->pi); #line 667 "dk3bif.ctr" #endif if(png_get_valid(dis->pp, dis->pi, PNG_INFO_pHYs)) { #if VERSION_BEFORE_20150821 dbldpi = dblxdpi = dblydpi = 0.0; #endif #if DK3_HAVE_PNG_GET_PIXELS_PER_INCH dpi = png_get_pixels_per_inch(dis->pp, dis->pi); xdpi = png_get_x_pixels_per_inch(dis->pp, dis->pi); ydpi = png_get_y_pixels_per_inch(dis->pp, dis->pi); dbldpi = (double)dpi; dblxdpi = (double)xdpi; dblydpi = (double)ydpi; #else /* 0.0254 = 254 / 10000 */ dpi = png_get_pixels_per_meter(dis->pp, dis->pi); xdpi = png_get_x_pixels_per_meter(dis->pp, dis->pi); ydpi = png_get_y_pixels_per_meter(dis->pp, dis->pi); dbldpi = 0.0254 * (double)dpi; dblxdpi = 0.0254 * (double)xdpi; dblydpi = 0.0254 * (double)ydpi; dpi = (png_uint_32)dbldpi; xdpi = (png_uint_32)dblxdpi; ydpi = (png_uint_32)dblydpi; #endif if(!(xdpi)) { if(dpi) { xdpi = dpi; dblxdpi = dbldpi; } else { if(ydpi) { xdpi = ydpi; dblxdpi = dblydpi; } } } if(!(ydpi)) { if(dpi) { ydpi = dpi; dblydpi = dbldpi; } else { if(xdpi) { ydpi = xdpi; dblydpi = dblxdpi; } } } if((xdpi) && (ydpi)) { (bp->cf)->xres = dblxdpi; (bp->cf)->yres = dblydpi; if((xdpi == 72UL) && (ydpi == 72UL)) { (bp->cf)->xres = (bp->cf)->yres = -1.0; } } #line 707 "dk3bif.ctr" } /* Establish transformations. */ if(ct == PNG_COLOR_TYPE_PALETTE) { /* Convert palette image to RGB */ png_set_palette_to_rgb(dis->pp); } if(png_get_valid(dis->pp, dis->pi, PNG_INFO_tRNS)) { /* Get alpha values if available */ png_set_tRNS_to_alpha(dis->pp); } #if !DK3_WORDS_BIGENDIAN if(bd == 16) { /* Change network byte order to host byte order on x86. */ png_set_swap(dis->pp); } #endif #if 0 /* I need to find out some more about gamma correction. */ if(png_get_gAMA(dis->pp, dis->pi, &gamma)) { png_set_gamma(dis->pp, scg, gamma); } else { png_set_gamma(dis->pp, scg, 0.45455); } #endif switch(im) { case PNG_INTERLACE_ADAM7: { np = png_set_interlace_handling(dis->pp); } break; } /* Re-read information. */ png_read_update_info(dis->pp, dis->pi); png_get_IHDR(dis->pp,dis->pi,&w,&h,&bd,&ct,&im,&cm,&fm); ch = png_get_channels(dis->pp, dis->pi); #line 747 "dk3bif.ctr" (bp->cf)->w = (dk3_bif_coord_t)w; (bp->cf)->h = (dk3_bif_coord_t)h; (bp->cf)->realbits = (bp->cf)->bits = (size_t)bd; dis->ct = ct; dis->im = im; dis->cm = cm; dis->fm = fm; dis->ch = ch; dis->np = np; fdis->h = h; switch(ct) { case PNG_COLOR_TYPE_GRAY: { /* 1,2,4,8,16 */ (bp->cf)->cs = DK3_COLOR_SPACE_GRAY; back = 1; } break; case PNG_COLOR_TYPE_GRAY_ALPHA: { /* 8,16 */ (bp->cf)->cs = DK3_COLOR_SPACE_GRAY_ALPHA; back = 1; } break; case PNG_COLOR_TYPE_PALETTE: { /* 1,2,4,8 */ (bp->cf)->cs = DK3_COLOR_SPACE_RGB; back = 1; } break; case PNG_COLOR_TYPE_RGB: { /* 8,16 */ (bp->cf)->cs = DK3_COLOR_SPACE_RGB; back = 1; } break; case PNG_COLOR_TYPE_RGB_ALPHA: { /* 8,16 */ (bp->cf)->cs = DK3_COLOR_SPACE_RGBA; back = 1; } break; } } else { #line 780 "dk3bif.ctr" } } else { #line 782 "dk3bif.ctr" } } else { #line 784 "dk3bif.ctr" } #if DK3_HAVE_SETJMP_H } else { back = 0; } #endif } else { #line 791 "dk3bif.ctr" } } else { #line 793 "dk3bif.ctr" } } else { #line 795 "dk3bif.ctr" } } else { #line 797 "dk3bif.ctr" } #line 799 "dk3bif.ctr" return back; } /** Read data for PNG image. @param bp Bitmap image file. @return 1 on success, 0 on error. */ static int dk3bif_read_png_data(dk3_bif_t *bp) { #if 0 png_color_16 bg; #endif png_color_16p bgp = NULL; dk3_bif_png_t *dis; dk3_bif_frame_png_t *fdis; png_bytep *rp; dk3_bif_coord_t i; int back = 0; dis = (dk3_bif_png_t *)(bp->implspec); fdis = (dk3_bif_frame_png_t *)((bp->cf)->implspec); #if DK3_HAVE_SETJMP_H if(setjmp(png_jmpbuf(dis->pp)) == 0) { #endif fdis->rowbytes = png_get_rowbytes(dis->pp, dis->pi); fdis->rows = dk3_new_app(png_bytep,(size_t)((bp->cf)->h),bp->app); if(fdis->rows) { rp = fdis->rows; for(i = 0L; i < (bp->cf)->h; i++) { *(rp++) = NULL; } back = 1; rp = fdis->rows; for(i = 0L; (i < (bp->cf)->h) && (back == 1); i++) { *rp = dk3_new_app(png_byte, fdis->rowbytes, bp->app); if(!(*rp)) { back = 0; } rp++; } if(back) { png_read_image(dis->pp, fdis->rows); if(png_get_bKGD(dis->pp, dis->pi, &bgp)) { fdis->bgred = bgp->red; fdis->bggreen = bgp->green; fdis->bgblue = bgp->blue; #line 844 "dk3bif.ctr" } if(dis->ct == PNG_COLOR_TYPE_PALETTE) { back = 0; png_get_PLTE(dis->pp, dis->pi, &(fdis->palp), &(fdis->paln)); if((fdis->palp) && (fdis->paln)) { back = 1; } } } } else { #line 854 "dk3bif.ctr" } #if DK3_HAVE_SETJMP_H } else { back = 0; } #endif return back; } /** Retrieve one pixel component from PNG. @param bp Bitmap image. @param x X coordinate. @param y Y coordinate. @param c Choose component: 0=red/gray, 1=green, 2=blue, 3=alpha. @return Pixel component. */ static dk3_bif_pixel_t dk3bif_get_png_pixel_component( dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y, int c ) { png_bytep row; dk3_bif_png_t *dis; dk3_bif_frame_png_t *fdis; dk3_bif_pixel_t back = (dk3_bif_pixel_t)0; dk3_bif_coord_t vi; if(bp) { if(bp->cf) { if(bp->implspec) { if((bp->cf)->implspec) { dis = (dk3_bif_png_t *)(bp->implspec); fdis = (dk3_bif_frame_png_t *)((bp->cf)->implspec); if(fdis->rows) { row = (fdis->rows)[y]; vi = 0L; switch(dis->ct) { case PNG_COLOR_TYPE_GRAY: { vi = x; } break; case PNG_COLOR_TYPE_GRAY_ALPHA: { vi = 2L * x; if(c == 3) { vi = vi + 1; } } break; case PNG_COLOR_TYPE_RGB: { vi = 3L * x; if((c >= 0) && (c < 3)) { vi = vi + (dk3_bif_coord_t)c; } } break; case PNG_COLOR_TYPE_RGB_ALPHA: { vi = 4L * x; if((c >= 0) && (c < 4)) { vi = vi + (dk3_bif_coord_t)c; } } break; default: { /* Must not happen, we requested conversion from palette to RGB. */ } break; } back = dk3pixre_get_value_from_packed_bytes( (unsigned char const *)row, vi, (bp->cf)->bits ); } } } } } return back; } #endif /* if DK3_HAVE_PNG_H */ #if DK3_HAVE_JPEGLIB_H /* JPEGLIB error management. */ /** JPEGLIB error manager. */ typedef struct { struct jpeg_error_mgr pub; /**< Default error manager. */ #if DK3_HAVE_SETJMP_H jmp_buf setjmp_buffer; /**< Buffer for setjmp. */ #endif } dk3_bif_jpg_error_mgr; /** Per frame data, JPEG-specific. */ typedef struct { JSAMPLE **rows; /**< Sample buffer. */ JDIMENSION w; /**< Image width. */ JDIMENSION h; /**< Image height. */ int is_adobe; /**< Flag: Adobe marker found. */ int num_comp; /**< Number of components found. */ } dk3_bif_frame_jpeg_t; /** Per file data, JPEG-specific. */ typedef struct { int st; struct jpeg_decompress_struct cinfo; /**< Decompression struct. */ dk3_bif_jpg_error_mgr errmgr; /**< Error manager. */ } dk3_bif_jpeg_t; /** Error exit replacement function. @param cinfo JPEG decompression structure. */ static void dk3bif_jpeg_error_exit(j_common_ptr cinfo) { dk3_bif_jpg_error_mgr *myerr = (dk3_bif_jpg_error_mgr *)(cinfo->err); if(myerr) { longjmp(myerr->setjmp_buffer, 1); } } /** Release type-specific information for JPEG file (frame). @param is Bitmap-type specific data. */ static void dk3bif_frame_release_implspec_jpeg(void *is) { dk3_bif_frame_jpeg_t *fdis; JSAMPLE **ptr; JDIMENSION i; fdis = (dk3_bif_frame_jpeg_t *)is; if(fdis->rows) { ptr = fdis->rows; for(i = 0; i < fdis->h; i++) { dk3_release(*ptr); ptr++; } dk3_delete(fdis->rows); } dk3_delete(is); } /** Release type specific information for JPEG file (image). @param is Bitmap-type specific data. */ static void dk3bif_release_implspec_jpeg(void *is) { dk3_bif_jpeg_t *dis; dis = (dk3_bif_jpeg_t *)is; if(dis->st >= 1) { #if DK3_HAVE_SETJMP_H if(setjmp((dis->errmgr).setjmp_buffer) == 0) { #endif jpeg_destroy_decompress(&(dis->cinfo)); #if DK3_HAVE_SETJMP_H } #endif } dk3_delete(dis); } /** Read header for JPEG image. @param bp Bitmap image file. @return 1 on success, 0 on error. */ static int dk3bif_read_jpeg_header(dk3_bif_t *bp) { dk3_bif_jpeg_t *dis = NULL; dk3_bif_frame_jpeg_t *fdis = NULL; int back = 0; #line 1037 "dk3bif.ctr" bp->cf = dk3bif_frame_new(bp); if(bp->cf) { dis = dk3_new_app(dk3_bif_jpeg_t,1,bp->app); if(dis) { bp->implspec = (void *)dis; dis->st = 0; /* Initial state. */ (dis->errmgr).pub.error_exit = dk3bif_jpeg_error_exit; (dis->cinfo).err = jpeg_std_error(&((dis->errmgr).pub)); (dis->errmgr).pub.error_exit = dk3bif_jpeg_error_exit; #if DK3_HAVE_SETJMP_H if(setjmp((dis->errmgr).setjmp_buffer) == 0) { #endif jpeg_create_decompress(&(dis->cinfo)); dis->st = 1; /* Decompress created. */ if(bp->tmpfipo) { jpeg_stdio_src(&(dis->cinfo), bp->tmpfipo); dis->st = 2; jpeg_read_header(&(dis->cinfo), TRUE); dis->st = 3; fdis = dk3_new_app(dk3_bif_frame_jpeg_t,1,bp->app); if(fdis) { (bp->cf)->implspec = (void *)fdis; fdis->is_adobe = 0; fdis->num_comp = (dis->cinfo).num_components; #line 1062 "dk3bif.ctr" fdis->rows = NULL; fdis->w = (dis->cinfo).image_width; fdis->h = (dis->cinfo).image_height; (bp->cf)->w = (dk3_bif_coord_t)(fdis->w); (bp->cf)->h = (dk3_bif_coord_t)(fdis->h); (bp->cf)->realbits = (bp->cf)->bits = 8; switch((dis->cinfo).jpeg_color_space) { case JCS_GRAYSCALE: { #line 1070 "dk3bif.ctr" (bp->cf)->cs = DK3_COLOR_SPACE_GRAY; } break; case JCS_RGB: { #line 1073 "dk3bif.ctr" (bp->cf)->cs = DK3_COLOR_SPACE_RGB; } break; case JCS_CMYK: { #line 1076 "dk3bif.ctr" (bp->cf)->cs = DK3_COLOR_SPACE_CMYK; } break; case JCS_YCCK: { #line 1079 "dk3bif.ctr" (bp->cf)->cs = DK3_COLOR_SPACE_CMYK; } break; case JCS_YCbCr: { #line 1082 "dk3bif.ctr" (bp->cf)->cs = DK3_COLOR_SPACE_YCbCr; } break; default: { /* No setting available (yet). */ } break; } if((dis->cinfo).saw_JFIF_marker) { switch((dis->cinfo).density_unit) { case 0x01: { /* per inch */ if(((dis->cinfo).X_density) && ((dis->cinfo).Y_density)) { (bp->cf)->xres = (double)((dis->cinfo).X_density); (bp->cf)->yres = (double)((dis->cinfo).Y_density); } } break; case 0x02: { /* per cm */ if(((dis->cinfo).X_density) && ((dis->cinfo).Y_density)) { (bp->cf)->xres = 2.54 * (double)((dis->cinfo).X_density); (bp->cf)->yres = 2.54 * (double)((dis->cinfo).Y_density); } } break; } } back = 1; if((dis->cinfo).saw_Adobe_marker) { fdis->is_adobe = 1; } } } #if DK3_HAVE_SETJMP_H } else { } #endif } } #line 1117 "dk3bif.ctr" return back; } /** Read data for JPEG image. @param bp Bitmap image file. @return 1 on success, 0 on error. */ static int dk3bif_read_jpeg_data(dk3_bif_t *bp) { dk3_bif_jpeg_t *dis = NULL; dk3_bif_frame_jpeg_t *fdis = NULL; JSAMPROW *rp = NULL; JDIMENSION y; int back = 0; int ok; int occ; #line 1136 "dk3bif.ctr" if(bp->implspec) { #line 1137 "dk3bif.ctr" if(bp->cf) { #line 1138 "dk3bif.ctr" if((bp->cf)->implspec) { #line 1139 "dk3bif.ctr" dis = (dk3_bif_jpeg_t *)(bp->implspec); fdis = (dk3_bif_frame_jpeg_t *)((bp->cf)->implspec); #line 1141 "dk3bif.ctr" if(dis->st == 3) { #line 1142 "dk3bif.ctr" #if DK3_HAVE_SETJMP_H if(setjmp((dis->errmgr).setjmp_buffer) == 0) { #line 1144 "dk3bif.ctr" #endif dis->st = 4; /* We attempted to continue. */ jpeg_start_decompress(&(dis->cinfo)); dis->st = 5; /* Decompression started. */ fdis->rows = dk3_new_app(JSAMPROW,fdis->h,bp->app); if(fdis->rows) { #line 1150 "dk3bif.ctr" occ = (dis->cinfo).out_color_components; ok = 1; #line 1152 "dk3bif.ctr" rp = fdis->rows; #line 1153 "dk3bif.ctr" for(y = 0; y < fdis->h; y++) { *(rp++) = NULL; } occ = occ * fdis->w; #line 1155 "dk3bif.ctr" rp = fdis->rows; for(y = 0; y < fdis->h; y++) { #line 1157 "dk3bif.ctr" *rp = dk3_new_app(JSAMPLE,occ,bp->app); if(!(*rp)) { ok = 0; #line 1160 "dk3bif.ctr" } rp++; } if(ok) { #line 1164 "dk3bif.ctr" dis->st = 6; /* Decompression started. */ rp = fdis->rows; #line 1166 "dk3bif.ctr" for(y = 0; y < fdis->h; y++) { #line 1167 "dk3bif.ctr" jpeg_read_scanlines(&(dis->cinfo), rp, 1); rp++; #line 1169 "dk3bif.ctr" } #line 1170 "dk3bif.ctr" dis->st = 7; /* Data was read successfully. */ jpeg_finish_decompress(&(dis->cinfo)); #line 1172 "dk3bif.ctr" dis->st = 8; /* Decompression finished. */ switch((dis->cinfo).out_color_space) { case JCS_GRAYSCALE: { #line 1175 "dk3bif.ctr" (bp->cf)->cs = DK3_COLOR_SPACE_GRAY; back = 1; } break; case JCS_RGB: { #line 1179 "dk3bif.ctr" (bp->cf)->cs = DK3_COLOR_SPACE_RGB; back = 1; } break; default: { (bp->cf)->cs = 0; } break; } } else { } } else { #line 1189 "dk3bif.ctr" } #if DK3_HAVE_SETJMP_H } else { } #endif } else { #line 1195 "dk3bif.ctr" } } else { #line 1197 "dk3bif.ctr" } } else { #line 1199 "dk3bif.ctr" } } #line 1201 "dk3bif.ctr" return back; } /** Retrieve one pixel component from JPEG. @param bp Bitmap image. @param x X coordinate. @param y Y coordinate. @param c Choose component: 0=red/gray, 1=green, 2=blue, 3=alpha. @return Pixel component. */ static dk3_bif_pixel_t dk3bif_get_jpeg_pixel_component( dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y, int c ) { #if VERSION_BEFORE_20150821 dk3_bif_jpeg_t *dis = NULL; #endif dk3_bif_frame_jpeg_t *fdis = NULL; dk3_bif_pixel_t back = (dk3_bif_pixel_t)0; JSAMPLE value; JSAMPLE *row; if(bp) { if(bp->cf) { if(bp->implspec) { if((bp->cf)->implspec) { #if VERSION_BEFORE_20150821 dis = (dk3_bif_jpeg_t *)(bp->implspec); #endif fdis = (dk3_bif_frame_jpeg_t *)((bp->cf)->implspec); if(c == 3) { back = 255; } else { switch((bp->cf)->cs) { case DK3_COLOR_SPACE_GRAY: { if((c >= 0) && (c < 3)) { if(fdis->rows) { row = (fdis->rows)[y]; if(row) { value = row[x]; back = (dk3_bif_pixel_t)value; back &= 0x00FFU; } } } } break; case DK3_COLOR_SPACE_RGB: { if((c >= 0) && (c < 3)) { if(fdis->rows) { row = (fdis->rows)[y]; if(row) { value = row[3 * x + c]; back = (dk3_bif_pixel_t)value; back &= 0x00FFU; } } } } break; } } } } } } return back; } #endif /* if DK3_HAVE_JPEGLIB_H */ #if DK3_HAVE_TIFF_H /** Per frame data, TIFF-specific. */ typedef struct { uint32 *r; /**< Raster image data. */ uint32 w; /**< Image width. */ uint32 h; /**< Image height. */ uint16 cps; uint16 spp; uint16 ori; /**< Orientation. */ } dk3_bif_frame_tiff_t; /** Per file data, TIFF-specific. */ typedef struct { TIFF *tiff; } dk3_bif_tiff_t; /** Release type-specific information for TIFF file. @param is Bitmap-type specific data. */ static void dk3bif_frame_release_implspec_tiff(void *is) { dk3_bif_frame_tiff_t *fdis; fdis = (dk3_bif_frame_tiff_t *)is; if(fdis->r) { _TIFFfree(fdis->r); fdis->r = NULL; } fdis->w = fdis->h = 0UL; fdis->spp = fdis->cps = 0U; dk3_delete(fdis); } /** Release type specific information for TIFF file (image). @param is Bitmap-type specific data. */ static void dk3bif_release_implspec_tiff(void *is) { dk3_bif_tiff_t *dis; dis = (dk3_bif_tiff_t *)is; if(dis->tiff) { TIFFClose(dis->tiff); dis->tiff = NULL; } dk3_delete(dis); } /** Read header for TIFF image. @param bp Bitmap image file. @return 1 on success, 0 on error. */ static int dk3bif_read_tiff_header(dk3_bif_t *bp) { dk3_bif_frame_tiff_t *fdis; dk3_bif_tiff_t *dis; float rv; #if VERSION_BEFORE_20140809 unsigned long wh = 0UL; #else dk3_um_t wh = DK3_UM_0; #endif uint32 w; uint32 h; int back = 0; int me = 0; size_t sz; #if VERSION_BEFORE_20150821 uint16 cps; uint16 spp; #endif uint16 ru; uint16 orient; #line 1357 "dk3bif.ctr" if(bp->tmpfn) { #line 1358 "dk3bif.ctr" dis = dk3_new_app(dk3_bif_tiff_t,1,bp->app); if(dis) { #line 1360 "dk3bif.ctr" /* Initialization of TIFF per file. */ bp->implspec = (void *)dis; dis->tiff = NULL; dis->tiff = TIFFOpen(bp->tmpfn, "rb"); if(dis->tiff) { #line 1367 "dk3bif.ctr" back = 1; do { #line 1369 "dk3bif.ctr" w = h = 0UL; rv = 0.0; ru = 0; #if VERSION_BEFORE_20150821 cps = spp = 0U; #endif bp->cf = dk3bif_frame_new(bp); if(bp->cf) { #line 1375 "dk3bif.ctr" (bp->cf)->realbits = (bp->cf)->bits = 8; (bp->cf)->cs = DK3_COLOR_SPACE_RGBA; fdis = dk3_new_app(dk3_bif_frame_tiff_t,1,bp->app); if(fdis) { #line 1379 "dk3bif.ctr" /* Initialize TIFF per frame. */ fdis->w = fdis->h = 0UL; fdis->cps = fdis->spp = 0U; fdis->r = NULL; fdis->ori = ORIENTATION_BOTLEFT; (bp->cf)->implspec = (void *)fdis; if(TIFFGetField(dis->tiff, TIFFTAG_IMAGEWIDTH, &w) == 1) { fdis->w = w; #line 1388 "dk3bif.ctr" (bp->cf)->w = (dk3_bif_coord_t)w; if(TIFFGetField(dis->tiff, TIFFTAG_IMAGELENGTH, &h) == 1) { fdis->h = h; #line 1391 "dk3bif.ctr" (bp->cf)->h = (dk3_bif_coord_t)h; rv = 0.0; if(TIFFGetField(dis->tiff, TIFFTAG_XRESOLUTION, &rv) == 1) { (bp->cf)->xres = (double)rv; #line 1395 "dk3bif.ctr" } rv = 0.0; if(TIFFGetField(dis->tiff, TIFFTAG_YRESOLUTION, &rv) == 1) { (bp->cf)->yres = (double)rv; #line 1399 "dk3bif.ctr" } ru = 0; if(TIFFGetField(dis->tiff, TIFFTAG_RESOLUTIONUNIT, &ru) == 1) { #line 1403 "dk3bif.ctr" switch(ru) { case RESUNIT_CENTIMETER: { #line 1405 "dk3bif.ctr" (bp->cf)->xres = 2.54 * (bp->cf)->xres; (bp->cf)->yres = 2.54 * (bp->cf)->yres; } break; case RESUNIT_NONE: { #line 1409 "dk3bif.ctr" (bp->cf)->xres = (bp->cf)->yres = -1.0; } break; } } orient = ORIENTATION_TOPLEFT; if(TIFFGetFieldDefaulted( dis->tiff, TIFFTAG_ORIENTATION, &orient ) == 1 ) { #line 1419 "dk3bif.ctr" fdis->ori = orient; switch(orient) { case 5: case 6: case 7: case 8: { #line 1422 "dk3bif.ctr" fdis->h = w; (bp->cf)->h = w; fdis->w = h; (bp->cf)->w = h; rv = (float)((bp->cf)->xres); (bp->cf)->xres = (bp->cf)->yres; (bp->cf)->yres = rv; } break; } } else { orient = ORIENTATION_TOPLEFT; } #if VERSION_BEFORE_20140809 wh = dk3ma_ul_mul_ok(w, h, &me); wh = dk3ma_ul_mul_ok(4UL, wh, &me); #else wh = dk3ma_um_mul_ok((dk3_um_t)w, (dk3_um_t)h, &me); wh = dk3ma_um_mul_ok((dk3_um_t)4U, wh, &me); #endif if(me) { back = 0; #line 1443 "dk3bif.ctr" } else { #line 1444 "dk3bif.ctr" #if VERSION_BEFORE_20140809 sz = (size_t)wh; if(wh == (unsigned long)sz) #else sz = dk3ma_um_to_sz(wh, &me); if (0 != sz) #endif { #line 1452 "dk3bif.ctr" fdis->r = (uint32 *)_TIFFmalloc(sz); if(fdis->r) { #line 1454 "dk3bif.ctr" if(TIFFReadRGBAImageOriented( dis->tiff, w, h, fdis->r, orient, 0 ) ) { #if TRACE_DEBUG || VERSION_BEFORE_20150821 back = 1; #line 1461 "dk3bif.ctr" #endif } else { #line 1463 "dk3bif.ctr" back = 0; } } else { #line 1466 "dk3bif.ctr" back = 0; } } else { back = 0; #line 1470 "dk3bif.ctr" } } } else { #line 1473 "dk3bif.ctr" back = 0; } } else { #line 1476 "dk3bif.ctr" back = 0; } } else { back = 0; #line 1480 "dk3bif.ctr" } } else { back = 0; #line 1483 "dk3bif.ctr" } w = h = 0UL; #if VERSION_BEFORE_20150821 cps = spp = 0U; #endif #line 1489 "dk3bif.ctr" } while((back == 1) && TIFFReadDirectory(dis->tiff)); TIFFClose(dis->tiff); dis->tiff = NULL; #line 1491 "dk3bif.ctr" if(bp->i_frames) { #line 1492 "dk3bif.ctr" dk3sto_it_reset(bp->i_frames); bp->cf = (dk3_bif_frame_t *)dk3sto_it_next(bp->i_frames); if(!(bp->cf)) { #line 1495 "dk3bif.ctr" back = 0; } } else { #line 1498 "dk3bif.ctr" } } else { #line 1500 "dk3bif.ctr" } } else { #line 1502 "dk3bif.ctr" } } else { #line 1504 "dk3bif.ctr" } #line 1505 "dk3bif.ctr" return back; } /** Read data for TIFF image. @param bp Bitmap image file. @return 1 on success, 0 on error. */ static int dk3bif_read_tiff_data(dk3_bif_t *bp) { int back = 0; if(bp->i_frames) { dk3sto_it_reset(bp->i_frames); bp->cf = (dk3_bif_frame_t *)dk3sto_it_next(bp->i_frames); if(bp->cf) { back = 1; } } return back; } /** Retrieve one pixel component from TIFF. @param bp Bitmap image. @param x X coordinate. @param y Y coordinate. @param c Choose component: 0=red/gray, 1=green, 2=blue, 3=alpha. @return Pixel component. */ static dk3_bif_pixel_t dk3bif_get_tiff_pixel_component( dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y, int c ) { dk3_bif_frame_tiff_t *fdis; dk3_bif_pixel_t back = (dk3_bif_pixel_t)0; uint32 uv; if(bp) { if(bp->cf) { if(bp->implspec) { if((bp->cf)->implspec) { fdis = (dk3_bif_frame_tiff_t *)((bp->cf)->implspec); if(fdis->r) { uv = (fdis->r)[y * (bp->cf)->w + x]; /* uv = (fdis->r)[((bp->cf)->h - y - 1) * (bp->cf)->w + x]; */ switch(c) { case 3: { uv = ((uv >> 24) & 0x000000FFUL); } break; case 2: { uv = ((uv >> 16) & 0x000000FFUL); } break; case 1: { uv = ((uv >> 8) & 0x000000FFUL); } break; default: { uv = (uv & 0x000000FFUL); } break; } back = (dk3_bif_pixel_t)uv; } } } } } return back; } #endif /* if DK3_HAVE_TIFF_H */ /** Calculate gray value from red, green, blue. @param r Red value. @param g Green value. @param b Blue value. @return Gray value. */ static dk3_bif_pixel_t dk3bif_ntsc(dk3_bif_pixel_t r, dk3_bif_pixel_t g, dk3_bif_pixel_t b) { dk3_bif_pixel_t back; back = (dk3_bif_pixel_t)( ( 30UL * (unsigned long)r + 59UL * (unsigned long)g + 11UL * (unsigned long)b ) / 100UL ); return back; } /** Delete BIF frame, release memory. @param tp Image type. @param fp Frame to delete. */ static void dk3bif_frame_delete(dk3_bif_frame_t *fp, int tp) { #line 1618 "dk3bif.ctr" if(fp) { /* Release type-depending components. */ if(fp->implspec) { switch(tp) { case DK3_BIF_IMAGE_TYPE_PNG: { #if DK3_HAVE_PNG_H dk3bif_frame_release_implspec_png(fp->implspec); #endif } break; case DK3_BIF_IMAGE_TYPE_JPEG: { #if DK3_HAVE_JPEGLIB_H dk3bif_frame_release_implspec_jpeg(fp->implspec); #endif } break; case DK3_BIF_IMAGE_TYPE_TIFF: { #if DK3_HAVE_TIFF_H dk3bif_frame_release_implspec_tiff(fp->implspec); #endif } break; } } fp->implspec = NULL; /* Release type-independent components. */ fp->w = fp->h = 0L; fp->realbits = fp->bits = fp->n = 0; fp->cs = 0; /* Release frame itself. */ dk3_delete(fp); } #line 1651 "dk3bif.ctr" } /** Allocate memory for new frame. @param bp Bitmap image file. @return Pointer to new frame on success, NULL on error. */ static dk3_bif_frame_t * dk3bif_frame_new(dk3_bif_t *bp) { dk3_bif_frame_t *back = NULL; back = dk3_new_app(dk3_bif_frame_t,1,bp->app); if(back) { back->implspec = NULL; back->xres = -1.0; back->yres = -1.0; back->w = 0L; back->h = 0L; back->realbits = back->bits = 0; back->realcolor = 1; back->realalpha = 1; back->n = bp->n_frames; back->cs = 0; back->bg = 0; back->bgr = back->bgg = back->bgb = back->bggr = 0U; if(dk3sto_add(bp->s_frames, (void *)back)) { bp->n_frames += 1; } else { dk3bif_frame_delete(back, bp->bt); back = NULL; } } return back; } dk3_bif_pixel_t dk3bif_get_pixel_component_not_resampled( dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y, int c ) { dk3_bif_pixel_t back = (dk3_bif_pixel_t)0; #line 1698 "dk3bif.ctr" if(c == 3) { #line 1699 "dk3bif.ctr" back = dk3pixre_get_max_value(&(bp->pr)); } if((x >= 0L) && (x < (bp->cf)->w)) { if((y >= 0L) && (y < (bp->cf)->h)) { switch(bp->bt) { case DK3_BIF_IMAGE_TYPE_PNG: { #if DK3_HAVE_PNG_H back = dk3bif_get_png_pixel_component(bp, x, y, c); #endif } break; case DK3_BIF_IMAGE_TYPE_JPEG: { #if DK3_HAVE_JPEGLIB_H back = dk3bif_get_jpeg_pixel_component(bp, x, y, c); #endif } break; case DK3_BIF_IMAGE_TYPE_TIFF: { #if DK3_HAVE_TIFF_H back = dk3bif_get_tiff_pixel_component(bp, x, y, c); #endif } break; } } } #line 1723 "dk3bif.ctr" return back; } /** Retrieve one pixel component resampled to output bit size. @param bp Bitmap image. @param x X coordinate. @param y Y coordinate. @param c Choose component: 0=red/gray, 1=green, 2=blue, 3=alpha. @return Pixel component. */ static dk3_bif_pixel_t dk3bif_get_pixel_component( dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y, int c ) { dk3_bif_pixel_t back; #line 1746 "dk3bif.ctr" /* Get unresampled value. */ back = dk3bif_get_pixel_component_not_resampled(bp, x, y, c); /* Resample value to requested output bit size. */ #line 1754 "dk3bif.ctr" back = dk3pixre_convert(&(bp->pr), back); return back; } /** Compare two frames by number. @param l Left frame. @param r Right frame or number. @param cr Comparison criteria: 0=frame/frame, 1=frame/number. @return Comparison result. */ static int dk3bif_frame_compare(void const *l, void const *r, int cr) { int back = 0; dk3_bif_frame_t const *pl; dk3_bif_frame_t const *pr; size_t *psz; if(l) { if(r) { pl = (dk3_bif_frame_t const *)l; pr = (dk3_bif_frame_t const *)r; psz = (size_t *)r; switch(cr) { case 1: { if(pl->n > *psz) { back = 1; } else { if(pl->n < *psz) { 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; } /** Set up upsampling/downsampling after changing frame or output bit number. @param bp Bitmap image file. */ static void dk3bif_set_pixel_sampling(dk3_bif_t *bp) { #line 1819 "dk3bif.ctr" if(bp) { if(bp->cf) { if(bp->bits) { #line 1822 "dk3bif.ctr" dk3pixre_set(&(bp->pr), (bp->cf)->bits, bp->bits); } else { #line 1824 "dk3bif.ctr" dk3pixre_set(&(bp->pr), (bp->cf)->bits, (bp->cf)->bits); } } } #line 1829 "dk3bif.ctr" } /** Allocate memory for bitmap image file. @param tp Image type. @param app Application structure for diagnostics, may not be NULL. @return Pointer to new structure on success, NULL on error. */ static dk3_bif_t * dk3bif_allocate_app(int tp, dk3_app_t *app) { dk3_bif_t *back = NULL; int ok = 0; #line 1845 "dk3bif.ctr" if(app) { back = dk3_new_app(dk3_bif_t,1,app); if(back) { dk3pixre_set(&(back->pr), 8, 8); back->app = app; back->tmpfn = NULL; back->tmpfipo = NULL; back->s_frames = NULL; back->i_frames = NULL; back->cf = NULL; back->implspec = NULL; back->n = dk3bif_temp_number++; back->n_frames = 0; back->bits = 0; back->bt = tp; back->bg = 0; back->remtmpf = 0; back->bgr = back->bgg = back->bgb = 255U; back->s_frames = dk3sto_open_app(app); if(back->s_frames) { dk3sto_set_comp(back->s_frames, dk3bif_frame_compare, 0); back->i_frames = dk3sto_it_open(back->s_frames); if(back->i_frames) { ok = 1; } } if(!(ok)) { dk3bif_close(back); back = NULL; } } } #line 1877 "dk3bif.ctr" return back; } /** Read image header information. Create the frames, fill implspec for bif and frame. @param bp Bitmap image file. @return 1 on success, 0 on error. */ static int dk3bif_read_header(dk3_bif_t *bp) { int back = 0; #line 1893 "dk3bif.ctr" switch(bp->bt) { case DK3_BIF_IMAGE_TYPE_PNG: { #if DK3_HAVE_PNG_H back = dk3bif_read_png_header(bp); #endif } break; case DK3_BIF_IMAGE_TYPE_JPEG: { #if DK3_HAVE_JPEGLIB_H back = dk3bif_read_jpeg_header(bp); #endif } break; case DK3_BIF_IMAGE_TYPE_TIFF: { #if DK3_HAVE_TIFF_H back = dk3bif_read_tiff_header(bp); #endif } break; } dk3bif_set_pixel_sampling(bp); #line 1912 "dk3bif.ctr" return back; } /** Create a temporary file name (8 bit characters). @param fnb File name buffer. @param bp Bitmap image file pointer. */ static void dk3bif_create_tmpfilename(char *fnb, dk3_bif_t *bp) { #line 1926 "dk3bif.ctr" #if DK3_ON_WINDOWS sprintf(fnb, dk3bif_kw_c8[1], _getpid(), bp->n); #else #if DK3_HAVE_GETPID sprintf(fnb, dk3bif_kw_c8[0], (unsigned long)getpid(), bp->n); #else time_t timer; time(&timer); sprintf(fnb, dk3bif_kw_c8[0], (unsigned long)timer, bp->n); #endif #endif #line 1938 "dk3bif.ctr" } /** Copy input file to temporary file. This function relies on tmpfn set. @param bp Bitmap image file. @param fipos Source file, must be opened "rb". @param app Application structure for diagnostics. @return 1 on success, 0 on error. */ static int dk3bif_copy_to_temp(dk3_bif_t *bp, FILE *fipos, dk3_app_t *app) { char bu[4096]; /* Buffer. */ FILE *fipod; /* Destination file. */ int back = 0; int cc = 1; /* Flag: Can continue copying. */ size_t rdb; /* Bytes read. */ #line 1959 "dk3bif.ctr" fipod = dk3sf_c8_fopen_app(bp->tmpfn, "wb", app); if(fipod) { back = 1; while(cc) { cc = 0; rdb = dk3sf_fread_app(bu, 1, sizeof(bu), fipos, app); if(rdb > 0) { if(dk3sf_fwrite_app(bu, 1, rdb, fipod, app)) { cc = 1; } else { back = 0; } } } #if DK3_CHAR_SIZE == 1 if(!dk3sf_fclose_fn_app(fipod, bp->tmpfn, app)) { back = 0; } #else if(!dk3sf_fclose_fn_app(fipod, NULL, app)) { back = 0; } #endif } #line 1983 "dk3bif.ctr" return back; } /** Correct image type. @param tp Original image type, may need correction. @return Corrected value (set to DK3_BIF_IMAGE_TYPE_UNKNOWN if necessary). */ static int dk3bif_correct_type(int tp) { int back; back = tp; #line 2000 "dk3bif.ctr" if(tp != DK3_BIF_IMAGE_TYPE_PNG) { if(tp != DK3_BIF_IMAGE_TYPE_JPEG) { if(tp != DK3_BIF_IMAGE_TYPE_TIFF) { /* +++ further file types here +++ */ back = DK3_BIF_IMAGE_TYPE_UNKNOWN; } } } #line 2008 "dk3bif.ctr" return back; } dk3_bif_t * dk3bif_open_filename_app(dkChar const *fn, int tp, dk3_app_t *app) { char fnb[128]; /* File name buffer for temp file. */ dk3_bif_t *back = NULL; FILE *fipos; int mytp; /* Type, corrected if necessary. */ int ok = 0; /* Flag: Success. */ #line 2022 "dk3bif.ctr" mytp = dk3bif_correct_type(tp); if((fn) && (app)) { if(mytp == DK3_BIF_IMAGE_TYPE_UNKNOWN) { mytp = dk3bif_check_file_name(fn); } if(dk3bif_type_supported(mytp)) { back = dk3bif_allocate_app(mytp, app); if(back) { switch(back->bt) { case DK3_BIF_IMAGE_TYPE_TIFF: { dk3bif_create_tmpfilename(fnb, back); back->tmpfn = dk3str_c8_dup_app(fnb, NULL); if(back->tmpfn) { back->remtmpf = 1; fipos = dk3sf_fopen_app(fn, dk3bif_kw_dk[0], app); if(fipos) { ok = dk3bif_copy_to_temp(back, fipos, app); fclose(fipos); if(ok) { ok = dk3bif_read_header(back); } } } } break; default: { back->tmpfipo = dk3sf_fopen_app(fn, dk3bif_kw_dk[0], app); if(back->tmpfipo) { ok = dk3bif_read_header(back); } } break; } if(!(ok)) { dk3bif_close(back); back = NULL; } } } else { if(app) { /* ERROR: File type unknown or unsupported! */ dk3app_log_i1(app, DK3_LL_ERROR, 257); } } } #line 2064 "dk3bif.ctr" return back; } dk3_bif_t * dk3bif_open_c8_filename_app(char const *fn, int tp, dk3_app_t *app) { dk3_bif_t *back = NULL; int mytp; /* Type, corrected if necessary. */ int ok = 0; /* Flag: Success. */ #line 2075 "dk3bif.ctr" mytp = dk3bif_correct_type(tp); if((fn) && (app)) { if(mytp == DK3_BIF_IMAGE_TYPE_UNKNOWN) { mytp = dk3bif_check_c8_file_name(fn); } if(dk3bif_type_supported(mytp)) { back = dk3bif_allocate_app(mytp, app); if(back) { switch(back->bt) { case DK3_BIF_IMAGE_TYPE_TIFF: { back->tmpfn = dk3str_c8_dup_app(fn, NULL); if(back->tmpfn) { ok = dk3bif_read_header(back); } } break; default: { back->tmpfipo = dk3sf_c8_fopen_app(fn, "rb", app); if(back->tmpfipo) { ok = dk3bif_read_header(back); } } break; } if(!(ok)) { dk3bif_close(back); back = NULL; } } } else { if(app) { /* ERROR: File type unknown or unsupported! */ dk3app_log_i1(app, DK3_LL_ERROR, 257); } } } #line 2108 "dk3bif.ctr" return back; } dk3_bif_t * dk3bif_open_file_app(FILE *fipo, int tp, dk3_app_t *app) { char fnb[128]; dk3_bif_t *back = NULL; int ok = 0; int mytp; #line 2121 "dk3bif.ctr" mytp = dk3bif_correct_type(tp); if((fipo) && (app) && (mytp != DK3_BIF_IMAGE_TYPE_UNKNOWN)) { if(dk3bif_type_supported(mytp)) { back = dk3bif_allocate_app(mytp, app); if(back) { dk3bif_create_tmpfilename(fnb, back); back->tmpfn = dk3str_c8_dup_app(fnb, NULL); if(back->tmpfn) { back->remtmpf = 1; if(dk3bif_copy_to_temp(back, fipo, app)) { ok = dk3bif_read_header(back); } } if(!(ok)) { dk3bif_close(back); back = NULL; } } } else { /* ERROR: Unknown/unsupported file type! */ if(app) { dk3app_log_i1(app, DK3_LL_ERROR, 257); } } } #line 2145 "dk3bif.ctr" return back; } void dk3bif_close(dk3_bif_t *bp) { dk3_bif_frame_t *fp; #line 2155 "dk3bif.ctr" if(bp) { /* Release image type specific data per frame. */ if(bp->s_frames) { if(bp->i_frames) { dk3sto_it_reset(bp->i_frames); while((fp = (dk3_bif_frame_t *)dk3sto_it_next(bp->i_frames)) != NULL) { /* Close and delete frame. */ dk3bif_frame_delete(fp, bp->bt); } dk3sto_it_close(bp->i_frames); } dk3sto_close(bp->s_frames); } bp->s_frames = NULL; bp->i_frames = NULL; bp->cf = NULL; /* Release image type specific data for file. */ if(bp->implspec) { switch(bp->bt) { case DK3_BIF_IMAGE_TYPE_PNG: { #if DK3_HAVE_PNG_H dk3bif_release_implspec_png(bp->implspec); #endif } break; case DK3_BIF_IMAGE_TYPE_JPEG: { #if DK3_HAVE_JPEGLIB_H dk3bif_release_implspec_jpeg(bp->implspec); #endif } break; case DK3_BIF_IMAGE_TYPE_TIFF: { #if DK3_HAVE_TIFF_H dk3bif_release_implspec_tiff(bp->implspec); #endif } break; } } bp->implspec = NULL; bp->n = 0UL; bp->n_frames = 0; bp->bits = 0; bp->bt = DK3_BIF_IMAGE_TYPE_UNKNOWN; /* Close file if open. */ if(bp->tmpfipo) { #line 2202 "dk3bif.ctr" fclose(bp->tmpfipo); bp->tmpfipo = NULL; } /* Delete file and release file name memory. */ if(bp->tmpfn) { #line 2208 "dk3bif.ctr" if(bp->remtmpf) { dk3sf_c8_remove_file_app(bp->tmpfn, bp->app); } dk3_release(bp->tmpfn); } bp->app = NULL; dk3_delete(bp); } #line 2216 "dk3bif.ctr" } int dk3bif_check_suffix_without_dot(dkChar const *sn) { int back = DK3_BIF_IMAGE_TYPE_UNKNOWN; int tp = -1; #line 2226 "dk3bif.ctr" if(sn) { tp = dk3str_array_index(dk3bif_dk_type_names, sn, 0); #line 2228 "dk3bif.ctr" switch(tp) { case 0: { #line 2230 "dk3bif.ctr" back = DK3_BIF_IMAGE_TYPE_PNG; } break; case 1: case 2: { #line 2233 "dk3bif.ctr" back = DK3_BIF_IMAGE_TYPE_JPEG; } break; case 3: case 4: { #line 2236 "dk3bif.ctr" back = DK3_BIF_IMAGE_TYPE_TIFF; } break; } } #line 2240 "dk3bif.ctr" return back; } int dk3bif_check_c8_suffix_without_dot(char const *sn) { int back = DK3_BIF_IMAGE_TYPE_UNKNOWN; int tp = -1; if(sn) { tp = dk3str_c8_array_index(dk3bif_c8_type_names, sn, 0); switch(tp) { case 0: { back = DK3_BIF_IMAGE_TYPE_PNG; } break; case 1: case 2: { back = DK3_BIF_IMAGE_TYPE_JPEG; } break; case 3: case 4: { back = DK3_BIF_IMAGE_TYPE_TIFF; } break; } } return back; } int dk3bif_check_file_name(dkChar const *fn) { int back = DK3_BIF_IMAGE_TYPE_UNKNOWN; dkChar const *sp; #line 2269 "dk3bif.ctr" if(fn) { sp = dk3str_get_suffix(fn); if(sp) { sp++; back = dk3bif_check_suffix_without_dot(sp); } } #line 2276 "dk3bif.ctr" return back; } int dk3bif_check_c8_file_name(char const *fn) { int back = DK3_BIF_IMAGE_TYPE_UNKNOWN; char const *sp; if(fn) { sp = dk3str_c8_get_suffix(fn); if(sp) { sp++; back = dk3bif_check_c8_suffix_without_dot(sp); } } return back; } /** Transfer background color from image to frame. @param bp Bitmap image file (source). @param fr Frame (destination). */ void dk3_bif_transfer_background(dk3_bif_t *bp, dk3_bif_frame_t *fr) { dk3_pixel_resample_t pixre; dk3pixre_set(&pixre, 8, fr->bits); fr->bgr = dk3pixre_convert(&pixre, bp->bgr); fr->bgg = dk3pixre_convert(&pixre, bp->bgg); fr->bgb = dk3pixre_convert(&pixre, bp->bgb); } int dk3bif_read_data(dk3_bif_t *bp) { int back = 0; dk3_bif_frame_t *fr = NULL; #line 2321 "dk3bif.ctr" if(bp) { switch(bp->bt) { case DK3_BIF_IMAGE_TYPE_PNG: { #if DK3_HAVE_PNG_H back = dk3bif_read_png_data(bp); #endif } break; case DK3_BIF_IMAGE_TYPE_JPEG: { #if DK3_HAVE_JPEGLIB_H #line 2331 "dk3bif.ctr" back = dk3bif_read_jpeg_data(bp); #line 2333 "dk3bif.ctr" #endif } break; case DK3_BIF_IMAGE_TYPE_TIFF: { #if DK3_HAVE_TIFF_H back = dk3bif_read_tiff_data(bp); #endif } break; } } if(back) { dk3sto_it_reset(bp->i_frames); while((fr = (dk3_bif_frame_t *)dk3sto_it_next(bp->i_frames)) != NULL) { /* The following settings are overwritten by dk3bif_analyze(). */ switch(fr->cs) { case DK3_COLOR_SPACE_GRAY: case DK3_COLOR_SPACE_GRAY_ALPHA: { fr->realcolor = 0; } break; default: { fr->realcolor = 1; } break; } switch(fr->cs) { case DK3_COLOR_SPACE_GRAY_ALPHA: case DK3_COLOR_SPACE_RGBA: { fr->realalpha = 1; } break; default: { fr->realalpha = 0; } break; } fr->realbits = fr->bits; /* Obtain background color from per-file settings. */ if((!(fr->bg)) || (bp->bg)) { dk3_bif_transfer_background(bp, fr); } fr->bggr = dk3bif_ntsc(fr->bgr, fr->bgg, fr->bgb); } dk3sto_it_reset(bp->i_frames); bp->cf = (dk3_bif_frame_t *)dk3sto_it_next(bp->i_frames); if(!(bp->cf)) { back = 0; } } dk3bif_set_pixel_sampling(bp); #line 2385 "dk3bif.ctr" return back; } size_t dk3bif_number_of_frames(dk3_bif_t *bp) { size_t back = 0; #line 2395 "dk3bif.ctr" if(bp) { back = bp->n_frames; } #line 2398 "dk3bif.ctr" return back; } int dk3bif_set_frame(dk3_bif_t *bp, size_t fn) { int back = 0; #line 2408 "dk3bif.ctr" if(bp) { bp->cf = (dk3_bif_frame_t *)dk3sto_it_find_like(bp->i_frames, (void *)(&fn), 1); if(bp->cf) { back = 1; dk3bif_set_pixel_sampling(bp); } else { dk3sto_it_reset(bp->i_frames); } } #line 2418 "dk3bif.ctr" return back; } size_t dk3bif_get_bits_per_pixel(dk3_bif_t *bp) { size_t back = 0; #line 2428 "dk3bif.ctr" if(bp) { if(bp->cf) { back = (bp->cf)->bits; } } #line 2433 "dk3bif.ctr" return back; } size_t dk3bif_real_bits_per_pixel(dk3_bif_t *bp) { size_t back = 0; #line 2443 "dk3bif.ctr" if(bp) { if(bp->cf) { back = (bp->cf)->realbits; } } #line 2448 "dk3bif.ctr" return back; } int dk3bif_real_color(dk3_bif_t *bp) { int back = 0; if(bp) { if(bp->cf) { back = (bp->cf)->realcolor; } } return back; } int dk3bif_real_alpha(dk3_bif_t *bp) { int back = 0; if(bp) { if(bp->cf) { back = (bp->cf)->realalpha; } } return back; } int dk3bif_set_bits_per_pixel(dk3_bif_t *bp, size_t sz) { int back = 0; #line 2486 "dk3bif.ctr" if((bp) && (sz)) { if(sz < 17) { bp->bits = sz; dk3bif_set_pixel_sampling(bp); back = 1; } else { bp->bits = 16; dk3bif_set_pixel_sampling(bp); /* Maximum number of bits exceeded! */ if(bp->app) { dk3app_log_i1(bp->app, DK3_LL_WARNING, 258); } } } #line 2500 "dk3bif.ctr" return back; } dk3_bif_coord_t dk3bif_get_width(dk3_bif_t *bp) { dk3_bif_coord_t back = 0L; #line 2510 "dk3bif.ctr" if(bp) { if(bp->cf) { back = (bp->cf)->w; } } #line 2515 "dk3bif.ctr" return back; } dk3_bif_coord_t dk3bif_get_height(dk3_bif_t *bp) { dk3_bif_coord_t back = 0L; #line 2525 "dk3bif.ctr" if(bp) { if(bp->cf) { back = (bp->cf)->h; } } #line 2530 "dk3bif.ctr" return back; } dk3_bif_coord_t dk3bif_get_largest_width(dk3_bif_t *bp) { dk3_bif_frame_t *fp; dk3_bif_coord_t back = 0L; #line 2541 "dk3bif.ctr" if(bp) { dk3sto_it_reset(bp->i_frames); while((fp = (dk3_bif_frame_t *)dk3sto_it_next(bp->i_frames)) != NULL) { if(fp->w > back) { back = fp->w; } } } #line 2547 "dk3bif.ctr" return back; } dk3_bif_coord_t dk3bif_get_largest_height(dk3_bif_t *bp) { dk3_bif_frame_t *fp; dk3_bif_coord_t back = 0L; #line 2558 "dk3bif.ctr" if(bp) { dk3sto_it_reset(bp->i_frames); while((fp = (dk3_bif_frame_t *)dk3sto_it_next(bp->i_frames)) != NULL) { if(fp->h > back) { back = fp->h; } } } #line 2565 "dk3bif.ctr" return back; } dk3_bif_pixel_t dk3bif_get_red(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y) { dk3_bif_pixel_t back = (dk3_bif_pixel_t)0; #line 2575 "dk3bif.ctr" if(bp) { if(bp->cf) { switch((bp->cf)->cs) { case DK3_COLOR_SPACE_GRAY: case DK3_COLOR_SPACE_GRAY_ALPHA: { back = dk3bif_get_pixel_component(bp, x, y, 0); } break; case DK3_COLOR_SPACE_RGB: case DK3_COLOR_SPACE_RGBA: { back = dk3bif_get_pixel_component(bp, x, y, 0); } break; } } } #line 2591 "dk3bif.ctr" return back; } dk3_bif_pixel_t dk3bif_get_green(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y) { dk3_bif_pixel_t back = (dk3_bif_pixel_t)0; #line 2601 "dk3bif.ctr" if(bp) { if(bp->cf) { switch((bp->cf)->cs) { case DK3_COLOR_SPACE_GRAY: case DK3_COLOR_SPACE_GRAY_ALPHA: { back = dk3bif_get_pixel_component(bp, x, y, 0); } break; case DK3_COLOR_SPACE_RGB: case DK3_COLOR_SPACE_RGBA: { back = dk3bif_get_pixel_component(bp, x, y, 1); } break; } } } #line 2617 "dk3bif.ctr" return back; } dk3_bif_pixel_t dk3bif_get_blue(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y) { dk3_bif_pixel_t back = (dk3_bif_pixel_t)0; #line 2627 "dk3bif.ctr" if(bp) { if(bp->cf) { switch((bp->cf)->cs) { case DK3_COLOR_SPACE_GRAY: case DK3_COLOR_SPACE_GRAY_ALPHA: { back = dk3bif_get_pixel_component(bp, x, y, 0); } break; case DK3_COLOR_SPACE_RGB: case DK3_COLOR_SPACE_RGBA: { back = dk3bif_get_pixel_component(bp, x, y, 2); } break; } } } #line 2643 "dk3bif.ctr" return back; } dk3_bif_pixel_t dk3bif_get_gray(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y) { dk3_bif_pixel_t back = (dk3_bif_pixel_t)0; #line 2653 "dk3bif.ctr" if(bp) { if(bp->cf) { switch((bp->cf)->cs) { case DK3_COLOR_SPACE_GRAY: case DK3_COLOR_SPACE_GRAY_ALPHA: { back = dk3bif_get_pixel_component(bp, x, y, 0); } break; case DK3_COLOR_SPACE_RGB: case DK3_COLOR_SPACE_RGBA: { back = dk3bif_ntsc( dk3bif_get_pixel_component(bp, x, y, 0), dk3bif_get_pixel_component(bp, x, y, 1), dk3bif_get_pixel_component(bp, x, y, 2) ); back &= dk3pixre_get_max_value(&(bp->pr)); #line 2671 "dk3bif.ctr" } break; } } } #line 2675 "dk3bif.ctr" return back; } dk3_bif_pixel_t dk3bif_get_alpha(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y) { dk3_bif_pixel_t back = (dk3_bif_pixel_t)0; #line 2685 "dk3bif.ctr" if(bp) { back = dk3pixre_get_max_value(&(bp->pr)); if(bp->cf) { switch((bp->cf)->cs) { case DK3_COLOR_SPACE_GRAY_ALPHA: case DK3_COLOR_SPACE_RGBA: { back = dk3bif_get_pixel_component(bp, x, y, 3); } break; default: { if((x >= 0L) && (x < (bp->cf)->w)) { if((y >= 0L) && (y < (bp->cf)->h)) { back = dk3pixre_get_max_value(&(bp->pr)); } } } break; } } } #line 2704 "dk3bif.ctr" return back; } /** Mix pixel value against background value. @param v Pixel value. @param w Background value. @param a Alpha channel value (opacity). @param m Maximum alpha value. @return Mixing result. */ static dk3_bif_pixel_t dk3bif_mix( dk3_bif_pixel_t v, dk3_bif_pixel_t w, dk3_bif_pixel_t a, dk3_bif_pixel_t m ) { unsigned long l1, l2, l3, l4, l5, l6; dk3_bif_pixel_t back; dk3_bif_pixel_t b; int me = 0; back = v; b = m - a; l1 = (unsigned long)v; l2 = (unsigned long)a; l3 = (unsigned long)w; l4 = (unsigned long)b; l5 = (unsigned long)m; l6 = dk3ma_ul_div_ok( dk3ma_ul_add_ok( dk3ma_ul_mul_ok(l1, l2, &me), dk3ma_ul_mul_ok(l3, l4, &me), &me ), l5, &me ); if(me == 0) { back = (((dk3_bif_pixel_t)l6) & m); } return back; } dk3_bif_pixel_t dk3bif_get_mixed_red(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y) { dk3_bif_pixel_t back = 0U; #line 2759 "dk3bif.ctr" back = dk3bif_get_red(bp, x, y); if(bp->cf) { switch((bp->cf)->cs) { case DK3_COLOR_SPACE_GRAY_ALPHA: case DK3_COLOR_SPACE_RGBA: { back = dk3bif_mix( back, (bp->cf)->bgr, dk3bif_get_alpha(bp, x, y), dk3pixre_get_max_value(&(bp->pr)) ); } break; } } #line 2772 "dk3bif.ctr" return back; } dk3_bif_pixel_t dk3bif_get_mixed_green(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y) { dk3_bif_pixel_t back = 0U; #line 2782 "dk3bif.ctr" back = dk3bif_get_green(bp, x, y); if(bp->cf) { switch((bp->cf)->cs) { case DK3_COLOR_SPACE_GRAY_ALPHA: case DK3_COLOR_SPACE_RGBA: { back = dk3bif_mix( back, (bp->cf)->bgg, dk3bif_get_alpha(bp, x, y), dk3pixre_get_max_value(&(bp->pr)) ); } break; } } #line 2795 "dk3bif.ctr" return back; } dk3_bif_pixel_t dk3bif_get_mixed_blue(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y) { dk3_bif_pixel_t back = 0U; #line 2805 "dk3bif.ctr" back = dk3bif_get_blue(bp, x, y); if(bp->cf) { switch((bp->cf)->cs) { case DK3_COLOR_SPACE_GRAY_ALPHA: case DK3_COLOR_SPACE_RGBA: { back = dk3bif_mix( back, (bp->cf)->bgb, dk3bif_get_alpha(bp, x, y), dk3pixre_get_max_value(&(bp->pr)) ); } break; } } #line 2818 "dk3bif.ctr" return back; } dk3_bif_pixel_t dk3bif_get_mixed_gray(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y) { dk3_bif_pixel_t back = 0U; #line 2828 "dk3bif.ctr" back = dk3bif_get_gray(bp, x, y); if(bp->cf) { switch((bp->cf)->cs) { case DK3_COLOR_SPACE_GRAY_ALPHA: case DK3_COLOR_SPACE_RGBA: { #line 2832 "dk3bif.ctr" back = dk3bif_mix( back, (bp->cf)->bggr, dk3bif_get_alpha(bp, x, y), dk3pixre_get_max_value(&(bp->pr)) ); } break; } } #line 2841 "dk3bif.ctr" return back; } int dk3bif_type_supported(int tp) { int back = 0; #line 2851 "dk3bif.ctr" switch(tp) { case DK3_BIF_IMAGE_TYPE_PNG: { #if DK3_HAVE_PNG_H back = 1; #endif } break; case DK3_BIF_IMAGE_TYPE_JPEG: { #if DK3_HAVE_JPEGLIB_H back = 1; #endif } break; case DK3_BIF_IMAGE_TYPE_TIFF: { #if DK3_HAVE_TIFF_H back = 1; #endif } break; } #line 2868 "dk3bif.ctr" return back; } FILE * dk3bif_get_file(dk3_bif_t *bp) { FILE *back = NULL; #line 2878 "dk3bif.ctr" if(bp) { back = bp->tmpfipo; } #line 2881 "dk3bif.ctr" return back; } int dk3bif_is_colored(dk3_bif_t *bp) { int back = 0; dk3_bif_coord_t x; dk3_bif_coord_t y; dk3_bif_pixel_t r; dk3_bif_pixel_t g; dk3_bif_pixel_t b; if(bp) { if(bp->cf) { switch((bp->cf)->cs) { case DK3_COLOR_SPACE_RGB: case DK3_COLOR_SPACE_RGBA: { for(y = 0L; (y < (bp->cf)->h) && (back == 0); y++) { for(x = 0L; (x < (bp->cf)->w) && (back == 0); x++) { r = dk3bif_get_red(bp, x, y); g = dk3bif_get_green(bp, x, y); b = dk3bif_get_blue(bp, x, y); if(r != g) { back = 1; } if(r != b) { back = 1; } } } } break; } } } return back; } double dk3bif_get_xres(dk3_bif_t *bp) { double back = -1.0; #line 2924 "dk3bif.ctr" if(bp) { if(bp->cf) { back = (bp->cf)->xres; } } #line 2929 "dk3bif.ctr" return back; } double dk3bif_get_yres(dk3_bif_t *bp) { double back = -1.0; #line 2939 "dk3bif.ctr" if(bp) { if(bp->cf) { back = (bp->cf)->yres; } } #line 2944 "dk3bif.ctr" return back; } int dk3bif_next_frame(dk3_bif_t *bp) { int back = 0; if(bp) { if(bp->i_frames) { bp->cf = (dk3_bif_frame_t *)dk3sto_it_next(bp->i_frames); if(bp->cf) { back = 1; dk3bif_set_pixel_sampling(bp); } } } return back; } void dk3bif_reset_frames(dk3_bif_t *bp) { if(bp) { bp->cf = NULL; dk3sto_it_reset(bp->i_frames); } } void dk3bif_set_background( dk3_bif_t *bp, dk3_bif_pixel_t r, dk3_bif_pixel_t g, dk3_bif_pixel_t b, int f ) { if(bp) { bp->bgr = r; bp->bgg = g; bp->bgb = b; bp->bg = (f ? 1 : 0); } } int dk3bif_get_color_space(dk3_bif_t *bp) { int back = 0; if(bp) { if(bp->cf) { back = (bp->cf)->cs; } } return back; } int dk3bif_get_type(dk3_bif_t *bp) { int back = DK3_BIF_IMAGE_TYPE_UNKNOWN; if(bp) { back = bp->bt; } return back; } #line 3021 "dk3bif.ctr" int dk3bif_jpeg_get_num_components(dk3_bif_t *bif) { int back = 0; #if DK3_HAVE_JPEGLIB_H dk3_bif_frame_jpeg_t *jpf; #line 3029 "dk3bif.ctr" if(bif) { #line 3030 "dk3bif.ctr" if(bif->cf) { #line 3031 "dk3bif.ctr" if(bif->bt == DK3_BIF_IMAGE_TYPE_JPEG) { #line 3032 "dk3bif.ctr" jpf = (dk3_bif_frame_jpeg_t *)((bif->cf)->implspec); if(jpf) { #line 3034 "dk3bif.ctr" back = jpf->num_comp; } else { #line 3036 "dk3bif.ctr" } } else { #line 3038 "dk3bif.ctr" } } else { #line 3040 "dk3bif.ctr" } } else { #line 3042 "dk3bif.ctr" } #line 3043 "dk3bif.ctr" #endif return back; } #line 3048 "dk3bif.ctr" int dk3bif_jpeg_get_found_adobe_marker(dk3_bif_t *bif) { int back = 0; #if DK3_HAVE_JPEGLIB_H dk3_bif_frame_jpeg_t *jpf; if(bif) { if(bif->cf) { if(bif->bt == DK3_BIF_IMAGE_TYPE_JPEG) { jpf = (dk3_bif_frame_jpeg_t *)((bif->cf)->implspec); if(jpf) { back = jpf->is_adobe; } } } } #endif return back; } dk3_bif_pixel_t dk3bif_average(dk3_bif_pixel_t left, dk3_bif_pixel_t upper) { dk3_bif_pixel_t back; long x; x = (long)left + (long)upper; x = x / 2; back = (dk3_bif_pixel_t)x; return back; } dk3_bif_pixel_t dk3bif_paeth( dk3_bif_pixel_t v1, dk3_bif_pixel_t v2, dk3_bif_pixel_t v3 ) { dk3_bif_pixel_t back; long p, pa, pb, pc; p = (long)v1 + (long)v2 - (long)v3; pa = p - (long)v1; pb = p - (long)v2; pc = p - (long)v3; if(pa < 0) { pa = 0L - pa; } if(pb < 0) { pb = 0L - pb; } if(pc < 0) { pc = 0L - pc; } if((pa <= pb) && (pa <= pc)) { back = v1; } else { if(pb <= pc) { back = v2; } else { back = v3; } } return back; } /* vim: set ai sw=2 : */