summaryrefslogtreecommitdiff
path: root/support/dktools/dk3bif.ctr
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/dktools/dk3bif.ctr
Initial commit
Diffstat (limited to 'support/dktools/dk3bif.ctr')
-rw-r--r--support/dktools/dk3bif.ctr3115
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 : */
+