%% options copyright owner = Dirk Krause copyright year = 2017-xxxx SPDX-License-Identifier: BSD-3-Clause %% module #include "dk4conf.h" $!trace-include #if DK4_HAVE_TIFF_H #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 DK4MAAL_H_INCLUDED #include "dk4maal.h" #endif #if DK4_HAVE_ASSERT_H #ifndef ASSERT_H_INCLUDED #include #define ASSERT_H_INCLUDED 1 #endif #endif void dk4biftiff_nc_release_per_frame_data( void *tsdata ) { dk4_bif_tiff_per_frame_t *pfd = NULL; /* Per-frame data */ $? "+ dk4biftiff_nc_release_per_frame_data" #if DK4_USE_ASSERT assert(NULL != tsdata); #endif pfd = (dk4_bif_tiff_per_frame_t *)tsdata; if (NULL != pfd) { if (NULL != pfd->rows) { $? ". release pfd->rows" _TIFFfree(pfd->rows); pfd->rows = NULL; } $? ". release pfd" dk4mem_free(pfd); } $? "- dk4biftiff_nc_release_per_frame_data" } dk4_bif_t * dk4biftiff_nc_open_type( dkChar const *fn, dk4_cs_conv_ctx_t const *pcsctx, dk4_er_t *erp ) { dk4_er_t er; /* Error report for math op */ dk4_bif_tiff_per_frame_t *pfd = NULL; /* Per-frame data */ dk4_bif_t *back = NULL; TIFF *tiff = NULL; /* TIFF file */ double xrv; /* Temporary resolution valuej */ float rv; /* Temporary resolution value */ uint32 w; /* Frame width */ uint32 h; /* Frame height */ int ok = 0; /* Flag: Success */ int cc = 0; /* Flag: Can continue */ uint16 ru; /* Resolution unit */ uint16 orie; /* Orientation */ tsize_t nby; /* Byte number to allocate */ $? "+ dk4biftiff_nc_open_type" back = dk4biftool_nc_new_for_one_frame( fn, DK4_BIF_TYPE_TIFF, 0, pcsctx, erp ); if (NULL == back) { goto finished; } $? ". bif allocated" pfd = dk4mem_new(dk4_bif_tiff_per_frame_t,1,NULL); if (NULL == pfd) { goto finished; } pfd->rows = NULL; $? ". per-frame structure allocated" back->cf->tsdata = pfd; #if (DK4_CHAR_SIZE > 1) && (DK4_ON_WINDOWS) tiff = TIFFOpenW(fn, "rb"); #else tiff = TIFFOpen(fn, "rb"); #endif if (NULL == tiff) { goto finished; } $? ". TIFF file opened" /* Traverse all frames */ ok = 1; do { cc = 0; w = 0UL; h = 0UL; /* Read image width and height */ if (1 == TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &w)) { back->cf->dim_x = w; } else { $? "! failed to read width" w = 0UL; } if (1 == TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &h)) { back->cf->dim_y = h; } else { $? "! failed to read height" h = 0UL; } /* Read resolution */ rv = 0.0; if (1 == TIFFGetField(tiff, TIFFTAG_XRESOLUTION, &rv)) { back->cf->res_x = rv; $? ". x resolution %g", rv } rv = 0.0; if (1 == TIFFGetField(tiff, TIFFTAG_YRESOLUTION, &rv)) { back->cf->res_y = rv; $? ". y resolution %g", rv } ru = 0; if (1 == TIFFGetField(tiff, TIFFTAG_RESOLUTIONUNIT, &ru)) { if (RESUNIT_CENTIMETER == ru) { $? ". resolution in cm" back->cf->res_x *= 2.54; back->cf->res_y *= 2.54; } } if ((0.0 >= back->cf->res_x) || (0.0 >= back->cf->res_y)) { back->cf->res_x = back->cf->res_y = -1.0; $? ". at least one illegal resolution value" } /* Read orientation, swap x and y coordinates if necessary */ orie = ORIENTATION_TOPLEFT; if (1 == TIFFGetFieldDefaulted(tiff, TIFFTAG_ORIENTATION, &orie)) { switch (orie) { case 5: case 6: case 7: case 8: { $? ". swap x/y" back->cf->dim_x = h; back->cf->dim_y = w; xrv = back->cf->res_x; back->cf->res_x = back->cf->res_y; back->cf->res_y = xrv; } break; } } else { orie = ORIENTATION_TOPLEFT; } /* Calculate byte number */ dk4error_init(&er); nby = dk4ma_long_mul( dk4ma_long_mul(w, h, &er), 4L, &er ); /* Read image data */ if ((DK4_E_NONE == er.ec) && (0L < w) && (0L < h)) { pfd->rows = (uint32 *)_TIFFmalloc(nby); if (NULL != pfd->rows) { if (1 == TIFFReadRGBAImageOriented(tiff,w,h,pfd->rows,orie,0)) { back->cf->bg[0] = 255; $? ". image read successfully" back->cf->bg[1] = 255; back->cf->bg[2] = 255; back->cf->bg[3] = 255; back->cf->bglbd[0] = 255; back->cf->bglbd[1] = 255; back->cf->bglbd[2] = 255; back->cf->bglbd[3] = 255; dk4pxres_setup(&(back->cf->resampler), 8, 8); back->cf->l_bdepth = back->cf->r_bdepth = 8; back->cf->n_comp = 4; back->cf->l_cs = back->cf->f_cs = DK4_CS_RGB_ALPHA; back->cf->hbg = 0; } else { $? "! failed to read image" dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); cc = -1; ok = 0; } } else { $? "! rows allocation failed" dk4error_set_elsize_nelem( erp, DK4_E_MEMORY_ALLOCATION_FAILED, nby, 1 ); cc = -1; ok = 0; } } else { $? ". math overflow or w or h 0" dk4error_set_simple_error_code(erp, DK4_E_SYNTAX); cc = -1; ok = 0; } /* Attempt to read one further frame */ if (0 == cc) { if (1 == TIFFReadDirectory(tiff)) { $? ". further frame available" if (0 != dk4biftool_nc_add_frame(back, erp)) { pfd = dk4mem_new(dk4_bif_tiff_per_frame_t,1,NULL); if (NULL != pfd) { $? ". pfd allocated" pfd->rows = NULL; back->cf->tsdata = pfd; cc = 1; } else { $? "! failed to allocate pfd" dk4error_set_elsize_nelem( erp, DK4_E_MEMORY_ALLOCATION_FAILED, sizeof(dk4_bif_tiff_per_frame_t), 1 ); ok = 0; cc = -1; } } else { $? "! failed to add frame" ok = 0; cc = -1; } } } } while (1 == cc); finished: if (NULL != tiff) { $? ". closing TIFF file" TIFFClose(tiff); } if (0 == ok) { if (NULL != back) { $? "! releasing bif structure due to errors" dk4bif_close(back); back = NULL; } } $? "- dk4biftiff_nc_open_type %d", TR_IPTR(back) return back; } int dk4biftiff_nc_get_original_pixel( dk4_px_t *dptr, dk4_bif_t const *bif, dk4_bif_dim_t rowno, dk4_bif_dim_t colno ) { dk4_bif_tiff_per_frame_t *pfd = NULL; /* Per-frame data */ uint32 abgr; /* Pixel index in array */ int back = 0; $? "+ dk4biftiff_nc_get_original_pixel" #if DK4_USE_ASSERT assert(NULL != dptr); assert(NULL != bif); #endif if (NULL == bif->cf->tsdata) { $? "! no per-frame data" goto finished; } pfd = (dk4_bif_tiff_per_frame_t *)(bif->cf->tsdata); abgr = (pfd->rows)[(rowno * bif->cf->dim_x) + colno]; dptr[0] = TIFFGetR(abgr); dptr[1] = TIFFGetG(abgr); dptr[2] = TIFFGetB(abgr); dptr[3] = TIFFGetA(abgr); back = 1; finished: $? "- dk4biftiff_nc_get_original_pixel %d", back return back; } #endif /* if DK4_HAVE_TIFF_H */ /* vim: set ai sw=4 ts=4 : */