/* Copyright (C) 2011-2020, Dirk Krause SPDX-License-Identifier: BSD-3-Clause */ /* WARNING: This file was generated by the dkct program (see http://dktools.sourceforge.net/ for details). 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 */ /** @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; #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 553 "dk3bif.ctr" fdis = (dk3_bif_frame_png_t *)is; if(fdis->rows) { #line 555 "dk3bif.ctr" for(i = 0L; i < fdis->h; i++) { #line 556 "dk3bif.ctr" dk3_delete((fdis->rows)[i]); } dk3_delete(fdis->rows); } dk3_release(fdis); #line 562 "dk3bif.ctr" } #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); } #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); } #endif /* if DK3_HAVE_TIFF_H */ /** 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 703 "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 736 "dk3bif.ctr" } #if (DK3_HAVE_PNG_H) || (DK3_HAVE_JPEGLIB_H) || (DK3_HAVE_TIFF_H) /** 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; } #endif #if DK3_HAVE_PNG_H /** 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 788 "dk3bif.ctr" dis = (dk3_bif_png_t *)is; if(dis->pp) { if(dis->pi) { #line 791 "dk3bif.ctr" png_destroy_info_struct(dis->pp, &(dis->pi)); } #line 793 "dk3bif.ctr" png_destroy_read_struct(&(dis->pp), (png_infopp)NULL, (png_infopp)NULL); } dis->pp = NULL; dis->pi = NULL; dk3_release(dis); #line 798 "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. */ volatile int np = 1; /* Number of interlace passes. */ size_t szh; /* Number of header bytes read. */ int back = 0; #line 832 "dk3bif.ctr" szh = fread(header, 1, 8, bp->tmpfipo); if(szh > 0) { #line 834 "dk3bif.ctr" if(png_sig_cmp(header, 0, szh) == 0) { dis = dk3_new_app(dk3_bif_png_t,1,bp->app); if(dis) { #line 837 "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 846 "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 851 "dk3bif.ctr" bp->cf = dk3bif_frame_new(bp); if(bp->cf) { #line 853 "dk3bif.ctr" fdis = dk3_new_app(dk3_bif_frame_png_t,1,bp->app); if(fdis) { #line 855 "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 880 "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 920 "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 960 "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 993 "dk3bif.ctr" } } else { #line 995 "dk3bif.ctr" } } else { #line 997 "dk3bif.ctr" } #if DK3_HAVE_SETJMP_H } else { back = 0; } #endif } else { #line 1004 "dk3bif.ctr" } } else { #line 1006 "dk3bif.ctr" } } else { #line 1008 "dk3bif.ctr" } } else { #line 1010 "dk3bif.ctr" } #line 1012 "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; volatile 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 1057 "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 1067 "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_JPEGLIB_H /** 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 1186 "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 1211 "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 1219 "dk3bif.ctr" (bp->cf)->cs = DK3_COLOR_SPACE_GRAY; } break; case JCS_RGB: { #line 1222 "dk3bif.ctr" (bp->cf)->cs = DK3_COLOR_SPACE_RGB; } break; case JCS_CMYK: { #line 1225 "dk3bif.ctr" (bp->cf)->cs = DK3_COLOR_SPACE_CMYK; } break; case JCS_YCCK: { #line 1228 "dk3bif.ctr" (bp->cf)->cs = DK3_COLOR_SPACE_CMYK; } break; case JCS_YCbCr: { #line 1231 "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 1266 "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 1285 "dk3bif.ctr" if(bp->implspec) { #line 1286 "dk3bif.ctr" if(bp->cf) { #line 1287 "dk3bif.ctr" if((bp->cf)->implspec) { #line 1288 "dk3bif.ctr" dis = (dk3_bif_jpeg_t *)(bp->implspec); fdis = (dk3_bif_frame_jpeg_t *)((bp->cf)->implspec); #line 1290 "dk3bif.ctr" if(dis->st == 3) { #line 1291 "dk3bif.ctr" #if DK3_HAVE_SETJMP_H if(setjmp((dis->errmgr).setjmp_buffer) == 0) { #line 1293 "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 1299 "dk3bif.ctr" occ = (dis->cinfo).out_color_components; ok = 1; #line 1301 "dk3bif.ctr" rp = fdis->rows; #line 1302 "dk3bif.ctr" for(y = 0; y < fdis->h; y++) { *(rp++) = NULL; } occ = occ * fdis->w; #line 1304 "dk3bif.ctr" rp = fdis->rows; for(y = 0; y < fdis->h; y++) { #line 1306 "dk3bif.ctr" *rp = dk3_new_app(JSAMPLE,occ,bp->app); if(!(*rp)) { ok = 0; #line 1309 "dk3bif.ctr" } rp++; } if(ok) { #line 1313 "dk3bif.ctr" dis->st = 6; /* Decompression started. */ rp = fdis->rows; #line 1315 "dk3bif.ctr" for(y = 0; y < fdis->h; y++) { #line 1316 "dk3bif.ctr" jpeg_read_scanlines(&(dis->cinfo), rp, 1); rp++; #line 1318 "dk3bif.ctr" } #line 1319 "dk3bif.ctr" dis->st = 7; /* Data was read successfully. */ jpeg_finish_decompress(&(dis->cinfo)); #line 1321 "dk3bif.ctr" dis->st = 8; /* Decompression finished. */ switch((dis->cinfo).out_color_space) { case JCS_GRAYSCALE: { #line 1324 "dk3bif.ctr" (bp->cf)->cs = DK3_COLOR_SPACE_GRAY; back = 1; } break; case JCS_RGB: { #line 1328 "dk3bif.ctr" (bp->cf)->cs = DK3_COLOR_SPACE_RGB; back = 1; } break; default: { (bp->cf)->cs = 0; } break; } } else { } } else { #line 1338 "dk3bif.ctr" } #if DK3_HAVE_SETJMP_H } else { } #endif } else { #line 1344 "dk3bif.ctr" } } else { #line 1346 "dk3bif.ctr" } } else { #line 1348 "dk3bif.ctr" } } #line 1350 "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_TIFF_H /** 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 1473 "dk3bif.ctr" if(bp->tmpfn) { #line 1474 "dk3bif.ctr" dis = dk3_new_app(dk3_bif_tiff_t,1,bp->app); if(dis) { #line 1476 "dk3bif.ctr" /* Initialization of TIFF per file. */ bp->implspec = (void *)dis; dis->tiff = NULL; dis->tiff = TIFFOpen(bp->tmpfn, "rb"); if(dis->tiff) { #line 1483 "dk3bif.ctr" back = 1; do { #line 1485 "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 1491 "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 1495 "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 1504 "dk3bif.ctr" (bp->cf)->w = (dk3_bif_coord_t)w; if(TIFFGetField(dis->tiff, TIFFTAG_IMAGELENGTH, &h) == 1) { fdis->h = h; #line 1507 "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 1511 "dk3bif.ctr" } rv = 0.0; if(TIFFGetField(dis->tiff, TIFFTAG_YRESOLUTION, &rv) == 1) { (bp->cf)->yres = (double)rv; #line 1515 "dk3bif.ctr" } ru = 0; if(TIFFGetField(dis->tiff, TIFFTAG_RESOLUTIONUNIT, &ru) == 1) { #line 1519 "dk3bif.ctr" switch(ru) { case RESUNIT_CENTIMETER: { #line 1521 "dk3bif.ctr" (bp->cf)->xres = 2.54 * (bp->cf)->xres; (bp->cf)->yres = 2.54 * (bp->cf)->yres; } break; case RESUNIT_NONE: { #line 1525 "dk3bif.ctr" (bp->cf)->xres = (bp->cf)->yres = -1.0; } break; } } orient = ORIENTATION_TOPLEFT; if(TIFFGetFieldDefaulted( dis->tiff, TIFFTAG_ORIENTATION, &orient ) == 1 ) { #line 1535 "dk3bif.ctr" fdis->ori = orient; switch(orient) { case 5: case 6: case 7: case 8: { #line 1538 "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 1559 "dk3bif.ctr" } else { #line 1560 "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 1568 "dk3bif.ctr" fdis->r = (uint32 *)_TIFFmalloc(sz); if(fdis->r) { #line 1570 "dk3bif.ctr" if(TIFFReadRGBAImageOriented( dis->tiff, w, h, fdis->r, orient, 0 ) ) { #if TRACE_DEBUG || VERSION_BEFORE_20150821 back = 1; #line 1577 "dk3bif.ctr" #endif } else { #line 1579 "dk3bif.ctr" back = 0; } } else { #line 1582 "dk3bif.ctr" back = 0; } } else { back = 0; #line 1586 "dk3bif.ctr" } } } else { #line 1589 "dk3bif.ctr" back = 0; } } else { #line 1592 "dk3bif.ctr" back = 0; } } else { back = 0; #line 1596 "dk3bif.ctr" } } else { back = 0; #line 1599 "dk3bif.ctr" } w = h = 0UL; #if VERSION_BEFORE_20150821 cps = spp = 0U; #endif #line 1605 "dk3bif.ctr" } while((back == 1) && TIFFReadDirectory(dis->tiff)); TIFFClose(dis->tiff); dis->tiff = NULL; #line 1607 "dk3bif.ctr" if(bp->i_frames) { #line 1608 "dk3bif.ctr" dk3sto_it_reset(bp->i_frames); bp->cf = (dk3_bif_frame_t *)dk3sto_it_next(bp->i_frames); if(!(bp->cf)) { #line 1611 "dk3bif.ctr" back = 0; } } else { #line 1614 "dk3bif.ctr" } } else { #line 1616 "dk3bif.ctr" } } else { #line 1618 "dk3bif.ctr" } } else { #line 1620 "dk3bif.ctr" } #line 1621 "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 /** 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; } 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 1735 "dk3bif.ctr" if(c == 3) { #line 1736 "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 1760 "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 1783 "dk3bif.ctr" /* Get unresampled value. */ back = dk3bif_get_pixel_component_not_resampled(bp, x, y, c); /* Resample value to requested output bit size. */ #line 1791 "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 1856 "dk3bif.ctr" if(bp) { if(bp->cf) { if(bp->bits) { #line 1859 "dk3bif.ctr" dk3pixre_set(&(bp->pr), (bp->cf)->bits, bp->bits); } else { #line 1861 "dk3bif.ctr" dk3pixre_set(&(bp->pr), (bp->cf)->bits, (bp->cf)->bits); } } } #line 1866 "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 1882 "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 1914 "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 1930 "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 1949 "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 1963 "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 1975 "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 1996 "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 2020 "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 2037 "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 2045 "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 2059 "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 2101 "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 2112 "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 2145 "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 2158 "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 2182 "dk3bif.ctr" return back; } void dk3bif_close(dk3_bif_t *bp) { dk3_bif_frame_t *fp; #line 2192 "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 2239 "dk3bif.ctr" fclose(bp->tmpfipo); bp->tmpfipo = NULL; } /* Delete file and release file name memory. */ if(bp->tmpfn) { #line 2245 "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 2253 "dk3bif.ctr" } int dk3bif_check_suffix_without_dot(dkChar const *sn) { int back = DK3_BIF_IMAGE_TYPE_UNKNOWN; int tp = -1; #line 2263 "dk3bif.ctr" if(sn) { tp = dk3str_array_index(dk3bif_dk_type_names, sn, 0); #line 2265 "dk3bif.ctr" switch(tp) { case 0: { #line 2267 "dk3bif.ctr" back = DK3_BIF_IMAGE_TYPE_PNG; } break; case 1: case 2: { #line 2270 "dk3bif.ctr" back = DK3_BIF_IMAGE_TYPE_JPEG; } break; case 3: case 4: { #line 2273 "dk3bif.ctr" back = DK3_BIF_IMAGE_TYPE_TIFF; } break; } } #line 2277 "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 2306 "dk3bif.ctr" if(fn) { sp = dk3str_get_suffix(fn); if(sp) { sp++; back = dk3bif_check_suffix_without_dot(sp); } } #line 2313 "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). */ static 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 2358 "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 2368 "dk3bif.ctr" back = dk3bif_read_jpeg_data(bp); #line 2370 "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 2422 "dk3bif.ctr" return back; } size_t dk3bif_number_of_frames(dk3_bif_t *bp) { size_t back = 0; #line 2432 "dk3bif.ctr" if(bp) { back = bp->n_frames; } #line 2435 "dk3bif.ctr" return back; } int dk3bif_set_frame(dk3_bif_t *bp, size_t fn) { int back = 0; #line 2445 "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 2455 "dk3bif.ctr" return back; } size_t dk3bif_get_bits_per_pixel(dk3_bif_t *bp) { size_t back = 0; #line 2465 "dk3bif.ctr" if(bp) { if(bp->cf) { back = (bp->cf)->bits; } } #line 2470 "dk3bif.ctr" return back; } size_t dk3bif_real_bits_per_pixel(dk3_bif_t *bp) { size_t back = 0; #line 2480 "dk3bif.ctr" if(bp) { if(bp->cf) { back = (bp->cf)->realbits; } } #line 2485 "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 2523 "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 2537 "dk3bif.ctr" return back; } dk3_bif_coord_t dk3bif_get_width(dk3_bif_t *bp) { dk3_bif_coord_t back = 0L; #line 2547 "dk3bif.ctr" if(bp) { if(bp->cf) { back = (bp->cf)->w; } } #line 2552 "dk3bif.ctr" return back; } dk3_bif_coord_t dk3bif_get_height(dk3_bif_t *bp) { dk3_bif_coord_t back = 0L; #line 2562 "dk3bif.ctr" if(bp) { if(bp->cf) { back = (bp->cf)->h; } } #line 2567 "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 2578 "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 2584 "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 2595 "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 2602 "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 2612 "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 2628 "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 2638 "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 2654 "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 2664 "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 2680 "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 2690 "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 2708 "dk3bif.ctr" } break; } } } #line 2712 "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 2722 "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 2741 "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 2796 "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 2809 "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 2819 "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 2832 "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 2842 "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 2855 "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 2865 "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 2869 "dk3bif.ctr" back = dk3bif_mix( back, (bp->cf)->bggr, dk3bif_get_alpha(bp, x, y), dk3pixre_get_max_value(&(bp->pr)) ); } break; } } #line 2878 "dk3bif.ctr" return back; } int dk3bif_type_supported(int tp) { int back = 0; #line 2888 "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 2905 "dk3bif.ctr" return back; } FILE * dk3bif_get_file(dk3_bif_t *bp) { FILE *back = NULL; #line 2915 "dk3bif.ctr" if(bp) { back = bp->tmpfipo; } #line 2918 "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 2961 "dk3bif.ctr" if(bp) { if(bp->cf) { back = (bp->cf)->xres; } } #line 2966 "dk3bif.ctr" return back; } double dk3bif_get_yres(dk3_bif_t *bp) { double back = -1.0; #line 2976 "dk3bif.ctr" if(bp) { if(bp->cf) { back = (bp->cf)->yres; } } #line 2981 "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 3058 "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 3066 "dk3bif.ctr" if(bif) { #line 3067 "dk3bif.ctr" if(bif->cf) { #line 3068 "dk3bif.ctr" if(bif->bt == DK3_BIF_IMAGE_TYPE_JPEG) { #line 3069 "dk3bif.ctr" jpf = (dk3_bif_frame_jpeg_t *)((bif->cf)->implspec); if(jpf) { #line 3071 "dk3bif.ctr" back = jpf->num_comp; } else { #line 3073 "dk3bif.ctr" } } else { #line 3075 "dk3bif.ctr" } } else { #line 3077 "dk3bif.ctr" } } else { #line 3079 "dk3bif.ctr" } #line 3080 "dk3bif.ctr" #endif return back; } #line 3085 "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 : */