%% options copyright owner = Dirk Krause copyright year = 2017-xxxx SPDX-License-Identifier: BSD-3-Clause %% header /** @file dk4bif.h Bitmap image files. */ #ifndef DK4CONF_H_INCLUDED #if DK4_BUILDING_DKTOOLS4 #include "dk4conf.h" #else #include #endif #endif #ifndef DK4BIFTY_H_INCLUDED #if DK4_BUILDING_DKTOOLS4 #include "dk4bifty.h" #else #include #endif #endif #ifdef __cplusplus extern "C" { #endif /** Find bitmap image file type for file name. @param fn File name to check. @return Non-negative dk4_bif_type_t value on success, -1 on error (NULL file name or file name suffix does not indicate a graphics type the function can handle). */ int dk4bif_type_for_suffix( dkChar const *fn ); /** Open bitmap image file. @param fn File name containing the bitmap image. @param hdronly Flag: Read header only. @param pcsctx Color space conversion context, may be NULL. @param erp Error report, may be NULL. @return Valid pointer to bitmap image file on success, NULL on error. Error codes: - DK4_E_INVALID_ARGUMENTS
if fn is NULL, - DK4_E_NOT_FOUND
if the file name does not contain a suffix or the suffix does not indicate a bitmap image file type the function can handle, - DK4_E_MEMORY_ALLOCATION_FAILED
if a memory allocation failed, - DK4_E_SYNTAX
if the file contents is incorrect (not matching the specified file type), - DK4_E_READ_FAILED
if the function failed to read from file fn. */ dk4_bif_t * dk4bif_open( dkChar const *fn, int hdronly, dk4_cs_conv_ctx_t const *pcsctx, dk4_er_t *erp ); /** Open bitmap image file. @param fn File name containing the bitmap image. @param ty Image file type (PNG, JPEG or TIFF). @param honly Flag: Read header information only. @param pcsctx Color space conversion context, may be NULL. @param erp Error report, may be NULL. @return Valid pointer to bitmap image file on success, NULL on error. Error codes: - DK4_E_INVALID_ARGUMENTS
if fn is NULL or an unknown bitmap type is requested, - DK4_E_READ_FAILED
if the function failed to read from file fn, - DK4_E_NOT_SUPPORTED
if the operation is not supported (i.e. compiled without a required library). */ dk4_bif_t * dk4bif_open_type( dkChar const *fn, int ty, int honly, dk4_cs_conv_ctx_t const *pcsctx, dk4_er_t *erp ); /** Open bitmap image file. @param fipo File, opened for binary reading. @param fn File name containing the bitmap image. @param ty Image file type (PNG, JPEG or TIFF). @param honly Flag: Read image header only. @param pcsctx Color space conversion context, may be NULL. @param erp Error report, may be NULL. @return Valid pointer to bitmap image file on success, NULL on error. Error codes: - DK4_E_INVALID_ARGUMENTS
if fipo or fn is NULL, - DK4_E_NOT_SUPPORTED
if the operation is not supported (i.e. compiled without a required library). */ dk4_bif_t * dk4bif_open_file( FILE *fipo, dkChar const *fn, int ty, int honly, dk4_cs_conv_ctx_t const *pcsctx, dk4_er_t *erp ); /** Close bitmap image file and release resources. @param bif Bitmap image file to close. */ void dk4bif_close( dk4_bif_t *bif ); /** Find number of frames in bitmap image file. @param bif Bitmap image file to query. @return Positive value on success, 0 on error. */ size_t dk4bif_get_number_of_frames( dk4_bif_t const *bif ); /** Set current frame in a bitmap image file. @param bif Bitmap image file. @param fno Index of new current frame (0 for first frame). @return 1 on success, 0 on error (out of range). */ int dk4bif_set_current_frame( dk4_bif_t *bif, size_t fno ); /** Retrieve low level bit depth of current frame bitmap image file. @param bif Bitmap image file @return Positive value on success, 0 on error. */ dk4_px_bit_depth_t dk4bif_get_original_bit_depth( dk4_bif_t const *bif ); /** Retrieve color space of current frame returned from low-level library. @param bif Bitmap image file. @return Non-negative dk4_bif_cs_t value on success, -1 on error. */ int dk4bif_get_color_space( dk4_bif_t const *bif ); /** Retrieve color space of current frame contained in the file. @param bif Bitmap image file. @return Non-negative dk4_bif_cs_t value on success, -1 on error. */ int dk4bif_get_file_color_space( dk4_bif_t const *bif ); /** Set required output bit depth for pixel data to retrieve for all frames. @param bif Bitmap image file. @param bd Required output bit depth. @return 1 on success, 0 on error. */ int dk4bif_set_output_bit_depth( dk4_bif_t *bif, dk4_px_bit_depth_t bd ); /** Set default background or enforced background for bitmap image file for all frames. @param bif Bitmap image file. @param bg Array containing background values. @param szbg Size of bg array (number of elements). @param bd Bit depth used in the bg array. @param force Flag: Enforce this background. Without this flag the background information from here is used only if no background information was found in the file. @return 1 on success, 0 on error. */ int dk4bif_set_background( dk4_bif_t *bif, dk4_px_t const *bg, size_t szbg, dk4_px_bit_depth_t bd, int force ); /** Get image type. @param bif Bitmap image file. @return Non-negative image type on success, negative value on error. */ int dk4bif_get_image_type( dk4_bif_t const *bif ); /** Retrieve data for one pixel in the required output bit depth and color space. @param dptr Address of destination array, must be large enough. @param szdptr Size of dptr array (number of elements). @param bif Bitmap image file. @param rowno Row number (0 for top row). @param colno Column number (0 for left column). @param cs Required color space. @return 1 on success, 0 on error. */ int dk4bif_get_pixel( dk4_px_t *dptr, size_t szdptr, dk4_bif_t const *bif, dk4_bif_dim_t rowno, dk4_bif_dim_t colno, int cs ); /** Get the current frames x resolution in dpi. @param bif Bitmap image file. @return Positive number on success, negative value on error or if not found. */ double dk4bif_get_xres( dk4_bif_t const *bif ); /** Get the current frames y resolution in dpi. @param bif Bitmap image file. @return Positive number on success, negative value on error or if not found. */ double dk4bif_get_yres( dk4_bif_t const *bif ); /** Set resolution explicitly. @param bif Bitmap image file. @param xres X resolution, must be positive. @param yres Y resolution, must be positive. @param erp Error report, may be NULL. @return 1 on success, 0 on error */ int dk4bif_set_res( dk4_bif_t *bif, double xres, double yres, dk4_er_t *erp ); /** Get current frame width. @param bif Bitmap image file. @return Positive number on success, negative value on error. */ dk4_bif_dim_t dk4bif_get_width( dk4_bif_t const *bif ); /** Get current frame height. @param bif Bitmap image file. @return Positive number on success, negative value on error. */ dk4_bif_dim_t dk4bif_get_height( dk4_bif_t const *bif ); /** Get color space conversion context for bitmap image. @param bif Bitmap image file. @return Valid pointer on success, NULL on error. */ const dk4_cs_conv_ctx_t * dk4bif_get_cs_conv_ctx( dk4_bif_t const *bif ); /** Set color space conversion context for bitmap image. @param bif Bitmap image file. @param pctx Color space conversion context to use. */ void dk4bif_set_cs_conv_ctx( dk4_bif_t *bif, dk4_cs_conv_ctx_t const *pctx ); /** Close a bitmap image frame, release ressources. @param frptr Frame to close. @param imgtype Bitmap image file type. */ void dk4bif_frame_close( dk4_bif_frame_t *frptr, int imgtype ); #ifdef __cplusplus } #endif /* vim: set ai sw=4 ts=4 : */ %% module #ifndef DK4CONF_H_INCLUDED #include "dk4conf.h" #endif #ifndef DK4MEM_H_INCLUDED #include "dk4mem.h" #endif #ifndef DK4BIF_H_INCLUDED #include "dk4bif.h" #endif #ifndef BIF_H_INCLUDED #include "bif.h" #endif #ifndef DK4PATHD_H_INCLUDED #include "dk4pathd.h" #endif #ifndef DK4STRD_H_INCLUDED #include "dk4strd.h" #endif #ifndef DK4FOPD_H_INCLUDED #include "dk4fopd.h" #endif #if DK4_HAVE_ASSERT_H #ifndef ASSERT_H_INCLUDED #include #define ASSERT_H_INCLUDED 1 #endif #endif $!trace-include /** File name suffixes for bitmap image files. */ static const dkChar * const dk4bif_suffixes[] = { $!string-table macro=dkT .png .jpg .jpeg .tif .tiff .pbm .pgm .ppm .pnm .pam $!end }; /** Keywords used by the module. */ static const dkChar * const dk4bif_kw[] = { $!string-table macro=dkT # # File open mode: read binary # rb $!end }; void dk4bif_frame_close( dk4_bif_frame_t *frptr, int imgtype ) { $? "+ dk4bif_frame_close frptr=%d", TR_IPTR(frptr) #if DK4_USE_ASSERT assert(NULL != frptr); #endif if (NULL != frptr) { if (NULL != frptr->tsdata) { switch (imgtype) { case DK4_BIF_TYPE_PNG : { #if DK4_HAVE_PNG_H dk4bifpng_nc_release_per_frame_data(frptr->tsdata); #else dk4mem_release(frptr->tsdata); #endif } break; case DK4_BIF_TYPE_JPEG : { #if DK4_HAVE_JPEGLIB_H dk4bifjpeg_nc_release_per_frame_data(frptr->tsdata, frptr); #else dk4mem_release(frptr->tsdata); #endif } break; case DK4_BIF_TYPE_TIFF : { #if DK4_HAVE_TIFF_H dk4biftiff_nc_release_per_frame_data(frptr->tsdata); #else dk4mem_release(frptr->tsdata); #endif } break; case DK4_BIF_TYPE_NETPBM : { dk4bifnetpbm_nc_release_per_frame_data(frptr->tsdata); } break; default : { dk4mem_release(frptr->tsdata); } break; } frptr->tsdata = NULL; } dk4mem_free(frptr); } $? "- dk4bif_frame_close" } void dk4bif_close( dk4_bif_t *bif ) { dk4_bif_frame_t *frptr; /* Traverse all frames */ $? "+ dk4bif_close ptr=%d", TR_IPTR(bif) #if DK4_USE_ASSERT assert(NULL != bif); #endif if (NULL != bif) { if (NULL != bif->s_frames) { if (NULL != bif->i_frames) { dk4sto_it_reset(bif->i_frames); do { frptr = (dk4_bif_frame_t *)dk4sto_it_next(bif->i_frames); if (NULL != frptr) { dk4bif_frame_close(frptr, bif->imgtype); } } while(NULL != frptr); dk4sto_it_close(bif->i_frames); bif->i_frames = NULL; } dk4sto_close(bif->s_frames); bif->s_frames = NULL; } bif->cf = NULL; if (NULL != bif->tsdata) { switch (bif->imgtype) { case DK4_BIF_TYPE_PNG : { #if DK4_HAVE_PNG_H dk4bifpng_nc_release_per_file_data(bif->tsdata); #else dk4mem_release(bif->tsdata); #endif } break; case DK4_BIF_TYPE_JPEG : { #if 0 /* No per-file data stored for JPEG file */ #if DK4_HAVE_JPEGLIB_H dk4bifjpeg_nc_release_per_file_data(bif->tsdata); #else dk4mem_release(bif->tsdata); #endif #endif } break; case DK4_BIF_TYPE_TIFF : { #if 0 /* No per-file data stored for TIFF */ #if DK4_HAVE_TIFF_H dk4biftiff_nc_release_per_file_data(bif->tsdata); #else dk4mem_release(bif->tsdata); #endif #endif } break; case DK4_BIF_TYPE_NETPBM : { /* No per-file data stored for NetPBM. */ } break; default : { dk4mem_release(bif->tsdata); } break; } } dk4mem_release(bif->filename); bif->n_frames = 0; bif->imgtype = 0; dk4mem_free(bif); } $? "- dk4bif_close" } int dk4bif_type_for_suffix( dkChar const *fn ) { const dkChar *sptr; /* Pointer to dot of file name suffix */ int back = -1; $? "+ dk4bif_type_for_suffix \"%!ds\"", TR_STR(fn) #if DK4_USE_ASSERT assert(NULL != fn); #endif if (NULL != fn) { sptr = dk4path_get_suffix(fn, NULL); $? ". sptr = \"%!ds\"", TR_STR(sptr) if (NULL != sptr) { switch (dk4str_array_index(dk4bif_suffixes, sptr, 0)) { case 0 : { back = DK4_BIF_TYPE_PNG; } break; case 1 : case 2 : { back = DK4_BIF_TYPE_JPEG; } break; case 3 : case 4 : { back = DK4_BIF_TYPE_TIFF; } break; case 5 : case 6 : case 7 : case 8 : case 9 : { back = DK4_BIF_TYPE_NETPBM; } break; } } } $? "- dk4bif_type_for_suffix %d", back return back; } dk4_bif_t * dk4bif_open_file( FILE *fipo, dkChar const *fn, int ty, int honly, dk4_cs_conv_ctx_t const *pcsctx, dk4_er_t *erp ) { dk4_bif_png_clobbered_t pngcp; /* Clobber protected variables */ dk4_bif_jpg_clobbered_t jpgcp; /* Clobber protected variables */ dk4_bif_t *back = NULL; $? "+ dk4bif_open_file ptr=%d \"%!ds\"", TR_IPTR(fipo), TR_STR(fn) #if DK4_USE_ASSERT assert(NULL != fipo); #endif if (NULL == fipo) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } switch (ty) { case DK4_BIF_TYPE_PNG : { #if DK4_HAVE_PNG_H pngcp.back = NULL; pngcp.pfrpng = NULL; pngcp.ok = 0; back = dk4bifpng_nc_open_file(fipo, fn, honly, pcsctx, &pngcp, erp); #else dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED); #endif } break; case DK4_BIF_TYPE_JPEG : { #if DK4_HAVE_JPEGLIB_H jpgcp.st = 0; jpgcp.ok = 0; jpgcp.back = NULL; back = dk4bifjpeg_nc_open_file(fipo,fn,honly,pcsctx,&jpgcp,erp); #else dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED); #endif } break; case DK4_BIF_TYPE_NETPBM : { $? ". before dk4bifnetpbm_nc_open_file honly=%d", honly back = dk4bifnetpbm_nc_open_file(fipo, fn, honly, pcsctx, erp); $? ". after dk4bifnetpbm_nc_open_file" } break; default : { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } break; } finished: $? "- dk4bif_open_file %d", TR_IPTR(back) return back; } dk4_bif_t * dk4bif_open_type( dkChar const *fn, int ty, int honly, dk4_cs_conv_ctx_t const *pcsctx, dk4_er_t *erp ) { FILE *inputfile; /* Input file */ dk4_bif_t *back = NULL; int tests = DK4_FOPEN_SC_IS_REGULAR; /* Tests for fopen */ $? "+ dk4bif_open_type \"%!ds\"", TR_STR(fn) #if DK4_USE_ASSERT assert(NULL != fn); #endif if (NULL == fn) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } if ((DK4_BIF_TYPE_MIN > ty) || (DK4_BIF_TYPE_MAX < ty)) { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); goto finished; } switch (ty) { case DK4_BIF_TYPE_PNG : case DK4_BIF_TYPE_JPEG : case DK4_BIF_TYPE_NETPBM : { inputfile = dk4fopen(fn, dk4bif_kw[0], tests, erp); if (NULL != inputfile) { back = dk4bif_open_file(inputfile, fn, ty, honly, pcsctx, erp); fclose(inputfile); } } break; case DK4_BIF_TYPE_TIFF : { #if DK4_HAVE_TIFF_H back = dk4biftiff_nc_open_type(fn, pcsctx, erp); #else dk4error_set_simple_error_code(erp, DK4_E_NOT_SUPPORTED); #endif } break; } finished: $? "- dk4bif_open_type %d", TR_IPTR(back) return back; } dk4_bif_t * dk4bif_open( dkChar const *fn, int hdronly, dk4_cs_conv_ctx_t const *pcsctx, dk4_er_t *erp ) { dk4_bif_t *back = NULL; int tp; /* Bitmap image file type */ $? "+ dk4bif_open \"%!ds\"", TR_STR(fn) #if DK4_USE_ASSERT assert(NULL != fn); #endif if (NULL != fn) { tp = dk4bif_type_for_suffix(fn); if ((DK4_BIF_TYPE_MIN <= tp) && (DK4_BIF_TYPE_MAX >= tp)) { back = dk4bif_open_type(fn, tp, hdronly, pcsctx, erp); } else { dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } $? "- dk4bif_open %d", TR_IPTR(back) return back; } size_t dk4bif_get_number_of_frames( dk4_bif_t const *bif ) { size_t back = 0; $? "+ dk4bif_get_number_of_frames %d", TR_IPTR(bif) #if DK4_USE_ASSERT assert(NULL != bif); #endif if (NULL != bif) { back = bif->n_frames; } $? "- dk4bif_get_number_of_frames %lu", (unsigned long)back return back; } int dk4bif_set_current_frame( dk4_bif_t *bif, size_t fno ) { int back = 0; $? "+ dk4bif_set_current_frame ptr=%d frame=%lu", TR_IPTR(bif), (unsigned long)fno #if DK4_USE_ASSERT assert(NULL != bif); #endif /* Check arguments */ if (NULL == bif) { goto finished; } if ((NULL == bif->s_frames) || (NULL == bif->i_frames)) { goto finished; } /* Retrieve frames from storage iterator until found */ dk4sto_it_reset(bif->i_frames); do { bif->cf = (dk4_bif_frame_t *)dk4sto_it_next(bif->i_frames); if (NULL == bif->cf) { goto finished; } } while(0 < fno--); if (NULL != bif->cf) { back = 1; } /* Return */ finished: $? "- dk4bif_set_current_frame %d", back return back; } dk4_px_bit_depth_t dk4bif_get_original_bit_depth( dk4_bif_t const *bif ) { dk4_px_bit_depth_t back = 0; $? "+ dk4_px_bit_depth_t ptr=%d", TR_IPTR(bif) #if DK4_USE_ASSERT assert(NULL != bif); #endif /* Check arguments */ if (NULL == bif) { goto finished; } if (NULL == bif->cf) { goto finished; } /* Retrieve bit depth from current frame */ back = (bif->cf)->l_bdepth; /* Return */ finished: $? "- dk4_px_bit_depth_t %u", (unsigned)back return back; } int dk4bif_get_color_space( dk4_bif_t const *bif ) { int back = -1; $? "+ dk4bif_get_color_space ptr=%d", TR_IPTR(bif) #if DK4_USE_ASSERT assert(NULL != bif); #endif /* Check arguments */ if (NULL == bif) { goto finished; } if (NULL == bif->cf) { goto finished; } /* Retrieve library color space from current frame */ back = (bif->cf)->l_cs; /* Return */ finished: $? "- dk4bif_get_color_space %d", back return back; } int dk4bif_get_file_color_space( dk4_bif_t const *bif ) { int back = -1; $? "+ dk4bif_get_file_color_space ptr=%d", TR_IPTR(bif) #if DK4_USE_ASSERT assert(NULL != bif); #endif /* Check arguments */ if (NULL == bif) { goto finished; } if (NULL == bif->cf) { goto finished; } /* Retrieve file color space from current frame */ back = (bif->cf)->f_cs; /* Return */ finished: $? "- dk4bif_get_file_color_space %d", back return back; } int dk4bif_set_output_bit_depth( dk4_bif_t *bif, dk4_px_bit_depth_t bd ) { dk4_bif_frame_t *fptr; /* Traverse all frames in storage */ int back = 0; $? "+ dk4bif_set_output_bit_depth ptr=%d bd=%u", TR_IPTR(bif), (unsigned)bd #if DK4_USE_ASSERT assert(NULL != bif); #endif /* Check arguments */ if (NULL == bif) { goto finished; } if ((NULL == bif->s_frames) || (NULL == bif->i_frames)) { goto finished; } if (0 != bif->hdronly) { goto finished; } /* Traverse all frames, set required bit depth and resampler in frame */ dk4sto_it_reset(bif->i_frames); do { fptr = (dk4_bif_frame_t *)dk4sto_it_next(bif->i_frames); if (NULL != fptr) { $? ". set bit depth for frame" if (0 != fptr->fmres) { dk4pxres_setup_from_maxval(&(fptr->resampler), fptr->fmrmv, bd); } else { dk4pxres_setup(&(fptr->resampler), fptr->l_bdepth, bd); } fptr->r_bdepth = bd; $? ". bglbd[0]=%u", (unsigned)(fptr->bglbd[0]) $? ". bglbd[1]=%u", (unsigned)(fptr->bglbd[1]) $? ". bglbd[2]=%u", (unsigned)(fptr->bglbd[2]) dk4mem_cpy( &(fptr->bg[0]), &(fptr->bglbd[0]), 4*sizeof(dk4_px_t), NULL ); if ((fptr->l_bdepth != bd) || (0 != fptr->fmres)) { dk4pxres_multiple(&(fptr->bg[0]), 4, &(fptr->resampler)); } $? ". bg[0]=%u", (unsigned)(fptr->bg[0]) $? ". bg[1]=%u", (unsigned)(fptr->bg[1]) $? ". bg[2]=%u", (unsigned)(fptr->bg[2]) } } while (NULL != fptr); /* Indicate success */ back = 1; /* Return */ finished: $? "- dk4bif_set_output_bit_depth %d", back return back; } int dk4bif_set_background( dk4_bif_t *bif, dk4_px_t const *bg, size_t szbg, dk4_px_bit_depth_t bd, int force ) { dk4_px_resample_t bgres; /* Resample bg data to required bit depth */ dk4_bif_frame_t *fptr; /* Traverse all frames */ size_t i; /* Current bg component index */ int back = 0; $? "+ dk4bif_set_background ptr=%d bg=%d", TR_IPTR(bif), TR_IPTR(bg) #if DK4_USE_ASSERT assert(NULL != bif); #endif /* Check arguments */ if ((NULL == bif) || (NULL == bg)) { goto finished; } if ((NULL == bif->s_frames) || (NULL == bif->i_frames)) { goto finished; } if (0 != bif->hdronly) { goto finished; } /* Correct number of background arguments */ if (szbg > 4) { szbg = 4; } /* Traverse all frames, set background in the frames bit depth */ dk4sto_it_reset(bif->i_frames); do { fptr = (dk4_bif_frame_t *)dk4sto_it_next(bif->i_frames); if (NULL != fptr) { if ((0 != force) || (0 == (bif->cf)->hbg)) { if (0 != fptr->fmres) { dk4pxres_setup_to_maxval(&bgres, bd, fptr->fmrmv); } else { dk4pxres_setup(&bgres, bd, (fptr->l_bdepth)); } for (i = 0; i < szbg; i++) { fptr->bg[i] = dk4pxres_get(&bgres, bg[i]); fptr->bglbd[i] = bg[i]; } } } } while (NULL != fptr); /* Indicate success */ back = 1; /* Return */ finished: $? "- dk4bif_set_background %d", back return back; } double dk4bif_get_xres( dk4_bif_t const *bif ) { double back = -1.0; $? "+ dk4bif_get_xres %d", TR_IPTR(bif) #if DK4_USE_ASSERT assert(NULL != bif); #endif if (NULL == bif) { goto finished; } if (NULL == bif->cf) { goto finished; } /* Retrieve x resolution from current frame */ back = (bif->cf)->res_x; /* Return */ finished: $? "- dk4bif_get_xres %g", back return back; } double dk4bif_get_yres( dk4_bif_t const *bif ) { double back = -1.0; $? "+ dk4bif_get_yres %d", TR_IPTR(bif) #if DK4_USE_ASSERT assert(NULL != bif); #endif /* Check arguments */ if (NULL == bif) { goto finished; } if (NULL == bif->cf) { goto finished; } /* Retrieve y resolution from current frame */ back = (bif->cf)->res_y; /* Return */ finished: $? "- dk4bif_get_yres %g", back return back; } int dk4bif_set_res( dk4_bif_t *bif, double xres, double yres, dk4_er_t *erp ) { int back = 0; $? "+ dk4bif_set_res %lg %lg", xres, yres #if DK4_USE_ASSERT assert(NULL != bif); #endif if ((NULL != bif) && (0.0 < xres) && (0.0 < yres)) { if (NULL != bif->cf) { $? ". settings applied" bif->cf->res_x = xres; bif->cf->res_y = yres; back = 1; } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } } else { dk4error_set_simple_error_code(erp, DK4_E_INVALID_ARGUMENTS); } $? "- dk4bif_set_res %d", back return back; } dk4_bif_dim_t dk4bif_get_width( dk4_bif_t const *bif ) { dk4_bif_dim_t back = -1L; $? "+ dk4_bif_dim_t %d", TR_IPTR(bif) #if DK4_USE_ASSERT assert(NULL != bif); #endif /* Check arguments */ if (NULL == bif) { goto finished; } if (NULL == bif->cf) { goto finished; } /* Retrieve width of current frame */ back = (bif->cf)->dim_x; /* Return */ finished: $? "- dk4_bif_dim_t %ld", (long)back return back; } dk4_bif_dim_t dk4bif_get_height( dk4_bif_t const *bif ) { dk4_bif_dim_t back = -1L; $? "+ dk4bif_get_height %d", TR_IPTR(bif) #if DK4_USE_ASSERT assert(NULL != bif); #endif /* Check arguments */ if (NULL == bif) { goto finished; } if (NULL == bif->cf) { goto finished; } /* Retrieve width from current frame */ back = (bif->cf)->dim_y; /* Return */ finished: $? "- dk4bif_get_height %ld", (long)back return back; } const dk4_cs_conv_ctx_t * dk4bif_get_cs_conv_ctx( dk4_bif_t const *bif ) { const dk4_cs_conv_ctx_t *back = NULL; $? "+ dk4bif_get_cs_conv_ctx %d", TR_IPTR(bif) #if DK4_USE_ASSERT assert(NULL != bif); #endif /* Check arguments */ if (NULL == bif) { goto finished; } /* Retrieve address of color space conversion context */ back = &(bif->cs_ctx); /* Return */ finished: $? "- dk4bif_get_cs_conv_ctx %d", TR_IPTR(back) return back; } void dk4bif_set_cs_conv_ctx( dk4_bif_t *bif, dk4_cs_conv_ctx_t const *pctx ) { $? "+ dk4bif_set_cs_conv_ctx bif=%d pctx=%d", TR_IPTR(bif), TR_IPTR(pctx) #if DK4_USE_ASSERT assert(NULL != bif); #endif if ((NULL != bif) && (NULL != pctx)) { DK4_MEMCPY(&(bif->cs_ctx), pctx, sizeof(dk4_cs_conv_ctx_t)); } $? "- dk4bif_set_cs_conv_ctx" } int dk4bif_nc_get_original_pixel( dk4_px_t *dptr, size_t szdptr, dk4_bif_t const *bif, dk4_bif_dim_t rowno, dk4_bif_dim_t colno ) { int back = 0; $? "+ dk4bif_nc_get_original_pixel" #if DK4_USE_ASSERT assert(NULL != bif); assert(NULL != dptr); assert(0 < szdptr); #endif switch (bif->imgtype) { case DK4_BIF_TYPE_PNG : { #if DK4_HAVE_PNG_H back = dk4bifpng_nc_get_original_pixel(dptr, bif, rowno, colno); #endif } break; case DK4_BIF_TYPE_JPEG : { #if DK4_HAVE_JPEGLIB_H back = dk4bifjpeg_nc_get_original_pixel( dptr, szdptr, bif, rowno, colno ); #endif } break; case DK4_BIF_TYPE_TIFF : { #if DK4_HAVE_TIFF_H back = dk4biftiff_nc_get_original_pixel(dptr, bif, rowno, colno); #endif } break; case DK4_BIF_TYPE_NETPBM : { back = dk4bifnetpbm_nc_get_original_pixel(dptr, bif, rowno, colno); } break; /* ##### FURTHER IMAGE TYPES HERE */ } $? "- dk4bif_nc_get_original_pixel %d", back return back; } #if TRACE_DEBUG static void show_pixel_data( dk4_px_t *dptr, size_t szdptr, int cs ) { size_t i; /* Index of current component to process */ size_t max; /* Number of components in color space */ max = dk4cs_color_space_size(cs); if (max > szdptr) { max = szdptr; } for (i = 0; i < max; i++) { $? ". component[%u] = %lu", (unsigned)i, (unsigned long)(dptr[i]) } } #endif int dk4bif_nc_get_pixel( dk4_px_t *dptr, size_t szdptr, dk4_bif_t const *bif, dk4_bif_dim_t rowno, dk4_bif_dim_t colno, int cs ) { dk4_px_t tmp[4]; /* Temporary pixel data */ size_t sztmp = DK4_SIZEOF(tmp,dk4_px_t); int back = 0; $? "+ dk4bif_nc_get_pixel szdptr=%u", (unsigned)szdptr #if DK4_USE_ASSERT assert(NULL != bif); assert(NULL != dptr); assert(0 < szdptr); #endif if ((bif->cf)->l_cs == cs) { $? ". same color space" /* Same color space */ back = dk4bif_nc_get_original_pixel(dptr, szdptr, bif, rowno, colno); $!trace-code show_pixel_data(dptr, szdptr, (bif->cf)->l_cs); if (0 != back) { if ( ((bif->cf)->l_bdepth != (bif->cf)->r_bdepth) || (0 != bif->cf->fmres) ) { /* Bit depth correction required */ $? ". change bit depth" dk4pxres_multiple( dptr, dk4cs_color_space_size(cs), &((bif->cf)->resampler) ); } } #if TRACE_DEBUG else { $? "! dk4bif_nc_get_original_pixel" } #endif } else { $? ". different color spaces" /* Color space conversion required */ back = dk4bif_nc_get_original_pixel(tmp, sztmp, bif, rowno, colno); $!trace-code show_pixel_data(tmp, szdptr, (bif->cf)->l_cs); if (0 != back) { if ( ((bif->cf)->l_bdepth != (bif->cf)->r_bdepth) || (0 != bif->cf->fmres) ) { $? ". different bit depths" /* Bit depth correction required */ if ((bif->cf)->l_bdepth > (bif->cf)->r_bdepth) { $? ". color space conversion before bit depth change" /* Color space conversion first, bit depth later */ dk4cs_nc_px_convert( dptr, cs, tmp, (bif->cf)->l_cs, &((bif->cf)->bglbd[0]), (dk4_px_t)((bif->cf)->resampler.denom), &(bif->cs_ctx) ); dk4pxres_multiple( dptr, dk4cs_color_space_size(cs), &((bif->cf)->resampler) ); } else { $? ". bit depth change before color space conversion" /* Bit depth conversion first, color space later */ dk4pxres_multiple( tmp, dk4cs_color_space_size((bif->cf)->l_cs), &((bif->cf)->resampler) ); dk4cs_nc_px_convert( dptr, cs, tmp, (bif->cf)->l_cs, &((bif->cf)->bg[0]), (dk4_px_t)((bif->cf)->resampler.nom), &(bif->cs_ctx) ); } } else { $? ". same bit depth" /* No bit depth correction, just change color space */ dk4cs_nc_px_convert( dptr, cs, tmp, (bif->cf)->l_cs, &((bif->cf)->bg[0]), (dk4_px_t)((bif->cf)->resampler.denom), &(bif->cs_ctx) ); } } #if TRACE_DEBUG else { $? "! dk4bif_nc_get_original_pixel" } #endif } $? "- dk4bif_nc_get_pixel %d", back return back; } int dk4bif_get_pixel( dk4_px_t *dptr, size_t szdptr, dk4_bif_t const *bif, dk4_bif_dim_t rowno, dk4_bif_dim_t colno, int cs ) { int back = 0; $? "+ dk4bif_get_pixel ptr=%d", TR_IPTR(dptr) #if DK4_USE_ASSERT assert(NULL != bif); assert(NULL != dptr); assert(0 < szdptr); #endif /* Check arguments */ if ((NULL == dptr) || (NULL == bif)) { $? "! dptr/bif" goto finished; } if (0 != bif->hdronly) { $? "! hdronly" goto finished; } if (0 == dk4cs_check(cs)) { $? "! cs" goto finished; } if (szdptr < dk4cs_color_space_size(cs)) { $? "! szdptr" goto finished; } if (((dk4_bif_dim_t)0L > rowno) || ((bif->cf)->dim_y <= rowno)) { $? "! row" goto finished; } if (((dk4_bif_dim_t)0L > colno) || ((bif->cf)->dim_x <= colno)) { $? "! col" goto finished; } back = dk4bif_nc_get_pixel(dptr, szdptr, bif, rowno, colno, cs); $!trace-code show_pixel_data(dptr, szdptr, cs); /* Return, fill default value 0 if there was any problem */ finished: if (0 == back) { if (NULL != dptr) { $? "! zero fill on error" while(0 < szdptr--) { *(dptr++) = 0; } } } $? "- dk4bif_get_pixel %d", back return back; } int dk4bif_get_image_type( dk4_bif_t const *bif ) { int back = -1; #if DK4_USE_ASSERT assert(NULL != bif); #endif if (NULL != bif) { back = bif->imgtype; } return back; } /* vim: set ai sw=4 ts=4 : */