diff options
Diffstat (limited to 'support/dktools/dk3bif.ctr')
-rw-r--r-- | support/dktools/dk3bif.ctr | 3115 |
1 files changed, 3115 insertions, 0 deletions
diff --git a/support/dktools/dk3bif.ctr b/support/dktools/dk3bif.ctr new file mode 100644 index 0000000000..afc5e90634 --- /dev/null +++ b/support/dktools/dk3bif.ctr @@ -0,0 +1,3115 @@ +%% options + +copyright owner = Dirk Krause +copyright year = 2011-xxxx +license = bsd + + + +%% header + +#include "dk3conf.h" +#include "dk3types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** Check whether a bitmap image file type is supported. + @param tp File type to check. + @return 1 for supported types, 0 otherwise. +*/ +int +dk3bif_type_supported(int tp); + +/** Check file name suffix (dkChar). + @param sn File name suffix without the dot. + @return Bitmap image file type. +*/ +int +dk3bif_check_suffix_without_dot(dkChar const *sn); + +/** Check file name suffix (char). + @param sn File name suffix without the dot. + @return Bitmap image file type. +*/ +int +dk3bif_check_c8_suffix_without_dot(char const *sn); + +/** Check file name suffix (dkChar). + @param fn File name to check. + @return Bitmap image file type. +*/ +int +dk3bif_check_file_name(dkChar const *fn); + +/** Check file name suffix (char). + @param fn File name to check. + @return Bitmap image file type. +*/ +int +dk3bif_check_c8_file_name(char const *fn); + +/** Open bitmap image file (dkChar). + @param fn File name. + @param tp Bitmap type. + @param app Application structure for diagnostics, may not be NULL. + @return Pointer to BIF on success, NULL on error. +*/ +dk3_bif_t * +dk3bif_open_filename_app(dkChar const *fn, int tp, dk3_app_t *app); + +/** Open bitmap image file (char). + @param fn File name. + @param tp Bitmap type. + @param app Application structure for diagnostics, may not be NULL. + @return Pointer to BIF on success, NULL on error. +*/ +dk3_bif_t * +dk3bif_open_c8_filename_app(char const *fn, int tp, dk3_app_t *app); + +/** Open bitmap image file. + @param fipo File, opened for binary reading. + @param tp Bitmap type. + @param app Application structure for diagnostics, may not be NULL. + @return Pointer to BIF on success, NULL on error. +*/ +dk3_bif_t * +dk3bif_open_file_app(FILE *fipo, int tp, dk3_app_t *app); + +/** Retrieve image type. + @param bp Bitmap image file. + @return Image type, DK3_BIF_IMAGE_TYPE_xxx, see @ref bifimagetypes. +*/ +int +dk3bif_get_type(dk3_bif_t *bp); + +/** Get width of current frame. + @param bp Bitmap image file. + @return Image width. +*/ +dk3_bif_coord_t +dk3bif_get_width(dk3_bif_t *bp); + +/** Get height of current frame. + @param bp Bitmap image file. + @return Image height. +*/ +dk3_bif_coord_t +dk3bif_get_height(dk3_bif_t *bp); + +/** Get width of widest frame. + @param bp Bitmap image file. + @return Image width. +*/ +dk3_bif_coord_t +dk3bif_get_largest_width(dk3_bif_t *bp); + +/** Get height of highest frame. + @param bp Bitmap image file. + @return Image height. +*/ +dk3_bif_coord_t +dk3bif_get_largest_height(dk3_bif_t *bp); + +/** Set background color on per-file base. + Use this function after opening the bitmap image file + but before dk3bif_read_data(). + @param bp Bitmap image file. + @param r Red. + @param g Green. + @param b Blue. + @param f Force flag: 0=use background color chunk + from file if available, 1=always use the color specified here. +*/ +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 +); + +/** Read image data. + @param bp Bitmap image file. + @return 1 on success, 0 on error. +*/ +int +dk3bif_read_data(dk3_bif_t *bp); + +/** Find number of frames in image file. + @param bp Bitmap image file. + @return Number of frames in the file. +*/ +size_t +dk3bif_number_of_frames(dk3_bif_t *bp); + +/** Set current frame number. + @param bp Bitmap image file. + @param fn Number of frame to process. + @return 1 on success, 0 on error. +*/ +int +dk3bif_set_frame(dk3_bif_t *bp, size_t fn); + +/** Reset internal current frame pointer, so the next + dk3bif_next_frame() call returns the first frame. + @param bp Bitmap image file. +*/ +void +dk3bif_reset_frames(dk3_bif_t *bp); + +/** Switch to the next frame. + @param bp Bitmap image file. + @return 1 on success, 0 on error (no more frames). +*/ +int +dk3bif_next_frame(dk3_bif_t *bp); + +/** Check whether a bitmap image is really colored. + @param bp Bitmap image file. + @return 1 for colored image, 0 for grey. +*/ +int +dk3bif_is_colored(dk3_bif_t *bp); + +/** Retrieve number of bits per pixel for current frame. + @param bp Bitmap image file. + @return Number of bits per pixel used in the file. +*/ +size_t +dk3bif_get_bits_per_pixel(dk3_bif_t *bp); + +/** Retrieve number of bits per pixel for current frame + really containing information. + This function returns a useful result only if + dk3bif_analyze() was run with DK3_ANALYSIS_BITS before. + @param bp Bitmap image file. + @return Number of non-redundant bits per pixel. +*/ +size_t +dk3bif_real_bits_per_pixel(dk3_bif_t *bp); + +/** Retrieve information whether colors are really used. + This function returns a useful result only if + dk3bif_analyze() was run with DK3_BIF_ANALYSIS_COLOR before. + @param bp Bitmap image file. + @return 1 for colors, 0 for gray. +*/ +int +dk3bif_real_color(dk3_bif_t *bp); + +/** Retrieve information whether alpha channel is really used. + This function returns a useful result only if + dk3bif_analyze() was run with DK3_BIF_ANALYSIS_ALPHA before. + @param bp Bitmap image file. + @return 1 for alpha channel used, 0 for unused. +*/ +int +dk3bif_real_alpha(dk3_bif_t *bp); + +/** Set number of bits per pixel when retrieving data. + @param bp Bitmap image file. + @param sz Number of bits per pixel. + @return 1 on success, 0 on error. +*/ +int +dk3bif_set_bits_per_pixel(dk3_bif_t *bp, size_t sz); + +/** Get color space. + @param bp Bitmap image file. + @return The color space used by the image. +*/ +int +dk3bif_get_color_space(dk3_bif_t *bp); + +/** Get red component of pixel. + @param bp Bitmap image file. + @param x X coordinate. + @param y Y coordinate. + @return Value corrected to requested bits per component. +*/ +dk3_bif_pixel_t +dk3bif_get_red(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y); + +/** Get green component of pixel. + @param bp Bitmap image file. + @param x X coordinate. + @param y Y coordinate. + @return Value corrected to requested bits per component. +*/ +dk3_bif_pixel_t +dk3bif_get_green(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y); + +/** Get blue component of pixel. + @param bp Bitmap image file. + @param x X coordinate. + @param y Y coordinate. + @return Value corrected to requested bits per component. +*/ +dk3_bif_pixel_t +dk3bif_get_blue(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y); + +/** Get gray component of pixel. + @param bp Bitmap image file. + @param x X coordinate. + @param y Y coordinate. + @return Value corrected to requested bits per component. +*/ +dk3_bif_pixel_t +dk3bif_get_gray(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y); + +/** Get alpha component of pixel. + @param bp Bitmap image file. + @param x X coordinate. + @param y Y coordinate. + @return Value corrected to requested bits per component. +*/ +dk3_bif_pixel_t +dk3bif_get_alpha(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y); + +/** Get red component of pixel mixed against background. + @param bp Bitmap image file. + @param x X coordinate. + @param y Y coordinate. + @return Value corrected to requested bits per component. +*/ +dk3_bif_pixel_t +dk3bif_get_mixed_red(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y); + +/** Get green component of pixel mixed against background. + @param bp Bitmap image file. + @param x X coordinate. + @param y Y coordinate. + @return Value corrected to requested bits per component. +*/ +dk3_bif_pixel_t +dk3bif_get_mixed_green(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y); + +/** Get blue component of pixel mixed against background. + @param bp Bitmap image file. + @param x X coordinate. + @param y Y coordinate. + @return Value corrected to requested bits per component. +*/ +dk3_bif_pixel_t +dk3bif_get_mixed_blue(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y); + +/** Get gray component of pixel mixed against background. + @param bp Bitmap image file. + @param x X coordinate. + @param y Y coordinate. + @return Value corrected to requested bits per component. +*/ +dk3_bif_pixel_t +dk3bif_get_mixed_gray(dk3_bif_t *bp, dk3_bif_coord_t x, dk3_bif_coord_t y); + +/** Get file to access raw data. + This function is primary intended to access JPEG data. + @param bp Bitmap image file. + @return FILE pointer if available, NULL otherwise. +*/ +FILE * +dk3bif_get_file(dk3_bif_t *bp); + +/** Retrieve X resolution. + @param bp Bitmap image file. + @return X resolution in dpi. +*/ +double +dk3bif_get_xres(dk3_bif_t *bp); + +/** Retrieve Y resolution. + @param bp Bitmap image file. + @return Y resolution in dpi. +*/ +double +dk3bif_get_yres(dk3_bif_t *bp); + +/** Close bitmap image file, release memory. + @param bp Bitmap image file to close. +*/ +void +dk3bif_close(dk3_bif_t *bp); + +/** Get original number of components for JPEG file. + @param bif Bitmap image file. + @return Number of components found in file on success, 0 on error. +*/ +int +dk3bif_jpeg_get_num_components(dk3_bif_t *bif); + +/** Check whether Adobe marker was found in JPEG input file. + @param bif Bitmap image file. + @return 1 if marker was found, 0 otherwise. +*/ +int +dk3bif_jpeg_get_found_adobe_marker(dk3_bif_t *bif); + +/** Calculate average predictor value from left and upper value. + @param left Value left to the pixel. + @param upper Value upper to the pixel. + @return Predictor value. +*/ +dk3_bif_pixel_t +dk3bif_average(dk3_bif_pixel_t left, dk3_bif_pixel_t upper); + +/** Paeth prediction function. + @param v1 Left value. + @param v2 Upper value. + @param v3 Upper left value. + @return Predicted value. +*/ +dk3_bif_pixel_t +dk3bif_paeth( + dk3_bif_pixel_t v1, + dk3_bif_pixel_t v2, + dk3_bif_pixel_t v3 +); + +/** Retrieve one pixel component not yet resampled. + @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. +*/ +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 +); + +#ifdef __cplusplus +} +#endif + + + +%% module + +#include "dk3conf.h" + +#include <stdio.h> + +#if DK3_HAVE_PNG_H +#include <png.h> +#else +#if DK3_HAVE_SETJMP_H +#include <setjmp.h> +#endif +#endif +#if DK3_HAVE_SYS_TYPES_H +#include <sys/types.h> +#endif +#if DK3_HAVE_STDLIB_H +#include <stdlib.h> +#endif +#if DK3_HAVE_UNISTD_H +#include <unistd.h> +#endif +#if DK3_HAVE_PROCESS_H +#include <process.h> +#endif +#if DK3_HAVE_JPEGLIB_H +#include <jpeglib.h> +#endif + +#if DK3_HAVE_TIFF_H +#include <tiff.h> +#include <tiffio.h> +#endif + +#if DK3_HAVE_STRING_H +#include <string.h> +#endif +#if DK3_HAVE_STRINGS_H +#include <strings.h> +#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" + + + +$!trace-include + + +$!trace-off + + +/** File suffixes for images. +*/ +static dkChar const * const dk3bif_dk_type_names[] = { +$!text macro=dkT +png +jpeg +jpg +tiff +tif +$!end +}; + + + +/** File suffixes for images. + Note: Order must correpsond to the order of dk3bif_dk_type_names. +*/ +static char const * const dk3bif_c8_type_names[] = { +$!text +png +jpeg +jpg +tiff +tif +$!end +}; + + + +/** 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; + $? "+ dk3bif_frame_release_implspec_png" + fdis = (dk3_bif_frame_png_t *)is; + if(fdis->rows) { $? ". delete rows" + for(i = 0L; i < fdis->h; i++) { $? ". delete row %ld", i + dk3_delete((fdis->rows)[i]); + } + dk3_delete(fdis->rows); + } + dk3_release(fdis); + $? "- dk3bif_frame_release_implspec_png" +} + +/** 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; + $? "+ dk3bif_release_implspec_png" + dis = (dk3_bif_png_t *)is; + if(dis->pp) { + if(dis->pi) { $? ". destroy info struct" + png_destroy_info_struct(dis->pp, &(dis->pi)); + } $? ". destroy read struct" + png_destroy_read_struct(&(dis->pp), (png_infopp)NULL, (png_infopp)NULL); + } + dis->pp = NULL; dis->pi = NULL; + dk3_release(dis); + $? "- dk3bif_release_implspec_png" +} + +/** 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; + $? "+ dk3bif_read_png_header" + szh = fread(header, 1, 8, bp->tmpfipo); + if(szh > 0) { $? ". szh ok" + if(png_sig_cmp(header, 0, szh) == 0) { + dis = dk3_new_app(dk3_bif_png_t,1,bp->app); + if(dis) { $? ". dis ok" + 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) { $? ". pp ok" +#if DK3_HAVE_SETJMP_H + if(setjmp(png_jmpbuf(dis->pp)) == 0) { +#endif + dis->pi = png_create_info_struct(dis->pp); + if(dis->pi) { $? ". piok" + bp->cf = dk3bif_frame_new(bp); + if(bp->cf) { $? ". cf ok" + fdis = dk3_new_app(dk3_bif_frame_png_t,1,bp->app); + if(fdis) { $? ". fdis ok" + 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); + $? ". w=%lu h=%lu ct=%d ch=%d bd=%d im=%d",w,h,ct,ch,bd,im +#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; + } + } + $? ". resolution %lg %lg", (bp->cf)->xres, (bp->cf)->yres + } + /* + 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); + $? ". w=%lu h=%lu ct=%d ch=%d bd=%d im=%d",w,h,ct,ch,bd,im + (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 { $? "! memory" + } + } else { $? "! memory" + } + } else { $? "! memory" + } +#if DK3_HAVE_SETJMP_H + } else { + back = 0; + } +#endif + } else { $? "! memory" + } + } else { $? "! memory" + } + } else { $? "! not a png file" + } + } else { $? "! failed to read any header data" + } + $? "- dk3bif_read_png_header %d", back + 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; $? ". bg chunk %lu %lu %lu", (unsigned long)(bgp->red), (unsigned long)(bgp->green), (unsigned long)(bgp->blue) + } + 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 { $? "! memory" + } +#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; + $? "+ dk3bif_read_jpeg_header" + 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; + $? ". fdis->num_comp = %d", (int)(fdis->num_comp) + 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: { $? ". gray" + (bp->cf)->cs = DK3_COLOR_SPACE_GRAY; + } break; + case JCS_RGB: { $? ". rgb" + (bp->cf)->cs = DK3_COLOR_SPACE_RGB; + } break; + case JCS_CMYK: { $? ". cmyk" + (bp->cf)->cs = DK3_COLOR_SPACE_CMYK; + } break; + case JCS_YCCK: { $? ". ycck" + (bp->cf)->cs = DK3_COLOR_SPACE_CMYK; + } break; + case JCS_YCbCr: { $? ". ycbcr" + (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 + } + } + $? "- dk3bif_read_jpeg_header %d", back + 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; + $? "+ dk3bif_read_jpeg_data" + if(bp->implspec) { $? ". implspec ok" + if(bp->cf) { $? ". cf ok" + if((bp->cf)->implspec) { $? ". cf->implspec ok" + dis = (dk3_bif_jpeg_t *)(bp->implspec); + fdis = (dk3_bif_frame_jpeg_t *)((bp->cf)->implspec); $? ". dis/fdis" + if(dis->st == 3) { $? ". state ok" +#if DK3_HAVE_SETJMP_H + if(setjmp((dis->errmgr).setjmp_buffer) == 0) { $? ". setjmp" +#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) { $? ". alloc ok" + occ = (dis->cinfo).out_color_components; + ok = 1; $? ". occ = %d", occ + rp = fdis->rows; $? ". fdis->w=%lu", (unsigned long)(fdis->w) + for(y = 0; y < fdis->h; y++) { *(rp++) = NULL; } + occ = occ * fdis->w; $? ". occ = %d", occ + rp = fdis->rows; + for(y = 0; y < fdis->h; y++) { $? ". alloc %lu", (unsigned long)y + *rp = dk3_new_app(JSAMPLE,occ,bp->app); + if(!(*rp)) { + ok = 0; $? "! memory" + } + rp++; + } + if(ok) { $? ". memory allocated" + dis->st = 6; /* Decompression started. */ + rp = fdis->rows; $? ". decompression started" + for(y = 0; y < fdis->h; y++) { $? ". now %lu", (unsigned long)y + jpeg_read_scanlines(&(dis->cinfo), rp, 1); + rp++; $? ". line scanned" + } $? ". image data read" + dis->st = 7; /* Data was read successfully. */ + jpeg_finish_decompress(&(dis->cinfo)); $? ". finished" + dis->st = 8; /* Decompression finished. */ + switch((dis->cinfo).out_color_space) { + case JCS_GRAYSCALE: { $? ". now grey" + (bp->cf)->cs = DK3_COLOR_SPACE_GRAY; + back = 1; + } break; + case JCS_RGB: { $? ". now rgb" + (bp->cf)->cs = DK3_COLOR_SPACE_RGB; + back = 1; + } break; + default: { + (bp->cf)->cs = 0; + } break; + } + } else { + } + } else { $? "! memory" + } +#if DK3_HAVE_SETJMP_H + } else { + } +#endif + } else { $? "! st" + } + } else { $? "! cf->implspec" + } + } else { $? "! cf" + } + } $? "- dk3bif_read_jpeg_data %d", back + 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; + $? "+ dk3bif_read_tiff_header" + if(bp->tmpfn) { $? ". have tmpfn" + dis = dk3_new_app(dk3_bif_tiff_t,1,bp->app); + if(dis) { $? ". dis" + /* + Initialization of TIFF per file. + */ + bp->implspec = (void *)dis; + dis->tiff = NULL; + dis->tiff = TIFFOpen(bp->tmpfn, "rb"); + if(dis->tiff) { $? ". TIFFOpen" + back = 1; + do { $? ". loop start" + 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) { $? ". frame ok" + (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) { $? ". fdis ok" + /* + 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; $? ". width ok" + (bp->cf)->w = (dk3_bif_coord_t)w; + if(TIFFGetField(dis->tiff, TIFFTAG_IMAGELENGTH, &h) == 1) { + fdis->h = h; $? ". height ok" + (bp->cf)->h = (dk3_bif_coord_t)h; + rv = 0.0; + if(TIFFGetField(dis->tiff, TIFFTAG_XRESOLUTION, &rv) == 1) { + (bp->cf)->xres = (double)rv; $? ". x resolution found" + } + rv = 0.0; + if(TIFFGetField(dis->tiff, TIFFTAG_YRESOLUTION, &rv) == 1) { + (bp->cf)->yres = (double)rv; $? ". y resolution found" + } + ru = 0; + if(TIFFGetField(dis->tiff, TIFFTAG_RESOLUTIONUNIT, &ru) == 1) + { $? ". resolution unit found" + switch(ru) { + case RESUNIT_CENTIMETER: { $? ". unit cm" + (bp->cf)->xres = 2.54 * (bp->cf)->xres; + (bp->cf)->yres = 2.54 * (bp->cf)->yres; + } break; + case RESUNIT_NONE: { $? ". other unit" + (bp->cf)->xres = (bp->cf)->yres = -1.0; + } break; + } + } + orient = ORIENTATION_TOPLEFT; + if(TIFFGetFieldDefaulted( + dis->tiff, TIFFTAG_ORIENTATION, &orient + ) == 1 + ) + { $? ". orientation = %u", (unsigned)orient + fdis->ori = orient; + switch(orient) { + case 5: case 6: case 7: case 8: { $? ". swap w/h" + 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; $? "! math error" + } else { $? ". wh product ok" +#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 + { $? ". wh ok" + fdis->r = (uint32 *)_TIFFmalloc(sz); + if(fdis->r) { $? ". allocation ok" + if(TIFFReadRGBAImageOriented( + dis->tiff, w, h, fdis->r, orient, 0 + ) + ) + { +#if TRACE_DEBUG || VERSION_BEFORE_20150821 + back = 1; $? ". image was read" +#endif + } else { $? "! read image failed" + back = 0; + } + } else { $? "! memory" + back = 0; + } + } else { + back = 0; $? "! numeric overflow" + } + } + } else { $? "! height not found" + back = 0; + } + } else { $? "! width not found" + back = 0; + } + } else { + back = 0; $? "! memory fdis" + } + } else { + back = 0; $? "! memory bp->cf" + } + w = h = 0UL; +#if VERSION_BEFORE_20150821 + cps = spp = 0U; +#endif + $? ". loop end" + } while((back == 1) && TIFFReadDirectory(dis->tiff)); + TIFFClose(dis->tiff); dis->tiff = NULL; $? ". tiff file closed" + if(bp->i_frames) { $? ". i_frames" + dk3sto_it_reset(bp->i_frames); + bp->cf = (dk3_bif_frame_t *)dk3sto_it_next(bp->i_frames); + if(!(bp->cf)) { $? "! no frame" + back = 0; + } + } else { $? "! i_frames" + } + } else { $? "! TIFFOpen" + } + } else { $? "! dis" + } + } else { $? "! no file name" + } $? "- dk3bif_read_tiff_header %d", back + 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) +{ + $? "+ dk3bif_frame_delete %!8s", TR_8PTR(fp) + 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); + } $? "- dk3bif_frame_delete" +} + + + +/** 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; + $? "+ dk3bif_get_pixel_component_not_resampled %lu %lu %d", (unsigned long)x, (unsigned long)y, c + if(c == 3) { $? ". alpha component asked, default is full" + 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; + } + } + } + $? "- dk3bif_get_pixel_component_not_resampled %u", (unsigned)back + 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; + $? "+ dk3bif_get_pixel_component %lu %lu %d", (unsigned long)x, (unsigned long)y, c + /* + Get unresampled value. + */ + back = dk3bif_get_pixel_component_not_resampled(bp, x, y, c); + /* + Resample value to requested output bit size. + */ + $? "- dk3bif_get_pixel_component %u", (unsigned)back + 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) +{ + $? "+ dk3bif_set_pixel_sampling" + if(bp) { + if(bp->cf) { + if(bp->bits) { $? ". resampling probably needed" + dk3pixre_set(&(bp->pr), (bp->cf)->bits, bp->bits); + } else { $? ". no resampling required" + dk3pixre_set(&(bp->pr), (bp->cf)->bits, (bp->cf)->bits); + } + } + } + $? "- dk3bif_set_pixel_sampling" +} + + + +/** 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; + $? "+ dk3bif_allocate_app" + 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; + } + } + } $? "- dk3bif_allocate_app %!8s", TR_8PTR(back) + 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; + $? "+ dk3bif_read_header" + 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); + $? "- dk3bif_read_header %d", back + 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) +{ + $? "+ dk3bif_create_tmpfilename" +#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 + $? "- dk3bif_create_tmpfilename" +} + + + +/** 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. */ + $? "+ dk3bif_copy_to_temp" + 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 + } $? "- dk3bif_copy_to_temp %d", back + 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; + $? "+ dk3bif_correct_type %d", tp + 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; + } + } + } $? "- dk3bif_correct_type %d", back + 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. */ + $? "+ dk3bif_open_filename_app" + 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); + } + } + } $? "- dk3bif_open_filename_app %!8s", TR_8PTR(back) + 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. */ + $? "+ dk3bif_open_c8_filename_app" + 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); + } + } + } $? "- dk3bif_open_c8_filename_app %!8s", TR_8PTR(back) + 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; + $? "+ dk3bif_open_file_app" + 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); + } + } + } $? "- dk3bif_open_file_app %!8s", TR_8PTR(back) + return back; +} + + + +void +dk3bif_close(dk3_bif_t *bp) +{ + dk3_bif_frame_t *fp; + $? "+ dk3bif_close" + 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) { $? ". close file" + fclose(bp->tmpfipo); bp->tmpfipo = NULL; + } + /* + Delete file and release file name memory. + */ + if(bp->tmpfn) { $? ". delete temp file name and remove file" + if(bp->remtmpf) { + dk3sf_c8_remove_file_app(bp->tmpfn, bp->app); + } + dk3_release(bp->tmpfn); + } + bp->app = NULL; + dk3_delete(bp); + } $? "- dk3bif_close" +} + + + +int +dk3bif_check_suffix_without_dot(dkChar const *sn) +{ + int back = DK3_BIF_IMAGE_TYPE_UNKNOWN; + int tp = -1; + $? "+ dk3bif_check_suffix_without_dot" + if(sn) { + tp = dk3str_array_index(dk3bif_dk_type_names, sn, 0); $? ". tp=%d", tp + switch(tp) { + case 0: { $? ". png" + back = DK3_BIF_IMAGE_TYPE_PNG; + } break; + case 1: case 2: { $? ". jpeg" + back = DK3_BIF_IMAGE_TYPE_JPEG; + } break; + case 3: case 4: { $? ". tiff" + back = DK3_BIF_IMAGE_TYPE_TIFF; + } break; + } + } $? "- dk3bif_check_suffix_without_dot %d", back + 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; + $? "+ dk3bif_check_file_name" + if(fn) { + sp = dk3str_get_suffix(fn); + if(sp) { + sp++; + back = dk3bif_check_suffix_without_dot(sp); + } + } $? "- dk3bif_check_file_name %d", back + 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; + $? "+ dk3bif_read_data" + 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 + $? ". read jpeg" + back = dk3bif_read_jpeg_data(bp); + $? ". jpeg read successfully" +#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); + $? "- dk3bif_read_data %d", back + return back; +} + + + +size_t +dk3bif_number_of_frames(dk3_bif_t *bp) +{ + size_t back = 0; + $? "+ dk3bif_number_of_frames" + if(bp) { + back = bp->n_frames; + } $? "- dk3bif_number_of_frames %u", (unsigned)back + return back; +} + + + +int +dk3bif_set_frame(dk3_bif_t *bp, size_t fn) +{ + int back = 0; + $? "+ dk3bif_set_frame %u", (unsigned)fn + 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); + } + } $? "- dk3bif_set_frame %d", back + return back; +} + + + +size_t +dk3bif_get_bits_per_pixel(dk3_bif_t *bp) +{ + size_t back = 0; + $? "+ dk3bif_get_bits_per_pixel" + if(bp) { + if(bp->cf) { + back = (bp->cf)->bits; + } + } $? "- dk3bif_get_bits_per_pixel %u", (unsigned)back + return back; +} + + + +size_t +dk3bif_real_bits_per_pixel(dk3_bif_t *bp) +{ + size_t back = 0; + $? "+ dk3bif_real_bits_per_pixel" + if(bp) { + if(bp->cf) { + back = (bp->cf)->realbits; + } + } $? "- dk3bif_real_bits_per_pixel %u", (unsigned)back + 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; + $? "+ dk3bif_set_bits_per_pixel" + 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); + } + } + } $? "- dk3bif_set_bits_per_pixel %d", back + return back; +} + + + +dk3_bif_coord_t +dk3bif_get_width(dk3_bif_t *bp) +{ + dk3_bif_coord_t back = 0L; + $? "+ dk3bif_get_width" + if(bp) { + if(bp->cf) { + back = (bp->cf)->w; + } + } $? "- dk3bif_get_width %ld", (long)back + return back; +} + + + +dk3_bif_coord_t +dk3bif_get_height(dk3_bif_t *bp) +{ + dk3_bif_coord_t back = 0L; + $? "+ dk3bif_get_height" + if(bp) { + if(bp->cf) { + back = (bp->cf)->h; + } + } $? "- dk3bif_get_height %ld", (long)back + 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; + $? "+ dk3bif_get_largest_width" + 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; } + } + } $? "- dk3bif_get_largest_width %ld", (long)back + 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; + $? "+ dk3bif_get_largest_height" + 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; } + } + } + $? "- dk3bif_get_largest_height %ld", (long)back + 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; + $? "+ dk3bif_get_red" + 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; + } + } + } $? "- dk3bif_get_red %ld %ld %u", (long)x, (long)y, (unsigned)back + 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; + $? "+ dk3bif_get_green" + 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; + } + } + } $? "- dk3bif_get_green %ld %ld %u", (long)x, (long)y, (unsigned)back + 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; + $? "+ dk3bif_get_blue" + 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; + } + } + } $? "- dk3bif_get_blue %ld %ld %u", (long)x, (long)y, (unsigned)back + 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; + $? "+ dk3bif_get_gray" + 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)); + $? ". r=%u g=%u b=%u gray=%u", 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 + } break; + } + } + } $? "- dk3bif_get_gray %u", (unsigned)back + 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; + $? "+ dk3bif_get_alpha" + 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; + } + } + } $? "- dk3bif_get_alpha %u", (unsigned)back + 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; + $? "+ dk3bif_get_mixed_red" + 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; + } + } $? "- dk3bif_get_mixed_red %ld %ld %u", (long)x, (long)y, (unsigned)back + 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; + $? "+ dk3bif_get_mixed_green" + 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; + } + } $? "- dk3bif_get_mixed_green %ld %ld %u", (long)x, (long)y, (unsigned)back + 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; + $? "+ dk3bif_get_mixed_blue" + 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; + } + } $? "- dk3bif_get_mixed_blue %ld %ld %u", (long)x, (long)y, (unsigned)back + 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; + $? "+ dk3bif_get_mixed_gray %ld %ld", x, y + 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: { $? ". mix" + back = dk3bif_mix( + back, + (bp->cf)->bggr, + dk3bif_get_alpha(bp, x, y), + dk3pixre_get_max_value(&(bp->pr)) + ); + } break; + } + } $? "- dk3bif_get_mixed_gray %u", (unsigned)back + return back; +} + + + +int +dk3bif_type_supported(int tp) +{ + int back = 0; + $? "+ dk3bif_type_supported %d", tp + 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; + } $? "- dk3bif_type_supported %d", back + return back; +} + + + +FILE * +dk3bif_get_file(dk3_bif_t *bp) +{ + FILE *back = NULL; + $? "+ dk3bif_get_file" + if(bp) { + back = bp->tmpfipo; + } $? "- dk3bif_get_file %!8s", TR_8PTR(back) + 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; + $? "+ dk3bif_get_xres" + if(bp) { + if(bp->cf) { + back = (bp->cf)->xres; + } + } $? "- dk3bif_get_xres %lg", back + return back; +} + + + +double +dk3bif_get_yres(dk3_bif_t *bp) +{ + double back = -1.0; + $? "+ dk3bif_get_yres" + if(bp) { + if(bp->cf) { + back = (bp->cf)->yres; + } + } $? "- dk3bif_get_yres %lg", back + 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; +} + + +$!trace-on + +int +dk3bif_jpeg_get_num_components(dk3_bif_t *bif) +{ + int back = 0; +#if DK3_HAVE_JPEGLIB_H + dk3_bif_frame_jpeg_t *jpf; + $? "+ dk3bif_jpeg_get_num_components" + if(bif) { $? ". bif" + if(bif->cf) { $? ". cf" + if(bif->bt == DK3_BIF_IMAGE_TYPE_JPEG) { $? ". cs ok" + jpf = (dk3_bif_frame_jpeg_t *)((bif->cf)->implspec); + if(jpf) { $? ". jpf" + back = jpf->num_comp; + } else { $? "! jpf" + } + } else { $? "! cs" + } + } else { $? "! cf" + } + } else { $? "! bif" + } $? "- dk3bif_jpeg_get_num_components %d", back +#endif + return back; +} + +$!trace-off + + +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 : */ + |