dust3d/thirdparty/cgal/CGAL-5.1/include/CGAL/ImageIO_impl.h

1744 lines
40 KiB
C
Raw Normal View History

// Copyright (c) 2005, 2006 ASCLEPIOS Project, INRIA Sophia-Antipolis (France)
2020-10-13 12:44:25 +00:00
// Copyright (c) 2007 Geometrica Project, INRIA Sophia-Antipolis (France)
// Copyright (c) 2008 GeometryFactory, Sophia-Antipolis (France)
// All rights reserved.
//
2020-10-13 12:44:25 +00:00
// This file is part of the ImageIO Library, and as been adapted for CGAL (www.cgal.org).
//
2020-10-13 12:44:25 +00:00
// $URL: https://github.com/CGAL/cgal/blob/v5.1/CGAL_ImageIO/include/CGAL/ImageIO_impl.h $
// $Id: ImageIO_impl.h 0779373 2020-03-26T13:31:46+01:00 Sébastien Loriot
// SPDX-License-Identifier: LGPL-3.0-or-later
//
#ifdef CGAL_HEADER_ONLY
#define CGAL_INLINE_FUNCTION inline
#else
#define CGAL_INLINE_FUNCTION
#endif
#ifdef _MSC_VER
// Suppress deprecated warning for fileno and strdup
2020-10-13 12:44:25 +00:00
# pragma warning(disable: 4127 4706 4996)
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <io.h>
#include <stdio.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
2020-10-13 12:44:25 +00:00
/* formats actuellement lus
2020-10-13 12:44:25 +00:00
format | extension(s) | lecture | ecriture
INRIMAGE | .inr[.gz] | X | X -> + .gradient[.gz] + .gradient_direction[.gz]
GIS | .dim, .ima[.gz] | X | X
ANALYZE | .hdr, .img[.gz] | X | X
PNM | .ppm, .pgm | X | X
2020-10-13 12:44:25 +00:00
GIF | .gif | X |
BMP | .gif | X |
*/
#include <CGAL/ImageIO/inr.h>
#include <CGAL/ImageIO/gif.h>
#include <CGAL/ImageIO/gis.h>
#include <CGAL/ImageIO/pnm.h>
#include <CGAL/ImageIO/bmp.h>
#include <CGAL/ImageIO/iris.h>
#include <CGAL/ImageIO/analyze.h>
#ifdef MINC_FILES
#include <CGAL/ImageIO/mincio.h>
#endif
#ifdef CGAL_USE_ZLIB
#define ZLIB_MAJOR_VERSION ZLIB_VERNUM>>8
#define ZLIB_MINOR_VERSION (ZLIB_VERNUM-(ZLIB_MAJOR_VERSION <<8))
#define CGAL_USE_GZFWRITE ZLIB_MAJOR_VERSION > 0x12 || ((ZLIB_MAJOR_VERSION == 0x12) && (ZLIB_MINOR_VERSION >= 0x90))
#endif
struct Remove_supported_file_format {
~Remove_supported_file_format()
{
removeSupportedFileFormat();
}
};
#ifdef CGAL_HEADER_ONLY
inline PTRIMAGE_FORMAT & get_static_firstFormat()
{
2020-10-13 12:44:25 +00:00
static PTRIMAGE_FORMAT firstFormat = nullptr;
return firstFormat;
}
inline PTRIMAGE_FORMAT & get_static_inrimageFormat()
{
2020-10-13 12:44:25 +00:00
static PTRIMAGE_FORMAT inrimageFormat = nullptr;
return inrimageFormat;
}
inline Remove_supported_file_format & get_static_rsff()
{
static Remove_supported_file_format rsff;
return rsff;
}
// Dummy call to get_static_rsff(), otherwise it would not get instanced
CGAL_UNUSED static Remove_supported_file_format &rsff_dummy_ref = get_static_rsff();
#else // not header-only
/** the first file format is initialized to null */
2020-10-13 12:44:25 +00:00
static PTRIMAGE_FORMAT firstFormat = nullptr;
inline PTRIMAGE_FORMAT & get_static_firstFormat()
{
return firstFormat;
}
/** the Inrimage file format (default format) is initialized to null */
2020-10-13 12:44:25 +00:00
static PTRIMAGE_FORMAT InrimageFormat = nullptr;
inline PTRIMAGE_FORMAT & get_static_inrimageFormat()
{
return InrimageFormat;
}
static Remove_supported_file_format rsff;
inline Remove_supported_file_format & get_static_rsff()
{
return rsff;
}
#endif
/*--------------------------------------------------
*
* mimics standard routines
*
--------------------------------------------------*/
extern "C" {
/* default allocation routine */
static void *(*allocRoutine)(size_t) = 0;
/* default deallocation routine */
static void (*deleteRoutine)(void *) = 0;
}
CGAL_INLINE_FUNCTION
void *ImageIO_alloc(size_t s) {
if(!allocRoutine) allocRoutine = malloc;
return ( (*allocRoutine)(s) );
}
/* call allocation routine */
CGAL_INLINE_FUNCTION
void ImageIO_free(void *m) {
if(!deleteRoutine) deleteRoutine = free;
(*deleteRoutine)(m);
}
/* call deallocation routine */
CGAL_INLINE_FUNCTION
unsigned int ImageIO_limit_len(size_t to_be_read)
{
return (unsigned int)(std::min)(to_be_read, size_t(1u<<30));
}
/* mimics fwrite() function.
2020-10-13 12:44:25 +00:00
According to _openWriteImage(), openMode will has one
of the following value:
- OM_STD (for stdout)
2020-10-13 12:44:25 +00:00
- OM_GZ
- OM_FILE
*/
CGAL_INLINE_FUNCTION
size_t ImageIO_write(const _image *im, const void *buf, size_t len) {
size_t to_be_written = len;
2020-10-13 12:44:25 +00:00
std::ptrdiff_t l = -1;
char *b = (char*)buf;
switch(im->openMode) {
default :
case OM_CLOSE :
return 0;
case OM_STD :
#ifdef CGAL_USE_ZLIB
while ( (to_be_written > 0) && ((l = gzwrite(im->fd, (void *) b, ImageIO_limit_len(to_be_written))) > 0) ) {
to_be_written -= l;
b += l;
}
2020-10-13 12:44:25 +00:00
#else
while ( (to_be_written > 0) && ((l = fwrite( b, 1, ImageIO_limit_len(to_be_written), im->fd )) > 0) ) {
to_be_written -= l;
b += l;
}
#endif
return ( len - to_be_written );
#ifdef CGAL_USE_ZLIB
case OM_GZ :
while ( (to_be_written > 0) && ((l = gzwrite(im->fd, (void *) b, ImageIO_limit_len(to_be_written))) > 0) ) {
to_be_written -= l;
b += l;
}
if(l<0)
{
int errnum;
fprintf(stderr, "zlib error: %s\n", gzerror(im->fd, &errnum));
}
return ( len - to_be_written );
#if CGAL_USE_GZFWRITE
case OM_FILE :
while ( (to_be_written > 0) && ((l = gzfwrite( b, sizeof(char), ImageIO_limit_len(to_be_written), im->fd )) > 0) ) {
to_be_written -= l;
b += l;
}
return ( len - to_be_written );
#endif // CGAL_USE_GZFWRITE
#else
case OM_FILE :
while ( (to_be_written > 0) && ((l = fwrite( b, 1, ImageIO_limit_len(to_be_written), im->fd )) > 0) ) {
to_be_written -= l;
b += l;
}
return ( len - to_be_written );
#endif
}
}
CGAL_INLINE_FUNCTION
size_t ImageIO_limit_read(size_t to_be_read)
{
return (std::min)(to_be_read, size_t(1u<<30));
}
/* mimics fread() function.
2020-10-13 12:44:25 +00:00
According to _openReadImage(), openMode will has one
of the following value:
- OM_STD (for stdin)
- OM_GZ *or* OM_FILE
*/
CGAL_INLINE_FUNCTION
2020-10-13 12:44:25 +00:00
size_t ImageIO_read(const _image *im, void *buf, size_t len)
{
size_t to_be_read = len;
int l = -1;
char *b = (char*)buf;
switch(im->openMode) {
default :
case OM_CLOSE :
return 0;
case OM_STD :
#ifdef CGAL_USE_ZLIB
while ( (to_be_read > 0) && ((l = gzread(im->fd, (void *) b, ImageIO_limit_len(to_be_read))) > 0) ) {
to_be_read -= l;
b += l;
}
2020-10-13 12:44:25 +00:00
#else
while ( (to_be_read > 0) && ((l = fread( b, 1, ImageIO_limit_len(to_be_read), im->fd )) > 0) ) {
to_be_read -= l;
b += l;
}
#endif
return ( len - to_be_read );
#ifdef CGAL_USE_ZLIB
case OM_GZ :
#if CGAL_USE_GZFWRITE
case OM_FILE :
#endif// CGAL_USE_GZFWRITE
while ( (to_be_read > 0) && ((l = gzread(im->fd, (void *) b, ImageIO_limit_len(to_be_read))) > 0) ) {
to_be_read -= l;
b += l;
}
if(l<0)
{
int errnum;
fprintf(stderr, "zlib error: %s\n", gzerror(im->fd, &errnum));
}
return ( len - to_be_read );
#else
case OM_FILE :
while ( (to_be_read > 0) && ((l = fread( b, 1, ImageIO_limit_len(to_be_read), im->fd )) > 0) ) {
to_be_read -= l;
b += l;
}
return ( len - to_be_read );
#endif
}
//return 0;
}
/* mimics fgets() function.
2020-10-13 12:44:25 +00:00
According to _openReadImage(), openMode will has one
of the following value:
- OM_STD (for stdout)
- OM_GZ *or* OM_FILE
*/
CGAL_INLINE_FUNCTION
char *ImageIO_gets( const _image *im, char *str, int size )
{
2020-10-13 12:44:25 +00:00
char *ret = nullptr;
switch(im->openMode) {
default :
case OM_CLOSE :
2020-10-13 12:44:25 +00:00
return nullptr;
case OM_STD :
#ifdef CGAL_USE_ZLIB
ret = (char *) gzgets(im->fd, str, size );
#else
ret = fgets(str, size, im->fd);
#endif
break;
#ifdef CGAL_USE_ZLIB
case OM_GZ :
#if CGAL_USE_GZFWRITE
case OM_FILE :
#endif // CGAL_USE_GZFWRITE
ret = (char *) gzgets(im->fd, str, size);
break;
2020-10-13 12:44:25 +00:00
#else
case OM_FILE :
ret = fgets(str, size, im->fd);
break;
#endif
}
return ret;
}
CGAL_INLINE_FUNCTION
long ImageIO_seek( const _image *im, long offset, int whence ) {
switch(im->openMode) {
case OM_CLOSE :
default :
return -1;
#ifdef CGAL_USE_ZLIB
case OM_GZ:
#if CGAL_USE_GZFWRITE
case OM_FILE:
#endif //CGAL_USE_GZFWRITE
return gzseek(im->fd, offset, whence );
#else
case OM_FILE:
return fseek( (FILE*)im->fd, offset, whence );
#endif
}
}
/* return non 0 in case of error
*/
CGAL_INLINE_FUNCTION
int ImageIO_error( const _image *im )
{
switch(im->openMode) {
case OM_CLOSE :
default :
return 0;
#ifdef CGAL_USE_ZLIB
case OM_GZ :
#if CGAL_USE_GZFWRITE
case OM_FILE :
#endif //CGAL_USE_GZFWRITE
static int errnum;
(void)gzerror(im->fd, &errnum);
return( (errnum != Z_OK) || gzeof(im->fd) );
#else
case OM_FILE :
return( ferror( (FILE*)im->fd ) || feof( (FILE*)im->fd ) );
#endif
}
//return 0;
}
/* Upon successful completion 0 is returned.
2020-10-13 12:44:25 +00:00
Closing the standard output with gzclose()
is necessary as it will flush the pending output.
*/
CGAL_INLINE_FUNCTION
int ImageIO_close( _image* im )
{
int ret=0;
2020-10-13 12:44:25 +00:00
switch ( im->openMode ) {
default :
case OM_CLOSE :
break;
#ifdef CGAL_USE_ZLIB
case OM_GZ :
case OM_STD :
#if CGAL_USE_GZFWRITE
case OM_FILE :
#endif//CGAL_USE_GZFWRITE
ret = gzclose( im->fd );
break;
2020-10-13 12:44:25 +00:00
#else
case OM_STD :
break;
case OM_FILE :
ret = fclose( (FILE*)im->fd );
#endif
}
2020-10-13 12:44:25 +00:00
im->fd = nullptr;
im->openMode = OM_CLOSE;
2020-10-13 12:44:25 +00:00
return ret;
}
2020-10-13 12:44:25 +00:00
/* given an initialized file descriptor and a file name,
open file from stdin (if name == nullptr, or name == "-", or name == "<"),
or a standard/gzipped file otherwise (gzipped files are handled assuming
2020-10-13 12:44:25 +00:00
that it is compiled and linked with zlib).
openMode will have one of the following value:
- OM_STD (for stdin)
- OM_GZ *or* OM_FILE
*/
CGAL_INLINE_FUNCTION
void _openReadImage(_image* im, const char *name) {
if(im->openMode == OM_CLOSE) {
/* open from stdin */
2020-10-13 12:44:25 +00:00
if( name == nullptr || name[0] == '\0'
|| (name[0] == '-' && name[1] == '\0')
|| (name[0] == '<' && name[1] == '\0') ) {
#ifdef CGAL_USE_ZLIB
im->fd = gzdopen(fileno(stdin), "rb");
#else
im->fd = fdopen(fileno(stdin), "rb");
#endif
im->openMode = OM_STD;
}
else {
2020-10-13 12:44:25 +00:00
#ifdef CGAL_USE_ZLIB
im->fd = gzopen(name, "rb");
if(im->fd) im->openMode = OM_GZ;
#else
im->fd = fopen(name, "rb");
if(im->fd) im->openMode = OM_FILE;
#endif
}
}
}
2020-10-13 12:44:25 +00:00
/* given an initialized file descriptor and a file name,
open file from stdout (if name == nullptr, or name == "-", or name == ">"),
a gzipped pipe (if name got the extension ".gz")
or a standard file otherwise.
openMode will have one of the following value:
- OM_STD (for stdout)
2020-10-13 12:44:25 +00:00
- OM_GZ
- OM_FILE
*/
CGAL_INLINE_FUNCTION
2020-10-13 12:44:25 +00:00
void _openWriteImage(_image* im, const char *name)
{
im->openMode = OM_CLOSE;
2020-10-13 12:44:25 +00:00
if( name == nullptr || name[0] == '\0'
|| (name[0] == '-' && name[1] == '\0')
|| (name[0] == '>' && name[1] == '\0') ) {
#ifdef CGAL_USE_ZLIB
#if (defined _LINUX_) || (defined _SOLARIS_) || (defined _SGI_)
im->fd = gzdopen(1, "wb");
#else
im->fd = gzdopen(fileno(stdout), "wb");
#endif
2020-10-13 12:44:25 +00:00
#else
im->fd = (_ImageIO_file) stdout;
#endif
im->openMode = OM_STD;
}
else{
2020-10-13 12:44:25 +00:00
#ifdef CGAL_USE_ZLIB
/* from gzopen() doc:
... The mode parameter is as in fopen ("rb" or "wb") but can
also include a compression level ("wb9") or a strategy: 'f' for
filtered data as in "wb6f", 'h' for Huffman only compression as
in "wb1h" ...
However, a small .gz header will be written ... thus gz(d)open can not
be used for rgular files.
*/
2020-10-13 12:44:25 +00:00
if( !strncmp(name+strlen(name)-3, ".gz", 3) )
{
#ifdef _MSC_VER
2020-10-13 12:44:25 +00:00
int ffd=_open(name,_O_RDWR | _O_CREAT| _O_TRUNC | _O_BINARY, _S_IREAD|_S_IWRITE);
im->fd = gzdopen( ffd, "wb" );
#else
2020-10-13 12:44:25 +00:00
im->fd = gzopen( name, "wb" );
#endif
2020-10-13 12:44:25 +00:00
im->openMode = OM_GZ;
}
2020-10-13 12:44:25 +00:00
else
{
2020-10-13 12:44:25 +00:00
#if CGAL_USE_GZFWRITE
im->fd = (_ImageIO_file) gzopen(name, "wb");
im->openMode = OM_FILE;
#else
2020-10-13 12:44:25 +00:00
fprintf(stderr, "_openWriteImage: error: zlib version 1.2.9 or later\n"
"is required to save in non-compressed files\n");
return;
#endif// CGAL_USE_GZFWRITE
}
#else //CGAL_USE_ZLIB
{
im->fd = (_ImageIO_file) fopen(name, "wb");
im->openMode = OM_FILE;
}
#endif
}
}
/* set allocation and deallocation routines */
CGAL_INLINE_FUNCTION
void setImageIOAllocationRoutines(ALLOCATION_FUNCTION alloc,
2020-10-13 12:44:25 +00:00
DEALLOCATION_FUNCTION del) {
if(alloc != nullptr) allocRoutine = alloc;
if(del != nullptr) deleteRoutine = del;
}
/*--------------------------------------------------
*
*
*
--------------------------------------------------*/
CGAL_INLINE_FUNCTION
ENDIANNESS _getEndianness()
{
union {
unsigned char uc[2];
unsigned short us;
} twobytes;
twobytes.us = 255;
/* on linux or dec
*/
if ( twobytes.uc[1] == 0 ) return( END_LITTLE );
/* on solaris or sgi
*/
return( END_BIG );
}
/* Allocates and initializes an image descriptor */
CGAL_INLINE_FUNCTION
_image *_initImage() {
_image *im;
im = (_image *) ImageIO_alloc(sizeof(_image));
2020-10-13 12:44:25 +00:00
if ( im == nullptr ) return( im );
/* default image size is 1*1*1 */
im->xdim = im->ydim = im->zdim = im->vdim = 1;
/* default image voxel size is 1.0*1.0*1.0 */
im->vx = im->vy = im->vz = 1.0;
/* default image center is 0 0 0 */
im->cx = im->cy = im->cz = 0;
/* default image offset is 0 0 0 */
im->tx = im->ty = im->tz = 0.0;
/* default image rotation is 0 0 0 */
im->rx = im->ry = im->rz = 0.0;
/* no data yet */
2020-10-13 12:44:25 +00:00
im->data = nullptr;
/* no file associated to image */
2020-10-13 12:44:25 +00:00
im->fd = nullptr;
im->openMode = OM_CLOSE;
im->endianness = END_UNKNOWN;
/* unknown data kind
default is binary
*/
im->dataMode = DM_BINARY;
/* no user string */
2020-10-13 12:44:25 +00:00
im->user = nullptr;
im->nuser = 0;
/* unknown word kind */
im->wdim = 0;
im->wordKind = WK_UNKNOWN;
im->vectMode = VM_SCALAR;
im->sign = SGN_UNKNOWN;
2020-10-13 12:44:25 +00:00
im->imageFormat = nullptr;
/** eventually initializes the supported file formats */
2020-10-13 12:44:25 +00:00
if (get_static_firstFormat()==nullptr)
initSupportedFileFormat();
/* return image descriptor */
return im;
}
CGAL_INLINE_FUNCTION
2020-10-13 12:44:25 +00:00
_image *_createImage(std::size_t x, std::size_t y, std::size_t z, std::size_t v,
double vx, double vy, double vz, std::size_t w,
WORD_KIND wk, SIGN sgn)
{
_image *im;
2020-10-13 12:44:25 +00:00
im = (_image *) ImageIO_alloc(sizeof(_image));
2020-10-13 12:44:25 +00:00
if ( im == nullptr ) return( im );
im->xdim = x;
im->ydim = y;
im->zdim = z;
im->vdim = v;
im->vx = vx;
im->vy = vy;
im->vz = vz;
/* default image center is 0 0 0 */
im->cx = im->cy = im->cz = 0;
/* default image offset is 0 0 0 */
im->tx = im->ty = im->tz = 0.0;
/* default image rotation is 0 0 0 */
im->rx = im->ry = im->rz = 0.0;
/* no data yet */
im->data = ImageIO_alloc(std::size_t(x)*std::size_t(y)*std::size_t(z)*std::size_t(v)*std::size_t(w));
/* no file associated to image */
2020-10-13 12:44:25 +00:00
im->fd = nullptr;
im->openMode = OM_CLOSE;
im->endianness = END_UNKNOWN;
/* unknown data kind
default is binary
*/
im->dataMode = DM_BINARY;
/* no user string */
2020-10-13 12:44:25 +00:00
im->user = nullptr;
im->nuser = 0;
/* unknown word kind */
im->wdim = w;
im->wordKind = wk;
im->vectMode = VM_SCALAR;
im->sign = sgn;
2020-10-13 12:44:25 +00:00
im->imageFormat = nullptr;
/** eventually initializes the supported file formats */
2020-10-13 12:44:25 +00:00
if (get_static_firstFormat()==nullptr)
initSupportedFileFormat();
/* return image descriptor */
return im;
}
/* return the bounding box of the image */
CGAL_INLINE_FUNCTION
void _get_image_bounding_box(_image* im,
2020-10-13 12:44:25 +00:00
double* x_min, double* y_min, double* z_min,
double* x_max, double* y_max, double* z_max) {
*x_min = im->tx;
*y_min = im->ty;
*z_min = im->tz;
*x_max = (double(im->xdim) - 1.0)*(im->vx) + *x_min ;
*y_max = (double(im->ydim) - 1.0)*(im->vy) + *y_min ;
*z_max = (double(im->zdim) - 1.0)*(im->vz) + *z_min ;
}
/* Free an image descriptor */
CGAL_INLINE_FUNCTION
void _freeImage(_image *im) {
unsigned int i;
2020-10-13 12:44:25 +00:00
if ( im == nullptr ) return;
/* close image if opened */
if(im->openMode != OM_CLOSE) ImageIO_close(im);
/* free data if any */
2020-10-13 12:44:25 +00:00
if(im->data != nullptr) ImageIO_free(im->data);
im->data = nullptr;
/* free user string array if any */
2020-10-13 12:44:25 +00:00
if( (im->nuser > 0) && (im->user != nullptr) ) {
for(i = 0; i < im->nuser; i++)
2020-10-13 12:44:25 +00:00
if ( im->user[i] != nullptr ) ImageIO_free(im->user[i]);
ImageIO_free(im->user);
}
im->nuser = 0;
2020-10-13 12:44:25 +00:00
im->user = nullptr;
/* free given descriptor */
ImageIO_free(im);
}
2020-10-13 12:44:25 +00:00
/* Reads an image from a file and returns an image descriptor or nullptr if
reading failed.
2020-10-13 12:44:25 +00:00
Reads from stdin if image name is nullptr. */
CGAL_INLINE_FUNCTION
_image* _readImage(const char *name) {
_image *im;
/* read header */
im = _readImageHeader( name );
2020-10-13 12:44:25 +00:00
if(im != nullptr && im->openMode != OM_CLOSE) {
/* read body */
if(_readImageData(im) < 0) {
fprintf(stderr, "_readImage: error: invalid data encountered in \'%s\'\n",
2020-10-13 12:44:25 +00:00
name);
_freeImage(im);
2020-10-13 12:44:25 +00:00
return nullptr;
}
ImageIO_close(im);
}
return im;
}
// raw
CGAL_INLINE_FUNCTION
_image* _readImage_raw(const char *name,
const unsigned int rx,
const unsigned int ry,
const unsigned int rz,
const double vx,
const double vy,
const double vz,
2020-10-13 12:44:25 +00:00
const unsigned int offset,
const std::size_t wdim,
WORD_KIND wk,
SIGN sgned
)
{
2020-10-13 12:44:25 +00:00
_image *im = nullptr;
im = (_image *) ImageIO_alloc(sizeof(_image));
2020-10-13 12:44:25 +00:00
if ( im == nullptr )
return nullptr;
im->xdim = rx;
im->ydim = ry;
im->zdim = rz;
im->vdim = 1;
im->vx = vx;
im->vy = vy;
im->vz = vz;
// image center
im->cx = im->cy = im->cz = 0;
// image offset
im->tx = im->ty = im->tz = 0.0;
// image rotation
im->rx = im->ry = im->rz = 0.0;
2020-10-13 12:44:25 +00:00
im->fd = nullptr;
im->openMode = OM_CLOSE;
im->endianness = END_UNKNOWN;
im->dataMode = DM_BINARY;
// no user string
2020-10-13 12:44:25 +00:00
im->user = nullptr;
im->nuser = 0;
// word type (unsigned byte)
im->wdim = wdim;
im->wordKind = wk;
im->vectMode = VM_SCALAR;
im->sign = sgned;
2020-10-13 12:44:25 +00:00
im->imageFormat = nullptr;
// read file
::_openReadImage(im, name);
if(!im->fd) {
fprintf(stderr, "_readImage_raw: error: unable to open file \'%s\'\n", name);
_freeImage(im);
2020-10-13 12:44:25 +00:00
return nullptr;
}
// read offset
if(offset > 0) {
im->data = ImageIO_alloc(offset+1);
ImageIO_read(im, im->data, offset);
ImageIO_free(im->data);
}
// allocate memory
im->data = ImageIO_alloc(rx*ry*rz*wdim);
2020-10-13 12:44:25 +00:00
if(im->data == nullptr)
return nullptr;
// read
ImageIO_read(im, im->data, rx*ry*rz*wdim);
ImageIO_close(im);
/*
unsigned int i,j,k;
unsigned char *data = (unsigned char *)im->data;
int dimxy = rx * ry;
for(i=0;i<rx;i++)
for(j=0;j<ry;j++)
for(k=0;k<rz;k++)
{
unsigned char voxel;
fread(&voxel,1,1,pFile);
data[k * dimxy + j * rx + i] = voxel;
}
*/
return im;
}
2020-10-13 12:44:25 +00:00
/* Reads an image from a file and returns an image descriptor or nullptr if<br>
reading failed.<br>
2020-10-13 12:44:25 +00:00
Reads from stdin if image name is nullptr.
If the image is vectorial, it is uninterlaced. */
CGAL_INLINE_FUNCTION
_image* _readNonInterlacedImage(const char *name) {
_image *im;
/* read header */
im = _readImageHeader(name);
if(im && im->openMode != OM_CLOSE) {
/* read scalar image body */
if(im->vdim == 1) {
if(_readImageData(im) < 0) {
2020-10-13 12:44:25 +00:00
fprintf(stderr, "_readImage: error: invalid data encountered in \'%s\'\n",
name);
_freeImage(im);
return nullptr;
}
}
/* read vectorial image body */
else {
im->vectMode = VM_NON_INTERLACED;
if(_readNonInterlacedImageData(im) < 0) {
2020-10-13 12:44:25 +00:00
fprintf(stderr, "_readImage: error: invalid data encountered in \'%s\'\n",
name);
_freeImage(im);
return nullptr;
}
}
ImageIO_close(im);
}
return im;
}
/* Write inrimage given in inr in file name. If file name's suffix is
.gz, the image is gziped. If file name's suffix is .hdr, the image
2020-10-13 12:44:25 +00:00
is written in ANALYZE format. If file name is nullptr, image is written
on stdout */
CGAL_INLINE_FUNCTION
int _writeImage(_image *im, const char *name_to_be_written ) {
int r = ImageIO_NO_ERROR;
std::size_t length = 0;
2020-10-13 12:44:25 +00:00
char *name = nullptr;
char *baseName = nullptr;
2020-10-13 12:44:25 +00:00
if ( im == nullptr ) return -1;
/* different conventions for the standard input
*/
2020-10-13 12:44:25 +00:00
if ( name_to_be_written == nullptr || name_to_be_written[0] == '\0'
|| (name_to_be_written[0] == '-' && name_to_be_written[1] == '\0')
|| (name_to_be_written[0] == '>' && name_to_be_written[1] == '\0') ) {
2020-10-13 12:44:25 +00:00
name = nullptr;
}
else {
name = strdup( name_to_be_written );
}
initSupportedFileFormat();
/* what is the wanted format
*/
2020-10-13 12:44:25 +00:00
if ( name == nullptr ) {
im->imageFormat = get_static_inrimageFormat();
} else {
std::size_t i,extLength;
PTRIMAGE_FORMAT f;
char ext[IMAGE_FORMAT_NAME_LENGTH];
char *ptr;
2020-10-13 12:44:25 +00:00
/* scan all formats; */
2020-10-13 12:44:25 +00:00
im->imageFormat=nullptr;
length=strlen(name);
2020-10-13 12:44:25 +00:00
for(f=get_static_firstFormat();(f!=nullptr)&& (im->imageFormat==nullptr);f=f->next) {
/* scan all extensions for that format */
ptr=&f->fileExtension[0];
do {
2020-10-13 12:44:25 +00:00
/* get next file extension */
i=0;
for(i=0;((*ptr)!=',' && (*ptr)!='\0');i++,ptr++) {
ext[i]=(*ptr);
}
if ((*ptr)==',') {
ext[i]='\0';
ptr++;
}
else {
ext[i]='\0';
}
extLength=strlen(ext);
/* test if the tail of name matches the extension */
if ( (length > extLength) && (!strcmp( name + length - extLength, ext)) ) {
im->imageFormat=f;
/* copy original name and removes extension */
baseName=strdup(name);
for(i= length - extLength;i<length;++i)
baseName[i]='\0';
}
} while (((*ptr)!='\0') && (im->imageFormat==nullptr));
}
2020-10-13 12:44:25 +00:00
if (!im->imageFormat) {
fprintf(stderr, "_writeImage: warning : unknown extension in %s = assuming Inrimage\n",name);
im->imageFormat=get_static_inrimageFormat();
baseName=strdup(name);
}
}
/* open file descriptor */
2020-10-13 12:44:25 +00:00
/* _openWriteImage( im, name ) ;
if(!im->fd) {
fprintf(stderr, "_writeImage: error: open failed\n");
2020-10-13 12:44:25 +00:00
if ( name != nullptr ) free( name );
if ( baseName != nullptr ) free( baseName );
return ImageIO_OPENING;
}
*/
if (im->imageFormat) {
2020-10-13 12:44:25 +00:00
if (im->imageFormat->writeImage==nullptr) {
im->imageFormat=get_static_inrimageFormat();
}
if ( 0 ) {
fprintf(stderr, "_writeImage: will write '%s' with '%s' format\n",
2020-10-13 12:44:25 +00:00
name, im->imageFormat->realName );
}
if ((*im->imageFormat->writeImage)(name, im)<0) {
fprintf(stderr, "_writeImage: error: unable to write \'%s\'\n",
2020-10-13 12:44:25 +00:00
name);
r = ImageIO_WRITING_HEADER;
2020-10-13 12:44:25 +00:00
}
}
2020-10-13 12:44:25 +00:00
/* close file descriptor */
ImageIO_close( im );
2020-10-13 12:44:25 +00:00
im->fd = nullptr;
im->openMode = OM_CLOSE;
2020-10-13 12:44:25 +00:00
if ( baseName != nullptr ) free( baseName );
if ( name != nullptr ) free( name );
return r;
}
2020-10-13 12:44:25 +00:00
/* read header from an image file
if standard input, it's an inrimage
if not, get a magic string
and try to find the good format
if data are in a separate file,
the header reading procedure will open
the data file.
error:
0 success
-1 unknown image type
-2 error while opening
-3 error while reading header
-4 error while reading header or data
*/
CGAL_INLINE_FUNCTION
_image *_readImageHeader( const char *name ) {
int error = 0;
return( _readImageHeaderAndGetError( name, &error ) );
}
CGAL_INLINE_FUNCTION
_image *_readImageHeaderAndGetError( const char *name_to_be_read, int *error )
{
_image *im;
char magic[5];
2020-10-13 12:44:25 +00:00
char *name = nullptr;
PTRIMAGE_FORMAT f;
int res;
*error = ImageIO_NO_ERROR;
2020-10-13 12:44:25 +00:00
/* open image file */
im = _initImage();
2020-10-13 12:44:25 +00:00
if ( name_to_be_read == nullptr || name_to_be_read[0] == '\0'
|| (name_to_be_read[0] == '-' && name_to_be_read[1] == '\0')
|| (name_to_be_read[0] == '<' && name_to_be_read[1] == '\0') ) {
2020-10-13 12:44:25 +00:00
name = nullptr;
}
else {
name = strdup( name_to_be_read );
}
2020-10-13 12:44:25 +00:00
_openReadImage(im, name);
if(!im->fd) {
2020-10-13 12:44:25 +00:00
if(name == nullptr) {
fprintf(stderr, "_readImageHeaderAndGetError: error: nullptr file name\n");
} else {
fprintf(stderr, "_readImageHeaderAndGetError: error: unable to open file \'%s\'\n", name);
}
_freeImage(im);
*error = ImageIO_OPENING;
2020-10-13 12:44:25 +00:00
if ( name != nullptr ) free( name );
return nullptr;
}
initSupportedFileFormat();
2020-10-13 12:44:25 +00:00
/* what is the wanted format ?
assume that stdin is inrimage
*/
if(im->openMode == OM_STD) {
im->imageFormat=get_static_inrimageFormat();
}
else {
/* get magic string for disk files
*/
ImageIO_read(im, magic, 4);
magic[4] = '\0';
ImageIO_seek(im, 0L, SEEK_SET);
/** test each format */
2020-10-13 12:44:25 +00:00
for(f=get_static_firstFormat();(f!=nullptr)&& (im->imageFormat==nullptr);f=f->next) {
/* test if it is the correct format based on magic and file extension */
if (((*f->testImageFormat)(magic, name)) >=0) {
2020-10-13 12:44:25 +00:00
im->imageFormat=f;
}
}
}
2020-10-13 12:44:25 +00:00
if ( im->imageFormat == nullptr ) {
fprintf(stderr, "_readImageHeaderAndGetError: does not find image format for \'%s\'\n", name);
ImageIO_close( im );
_freeImage(im);
*error = ImageIO_UNKNOWN_TYPE;
2020-10-13 12:44:25 +00:00
if ( name != nullptr ) free( name );
return nullptr;
}
/* now tests if the header can be read correctly */
2020-10-13 12:44:25 +00:00
res=(*(im->imageFormat)->readImageHeader)(name,im);
2020-10-13 12:44:25 +00:00
/* could read header only */
if (res == 0) {
2020-10-13 12:44:25 +00:00
if ( name != nullptr ) free( name );
return( im );
2020-10-13 12:44:25 +00:00
}
/* could read header and data */
else if ( res > 0 ) {
ImageIO_close(im);
2020-10-13 12:44:25 +00:00
if ( name != nullptr ) free( name );
return im;
2020-10-13 12:44:25 +00:00
}
/* could not read error : throw error */
fprintf(stderr, "_readImageHeaderAndGetError: an error occurs when reading image\n" );
2020-10-13 12:44:25 +00:00
if ( name == nullptr || im->openMode == OM_STD) {
fprintf(stderr, "\t from \'standard input\'" );
}
else {
fprintf(stderr, "\t from file \'%s\'", name );
}
fprintf(stderr, " using format \'%s\'\n", (im->imageFormat)->realName );
ImageIO_close( im );
_freeImage(im);
*error = ImageIO_READING_HEADER;
2020-10-13 12:44:25 +00:00
if ( name != nullptr ) free( name );
return nullptr;
}
CGAL_INLINE_FUNCTION
2020-10-13 12:44:25 +00:00
static void _swapImageData( _image *im )
{
unsigned char *ptr1, *ptr2, b[8];
unsigned short int si, *ptr3, *ptr4;
unsigned int i, *ptr5, *ptr6;
std::size_t size, length;
2020-10-13 12:44:25 +00:00
if( _getEndianness() != im->endianness) {
size = std::size_t(im->xdim) * im->ydim * im->zdim * im->vdim * im->wdim;
if ( size <= 0 ) return;
length = size / im->wdim;
ptr1 = ptr2 = (unsigned char *) im->data;
2020-10-13 12:44:25 +00:00
/* 2 bytes swap */
if(im->wdim == 2) {
/*
2020-10-13 12:44:25 +00:00
while(length--) {
b[0] = *ptr1++;
b[1] = *ptr1++;
*ptr2++ = b[1];
*ptr2++ = b[0];
}
*/
ptr3 = ptr4 = (unsigned short int *) im->data;
while( length-- ) {
2020-10-13 12:44:25 +00:00
si = *ptr3++;
*ptr4++ = (unsigned short int)(((si >> 8) & 0xff) | (si << 8));
}
}
2020-10-13 12:44:25 +00:00
/* 4 bytes swap */
else if(im->wdim == 4) {
/*
2020-10-13 12:44:25 +00:00
while(length--) {
b[0] = *ptr1++;
b[1] = *ptr1++;
b[2] = *ptr1++;
b[3] = *ptr1++;
*ptr2++ = b[3];
*ptr2++ = b[2];
*ptr2++ = b[1];
*ptr2++ = b[0];
}
*/
ptr5 = ptr6 = (unsigned int *) im->data;
while( length-- ) {
2020-10-13 12:44:25 +00:00
i = *ptr5++;
*ptr6++ = (i << 24) | ((i & 0xff00) << 8) | ((i >> 8) & 0xff00) | ((i >> 24) & 0xff);
}
}
/* 8 bytes swap */
else if(im->wdim == 8) {
while(length--) {
2020-10-13 12:44:25 +00:00
b[0] = *ptr1++;
b[1] = *ptr1++;
b[2] = *ptr1++;
b[3] = *ptr1++;
b[4] = *ptr1++;
b[5] = *ptr1++;
b[6] = *ptr1++;
b[7] = *ptr1++;
*ptr2++ = b[7];
*ptr2++ = b[6];
*ptr2++ = b[5];
*ptr2++ = b[4];
*ptr2++ = b[3];
*ptr2++ = b[2];
*ptr2++ = b[1];
*ptr2++ = b[0];
}
}
}
}
/* Read data of an inrimage.
2020-10-13 12:44:25 +00:00
If im->data is not nullptr, assume that the buffer was previously allocated
Swap bytes depending on the endianness and the current architecture */
CGAL_INLINE_FUNCTION
int _readImageData(_image *im) {
unsigned long size, nread;
if(im->openMode != OM_CLOSE) {
size = im->xdim * im->ydim * im->zdim * im->vdim * im->wdim;
2020-10-13 12:44:25 +00:00
if ( size <= 0 ) return -3;
if(!im->data) {
im->data = (unsigned char *) ImageIO_alloc(size);
if(!im->data) return -2;
}
nread = ImageIO_read(im, im->data, size);
if(nread != size) return -1;
2020-10-13 12:44:25 +00:00
/* architecture is big endian and data little endian
length = nb of points
*/
_swapImageData( im );
}
return 1;
}
/* Read data of a vectorial inrimage, making the resulting buffer non-
inerlaced.
2020-10-13 12:44:25 +00:00
If im->data is not nullptr, assume that the buffer was previously allocated
Swap bytes depending on the endianness and the current architecture. */
CGAL_INLINE_FUNCTION
int _readNonInterlacedImageData(_image *im) {
unsigned long size, nread;
unsigned char **vp, *buf;
unsigned int i, j, k, v, w;
if(im->vdim == 1) return _readImageData(im);
2020-10-13 12:44:25 +00:00
if(im->openMode != OM_CLOSE) {
size = im->xdim * im->ydim * im->zdim * im->vdim * im->wdim;
if ( size <= 0 ) return -3;
if(!im->data) {
im->data = (unsigned char *) ImageIO_alloc(size);
if(!im->data) return -2;
}
vp = (unsigned char **) ImageIO_alloc(im->vdim * sizeof(unsigned char *));
buf = (unsigned char *) ImageIO_alloc(im->vdim * im->wdim);
size = im->xdim * im->ydim * im->zdim * im->wdim;
for(v = 0; v < im->vdim; v++)
vp[v] = (unsigned char *) im->data + v * size;
for(k = 0; k < im->zdim; k++) {
for(j = 0; j < im->ydim; j++) {
2020-10-13 12:44:25 +00:00
for(i = 0; i < im->xdim; i++) {
nread = ImageIO_read(im, buf, im->vdim * im->wdim);
if(nread != im->vdim * im->wdim) return -1;
for(v = 0; v < im->vdim; v++)
for(w = 0; w < im->wdim; w++)
*vp[v]++ = *buf++;
buf -= im->vdim * im->wdim;
}
}
}
ImageIO_free(buf);
ImageIO_free(vp);
/* architecture is big endian and data little endian */
_swapImageData( im );
2020-10-13 12:44:25 +00:00
/* reorder lines */
/* no non-interlaced data for ANALYZE. But if ever... */
/* if( im->imageFormat == IF_ANALYZE ) { */
/* int v ; */
/* int vdim = im->vdim ; */
/* int lineSize = im->wdim * im->xdim ; */
/* int vsize = lineSize * im->ydim * im->zdim ; */
/* char* swapped = ImageIO_alloc(lineSize) ; */
/* for( v = 0 ; v < vdim ; ++v ) */
/* { */
2020-10-13 12:44:25 +00:00
/* char* buf1 = (char*)im->data + v*vsize ; */
/* char* buf2 = buf1 + vsize - lineSize ; */
/* while( buf1 < buf2 ) */
/* { */
/* memcpy( swapped, buf1, lineSize ) ; */
/* memcpy( buf1, buf2, lineSize ) ; */
/* memcpy( buf2, swapped, lineSize ) ; */
/* buf1 += lineSize ; */
/* buf2 -= lineSize ; */
/* } */
/* ImageIO_free( swapped ) ; */
/* } */
/* } */
}
return 1;
}
/* Reads body from a non-interlaced vectorial inrimage whose header has
been read by _readImageHeader. The image buffer is interlaced. */
CGAL_INLINE_FUNCTION
int _readNonInterlacedFileData(_image *im) {
unsigned long size, nread;
unsigned char *ptr1, *vp, *buf;
unsigned int i, j, k, v, w;
if(im->vdim == 1) return _readImageData(im);
if(im->openMode != OM_CLOSE) {
size = im->xdim * im->ydim * im->zdim * im->vdim * im->wdim;
if ( size <= 0 ) return -3;
if(!im->data) {
im->data = (unsigned char *) ImageIO_alloc(size);
if(!im->data) return -2;
}
size = im->xdim * im->ydim * im->zdim * im->wdim;
buf = ptr1 = (unsigned char *) ImageIO_alloc(size);
for(v = 0; v < im->vdim; v++) {
buf = ptr1;
nread = ImageIO_read(im, buf, size);
if(nread != size) return -1;
vp = (unsigned char *) im->data + (v * im->wdim);
for(k = 0; k < im->zdim; k++) {
2020-10-13 12:44:25 +00:00
for(j = 0; j < im->ydim; j++) {
for(i = 0; i < im->xdim; i++) {
for(w = 0; w < im->wdim; w++) *vp++ = *buf++;
vp += (im->vdim - 1) * im->wdim;
}
}
}
}
ImageIO_free(buf);
/* architecture is big endian and data little endian */
_swapImageData( im );
2020-10-13 12:44:25 +00:00
/* reorder lines */
/* no non-interlaced data for ANALYZE. But if ever... */
/* if( im->imageFormat == IF_ANALYZE ) { */
/* int v ; */
/* int vdim = im->vdim ; */
/* int lineSize = im->wdim * im->xdim ; */
/* int vsize = lineSize * im->ydim * im->zdim ; */
/* char* swapped = ImageIO_alloc(lineSize) ; */
/* for( v = 0 ; v < vdim ; ++v ) */
/* { */
2020-10-13 12:44:25 +00:00
/* char* buf1 = (char*)im->data + v*vsize ; */
/* char* buf2 = buf1 + vsize - lineSize ; */
/* while( buf1 < buf2 ) */
/* { */
/* memcpy( swapped, buf1, lineSize ) ; */
/* memcpy( buf1, buf2, lineSize ) ; */
/* memcpy( buf2, swapped, lineSize ) ; */
/* buf1 += lineSize ; */
/* buf2 -= lineSize ; */
/* } */
/* ImageIO_free( swapped ) ; */
/* } */
/* } */
}
2020-10-13 12:44:25 +00:00
return 1;
}
/*--------------------------------------------------
*
* ?????
*
--------------------------------------------------*/
/* check the type of image in fileName */
CGAL_INLINE_FUNCTION
PTRIMAGE_FORMAT imageType(const char *fileName) {
_ImageIO_file f;
char magic[5];
PTRIMAGE_FORMAT format;
if(!fileName) {
2020-10-13 12:44:25 +00:00
#ifdef CGAL_USE_ZLIB
f = gzdopen(fileno(stdin), "rb");
#else
f = fdopen(fileno(stdin), "rb");
#endif
}
else {
2020-10-13 12:44:25 +00:00
#ifdef CGAL_USE_ZLIB
f = gzopen(fileName, "rb");
#else
f = fopen(fileName, "rb");
#endif
}
2020-10-13 12:44:25 +00:00
if(!f) return nullptr;
#ifdef CGAL_USE_ZLIB
gzread( f, (void *) magic, 4);
#else
fread( (void *) magic, 1, 4, f );
#endif
magic[4] = '\0';
2020-10-13 12:44:25 +00:00
#ifdef CGAL_USE_ZLIB
gzclose( f );
#else
if(fileName) fclose( f );
#endif
2020-10-13 12:44:25 +00:00
if (get_static_firstFormat()==nullptr)
initSupportedFileFormat();
2020-10-13 12:44:25 +00:00
for(format=get_static_firstFormat();(format!=nullptr);format=format->next) {
/* test if it is the correct header based on magic and file extension */
if (((*format->testImageFormat)(magic,fileName)) >=0) {
return format;
}
}
return 0;
}
/*--------------------------------------------------
*
* Image Format Management
*
--------------------------------------------------*/
2020-10-13 12:44:25 +00:00
/** adds a format at the beginning of the list of image formats.
Test if all mandatory fields have been filled */
CGAL_INLINE_FUNCTION
2020-10-13 12:44:25 +00:00
int addImageFormat( PTRIMAGE_FORMAT format)
{
if ( (format->testImageFormat) &&
(format->readImageHeader) &&
(strlen(format->fileExtension)>0) &&
(strlen(format->realName)>0) ) {
format->next=get_static_firstFormat();
get_static_firstFormat()=format;
2020-10-13 12:44:25 +00:00
return 0;
2020-10-13 12:44:25 +00:00
}
else {
fprintf(stderr,"addImageFormat: information missing in file format %s\n",
2020-10-13 12:44:25 +00:00
format->realName);
return -1;
}
}
2020-10-13 12:44:25 +00:00
/** adds a format at the end of the list of image formats.
Test if all mandatory fields have been filled */
CGAL_INLINE_FUNCTION
2020-10-13 12:44:25 +00:00
int addImageFormatAtEnd( PTRIMAGE_FORMAT format)
{
PTRIMAGE_FORMAT f;
if ( (format->testImageFormat) &&
(format->readImageHeader) &&
(strlen(format->fileExtension)>0) &&
(strlen(format->realName)>0) ) {
2020-10-13 12:44:25 +00:00
format->next = nullptr;
if (get_static_firstFormat() == nullptr) {
get_static_firstFormat()=format;
}
else {
2020-10-13 12:44:25 +00:00
for(f=get_static_firstFormat();(f->next!=nullptr);f=f->next)
;
f->next=format;
}
2020-10-13 12:44:25 +00:00
return 0;
2020-10-13 12:44:25 +00:00
}
else {
fprintf(stderr,"addImageFormatAtEnd: information missing in file format %s\n",
2020-10-13 12:44:25 +00:00
format->realName);
return -1;
}
}
/** creates supported image formats */
CGAL_INLINE_FUNCTION
2020-10-13 12:44:25 +00:00
void initSupportedFileFormat()
{
PTRIMAGE_FORMAT f;
2020-10-13 12:44:25 +00:00
if ( get_static_inrimageFormat() == nullptr ) {
f = createAnalyzeFormat();
addImageFormatAtEnd( f );
f = createBMPFormat();
addImageFormatAtEnd( f );
f = createGifFormat();
addImageFormatAtEnd( f );
f = createGisFormat();
addImageFormatAtEnd( f );
f = createIrisFormat();
addImageFormatAtEnd( f );
f = createPgmFormat();
addImageFormatAtEnd( f );
f = createPgmAscIIFormat();
addImageFormatAtEnd( f );
f = createPpmFormat();
addImageFormatAtEnd( f );
get_static_inrimageFormat() = createInrimageFormat();
addImageFormat( get_static_inrimageFormat() );
}
}
CGAL_INLINE_FUNCTION
PTRIMAGE_FORMAT firstImageFormat() {
return get_static_firstFormat();
}
/** prints supported image formats */
CGAL_INLINE_FUNCTION
2020-10-13 12:44:25 +00:00
void printSupportedFileFormat() {
PTRIMAGE_FORMAT f;
int i;
initSupportedFileFormat();
2020-10-13 12:44:25 +00:00
for(i=0, f=get_static_firstFormat();(f!=nullptr);i++, f=f->next) {
if ( (f->testImageFormat) &&
2020-10-13 12:44:25 +00:00
(f->readImageHeader) &&
(strlen(f->fileExtension)>0) &&
(strlen(f->realName)>0)) {
fprintf( stderr, "#%2d: format name ='%s', extensions='%s'",
2020-10-13 12:44:25 +00:00
i, f->realName, f->fileExtension );
if (f->readImageHeader)
fprintf( stderr, ", read" );
if (f->writeImage)
fprintf( stderr, ", write" );
fprintf( stderr, "\n" );
}
}
}
/** remove supported image formats */
CGAL_INLINE_FUNCTION
2020-10-13 12:44:25 +00:00
void removeSupportedFileFormat() {
PTRIMAGE_FORMAT f=get_static_firstFormat();
2020-10-13 12:44:25 +00:00
while( f != nullptr) {
PTRIMAGE_FORMAT f_old = f;
f = f->next;
ImageIO_free( f_old);
}
2020-10-13 12:44:25 +00:00
get_static_inrimageFormat()=nullptr;
}
/** trilinear interpolation in an _image float type
*/
CGAL_INLINE_FUNCTION
float triLinInterp(const _image* image,
2020-10-13 12:44:25 +00:00
float posx,
float posy,
float posz,
float value_outside /*= 0.f */)
{
const std::size_t dimx = image->xdim;
const std::size_t dimy = image->ydim;
const std::size_t dimz = image->zdim;
const std::size_t dimxy = dimx*dimy;
2020-10-13 12:44:25 +00:00
if(posx < 0.f || posy < 0.f || posz < 0.f )
return value_outside;
posx = static_cast<float>(posx /(image->vx));
posy = static_cast<float>(posy /(image->vy));
posz = static_cast<float>(posz /(image->vz));
//patch suggested by J.Cugnoni to prevent integer overflow
if(posz >= float(dimz-1) || posy >= float(dimy-1) || posx >= float(dimx-1))
return value_outside;
2020-10-13 12:44:25 +00:00
const int i1 = (int)(posz);
const int j1 = (int)(posy);
const int k1 = (int)(posx);
const int i2 = i1 + 1;
const int j2 = j1 + 1;
const int k2 = k1 + 1;
const float KI2 = float(i2)-posz;
const float KI1 = posz-float(i1);
const float KJ2 = float(j2)-posy;
const float KJ1 = posy-float(j1);
CGAL_IMAGE_IO_CASE
(image,
Word *array = (Word *) image->data;
return (((float)array[i1 * dimxy + j1 * dimx + k1] * KI2 +
(float)array[i2 * dimxy + j1 * dimx + k1] * KI1) * KJ2 +
((float)array[i1 * dimxy + j2 * dimx + k1] * KI2 +
(float)array[i2 * dimxy + j2 * dimx + k1] * KI1) * KJ1) * (float(k2)-posx)+
(((float)array[i1 * dimxy + j1 * dimx + k2] * KI2 +
(float)array[i2 * dimxy + j1 * dimx + k2] * KI1) * KJ2 +
((float)array[i1 * dimxy + j2 * dimx + k2] * KI2 +
(float)array[i2 * dimxy + j2 * dimx + k2] * KI1) * KJ1) * (posx-float(k1));
);
return 0.f;
}
// Gives the value of the image at pixel (i,j,k), converted in float.
CGAL_INLINE_FUNCTION
float evaluate(const _image* image,
const std::size_t i,
const std::size_t j,
const std::size_t k)
{
using CGAL::IMAGEIO::static_evaluate;
CGAL_IMAGE_IO_CASE(image, return (float)static_evaluate<Word>(image, i, j, k); );
return 0.f;
}
2020-10-13 12:44:25 +00:00
/** convert the data of the image to float
*/
CGAL_INLINE_FUNCTION
2020-10-13 12:44:25 +00:00
void convertImageTypeToFloat(_image* image){
if(image->wordKind == WK_FLOAT && image->wdim == 4)
return;
const std::size_t dimx = image->xdim;
const std::size_t dimy = image->ydim;
const std::size_t dimz = image->zdim;
2020-10-13 12:44:25 +00:00
float * array = (float*)ImageIO_alloc (dimx * dimy * dimz *sizeof(float));
2020-10-13 12:44:25 +00:00
if (array == nullptr ) {
fprintf ( stderr, "allocation error\n" );
return;
}
CGAL_IMAGE_IO_CASE
2020-10-13 12:44:25 +00:00
(image,
Word * typedArray = (Word *)(image->data);
for(unsigned int i = 0; i<dimx * dimy * dimz;++i)
array[i] = (float)(typedArray[i]);
);
ImageIO_free ( image->data );
image->data = array;
2020-10-13 12:44:25 +00:00
image->wordKind = WK_FLOAT;
image->wdim = 4;
}