From a4afce92b639c6f3e151a9894363265bac6078a5 Mon Sep 17 00:00:00 2001 From: Guillaume Damiand Date: Mon, 16 Mar 2015 16:11:01 +0100 Subject: [PATCH] Image_3, ImageIO, vmpendian and fgets --- CGAL_ImageIO/include/CGAL/ImageIO.h | 3 + CGAL_ImageIO/include/CGAL/ImageIO_impl.h | 1626 +++++++++++++++++ CGAL_ImageIO/include/CGAL/Image_3.h | 4 +- CGAL_ImageIO/include/CGAL/Image_3_impl.h | 232 +++ CGAL_ImageIO/src/CGAL_ImageIO/ImageIO.cpp | 1567 +--------------- CGAL_ImageIO/src/CGAL_ImageIO/Image_3.cpp | 205 +-- CGAL_ImageIO/src/CGAL_ImageIO/bmpendian.cpp | 220 +-- CGAL_ImageIO/src/CGAL_ImageIO/bmpendian.h | 4 + .../src/CGAL_ImageIO/bmpendian_impl.h | 257 +++ CGAL_ImageIO/src/CGAL_ImageIO/fgetns.cpp | 22 +- CGAL_ImageIO/src/CGAL_ImageIO/fgetns.h | 9 + CGAL_ImageIO/src/CGAL_ImageIO/fgetns_impl.h | 48 + cppfiles.txt | 12 +- 13 files changed, 2203 insertions(+), 2006 deletions(-) create mode 100644 CGAL_ImageIO/include/CGAL/ImageIO_impl.h create mode 100644 CGAL_ImageIO/include/CGAL/Image_3_impl.h create mode 100644 CGAL_ImageIO/src/CGAL_ImageIO/bmpendian_impl.h create mode 100644 CGAL_ImageIO/src/CGAL_ImageIO/fgetns_impl.h diff --git a/CGAL_ImageIO/include/CGAL/ImageIO.h b/CGAL_ImageIO/include/CGAL/ImageIO.h index 29978fdd3da..677a6d77e93 100644 --- a/CGAL_ImageIO/include/CGAL/ImageIO.h +++ b/CGAL_ImageIO/include/CGAL/ImageIO.h @@ -700,5 +700,8 @@ CGAL_IMAGEIO_EXPORT float evaluate(const _image* image,const std::size_t i,const */ CGAL_IMAGEIO_EXPORT void convertImageTypeToFloat(_image* image); +#ifdef CGAL_HEADER_ONLY +#include "ImageIO_impl.h" +#endif // CGAL_HEADER_ONLY #endif // end IMAGEIO_H diff --git a/CGAL_ImageIO/include/CGAL/ImageIO_impl.h b/CGAL_ImageIO/include/CGAL/ImageIO_impl.h new file mode 100644 index 00000000000..ff811c3fdf8 --- /dev/null +++ b/CGAL_ImageIO/include/CGAL/ImageIO_impl.h @@ -0,0 +1,1626 @@ +// Copyright (c) 2005, 2006 ASCLEPIOS Project, INRIA Sophia-Antipolis (France) +// Copyright (c) 2007 Geometrica Project, INRIA Sophia-Antipolis (France) +// Copyright (c) 2008 GeometryFactory, Sophia-Antipolis (France) +// All rights reserved. +// +// The files in this directory are part of the ImageIO Library. +// You can redistribute them and/or modify them under the terms of the +// GNU Lesser General Public License as published by the Free Software Foundation; +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// These files are provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE. +// +// $URL$ +// $Id$ +// + +#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 +# pragma warning(disable:4996) + +#include +#include +#include +#include +#include +#endif + +#include +#include +#include +#include + +/* formats actuellement lus + + 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 + GIF | .gif | X | + BMP | .gif | X | +*/ +#include "inr.h" +#include "gif.h" +#include "gis.h" +#include "pnm.h" +#include "bmp.h" +#include "iris.h" +#include "analyze.h" +#ifdef MINC_FILES +# include "mincio.h" +#endif + + + +/** the first file format is initialized to null */ +static PTRIMAGE_FORMAT firstFormat=NULL; + +/** the Inrimage file format (default format) is initialized to null */ +static PTRIMAGE_FORMAT InrimageFormat=NULL; + + + + + +/*-------------------------------------------------- + * + * 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 */ + + + +/* mimics fwrite() function. + According to _openWriteImage(), openMode will has one + of the following value: + - OM_STD (for stdout) + - OM_GZ + - OM_FILE +*/ +CGAL_INLINE_FUNCTION +size_t ImageIO_write(const _image *im, const void *buf, size_t len) { + + switch(im->openMode) { + default : + case OM_CLOSE : + return 0; + case OM_STD : +#ifdef CGAL_USE_ZLIB + return gzwrite(im->fd, (void *) buf, len); +#else + return fwrite(buf, 1, len, im->fd); +#endif +#ifdef CGAL_USE_ZLIB + case OM_GZ : + return gzwrite(im->fd, (void *) buf, len); +#endif + case OM_FILE: + return fwrite(buf, 1, len, (FILE*)im->fd); + } + //return 0; +} + + + +/* mimics fread() function. + According to _openReadImage(), openMode will has one + of the following value: + - OM_STD (for stdin) + - OM_GZ *or* OM_FILE +*/ +CGAL_INLINE_FUNCTION +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, to_be_read)) > 0) ) { + to_be_read -= l; + b += l; + } +#else + while ( (to_be_read > 0) && ((l = fread( b, 1, 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 : + while ( (to_be_read > 0) && ((l = gzread(im->fd, (void *) b, 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, to_be_read, im->fd )) > 0) ) { + to_be_read -= l; + b += l; + } + return ( len - to_be_read ); +#endif + } + + //return 0; +} + + + +/* mimics fgets() function. + 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 ) +{ + char *ret = NULL; + switch(im->openMode) { + default : + case OM_CLOSE : + return NULL; + 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 : + ret = (char *) gzgets(im->fd, str, size); + break; +#else + case OM_FILE : + ret = fgets(str, size, im->fd); + break; +#endif + } + return ret; +} + + + +CGAL_INLINE_FUNCTION +int 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: + return gzseek(im->fd, offset, whence ); +#endif + case OM_FILE: + return fseek( (FILE*)im->fd, offset, whence ); + } +} + +/* 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 : + static int errnum; + (void)gzerror(im->fd, &errnum); + return( (errnum != Z_OK) || gzeof(im->fd) ); +#endif + case OM_FILE : + return( ferror( (FILE*)im->fd ) || feof( (FILE*)im->fd ) ); + } + //return 0; +} + + + +/* Upon successful completion 0 is returned. + + 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; + + switch ( im->openMode ) { + default : + case OM_CLOSE : + break; +#ifdef CGAL_USE_ZLIB + case OM_GZ : + case OM_STD : + ret = gzclose( im->fd ); + break; +#else + case OM_STD : + break; +#endif + case OM_FILE : + ret = fclose( (FILE*)im->fd ); + } + im->fd = NULL; + im->openMode = OM_CLOSE; + + return ret; +} + + + + + + + +/* given an initialized file descriptor and a file name, + open file from stdin (if name == NULL, or name == "-", or name == "<"), + or a standard/gzipped file otherwise (gzipped files are handled assuming + 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 */ + if( name == NULL || 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 { +#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 + + } + + } +} + + + + + +/* given an initialized file descriptor and a file name, + open file from stdout (if name == NULL, 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) + - OM_GZ + - OM_FILE +*/ +CGAL_INLINE_FUNCTION +void _openWriteImage(_image* im, const char *name) +{ + im->openMode = OM_CLOSE; + + if( name == NULL || 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 +#else + im->fd = (_ImageIO_file) stdout; +#endif + im->openMode = OM_STD; + } + + else{ +#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. + */ + + if( !strncmp(name+strlen(name)-3, ".gz", 3) ) + { +#ifdef _MSC_VER + int ffd=_open(name,_O_RDWR | _O_CREAT| _O_TRUNC | _O_BINARY, _S_IREAD|_S_IWRITE); + im->fd = gzdopen( ffd, "wb" ); +#else + im->fd = gzopen( name, "wb" ); +#endif + im->openMode = OM_GZ; + } + else +#endif + { + im->fd = (_ImageIO_file) fopen(name, "wb"); + im->openMode = OM_FILE; + } + } +} + + + +/* set allocation and deallocation routines */ +CGAL_INLINE_FUNCTION +void setImageIOAllocationRoutines(ALLOCATION_FUNCTION alloc, + DEALLOCATION_FUNCTION del) { + if(alloc != NULL) allocRoutine = alloc; + if(del != NULL) 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)); + if ( im == NULL ) 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 */ + im->data = NULL; + + /* no file associated to image */ + im->fd = NULL; + im->openMode = OM_CLOSE; + im->endianness = END_UNKNOWN; + + /* unknown data kind + default is binary + */ + im->dataMode = DM_BINARY; + + /* no user string */ + im->user = NULL; + im->nuser = 0; + + /* unknown word kind */ + im->wdim = 0; + im->wordKind = WK_UNKNOWN; + im->vectMode = VM_SCALAR; + im->sign = SGN_UNKNOWN; + im->imageFormat = NULL; + + /** eventually initializes the supported file formats */ + if (firstFormat==NULL) + initSupportedFileFormat(); + /* return image descriptor */ + return im; +} + +CGAL_INLINE_FUNCTION +_image *_createImage(int x, int y, int z, int v, + float vx, float vy, float vz, int w, + WORD_KIND wk, SIGN sgn) +{ + _image *im; + + im = (_image *) ImageIO_alloc(sizeof(_image)); + if ( im == NULL ) 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(x*y*z*v*w); + + /* no file associated to image */ + im->fd = NULL; + im->openMode = OM_CLOSE; + im->endianness = END_UNKNOWN; + + /* unknown data kind + default is binary + */ + im->dataMode = DM_BINARY; + + /* no user string */ + im->user = NULL; + im->nuser = 0; + + /* unknown word kind */ + im->wdim = w; + im->wordKind = wk; + im->vectMode = VM_SCALAR; + im->sign = sgn; + im->imageFormat = NULL; + + /** eventually initializes the supported file formats */ + if (firstFormat==NULL) + initSupportedFileFormat(); + /* return image descriptor */ + return im; +} + +/* return the bounding box of the image */ +CGAL_INLINE_FUNCTION +void _get_image_bounding_box(_image* im, + 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 = (im->xdim - 1.0f)*(im->vx) + *x_min ; + *y_max = (im->ydim - 1.0f)*(im->vy) + *y_min ; + *z_max = (im->zdim - 1.0f)*(im->vz) + *z_min ; +} + +/* Free an image descriptor */ +CGAL_INLINE_FUNCTION +void _freeImage(_image *im) { + unsigned int i; + + if ( im == NULL ) return; + + /* close image if opened */ + if(im->openMode != OM_CLOSE) ImageIO_close(im); + + /* free data if any */ + if(im->data != NULL) ImageIO_free(im->data); + im->data = NULL; + + /* free user string array if any */ + if( (im->nuser > 0) && (im->user != NULL) ) { + for(i = 0; i < im->nuser; i++) + if ( im->user[i] != NULL ) ImageIO_free(im->user[i]); + ImageIO_free(im->user); + } + im->nuser = 0; + im->user = NULL; + + /* free given descriptor */ + ImageIO_free(im); +} + + + + + +/* Reads an image from a file and returns an image descriptor or NULL if + reading failed. + Reads from stdin if image name is NULL. */ +CGAL_INLINE_FUNCTION +_image* _readImage(const char *name) { + _image *im; + + + /* read header */ + im = _readImageHeader( name ); + + if(im != NULL && im->openMode != OM_CLOSE) { + /* read body */ + if(_readImageData(im) < 0) { + fprintf(stderr, "_readImage: error: invalid data encountered in \'%s\'\n", + name); + _freeImage(im); + return NULL; + } + 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, + const unsigned int offset) +{ + _image *im = NULL; + im = (_image *) ImageIO_alloc(sizeof(_image)); + if ( im == NULL ) + return NULL; + + 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; + + + im->fd = NULL; + im->openMode = OM_CLOSE; + im->endianness = END_UNKNOWN; + + im->dataMode = DM_BINARY; + + // no user string + im->user = NULL; + im->nuser = 0; + + // word type (unsigned byte) + im->wdim = 1; + im->wordKind = WK_FIXED; + im->vectMode = VM_SCALAR; + im->sign = SGN_UNSIGNED; + im->imageFormat = NULL; + + // read file + ::_openReadImage(im, name); + if(!im->fd) { + fprintf(stderr, "_readImage_raw: error: unable to open file \'%s\'\n", name); + _freeImage(im); + return NULL; + } + + // 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); + if(im->data == NULL) + return NULL; + + // read + ImageIO_read(im, im->data, rx*ry*rz); + + ImageIO_close(im); + /* + unsigned int i,j,k; + unsigned char *data = (unsigned char *)im->data; + int dimxy = rx * ry; + for(i=0;i + reading failed.
+ Reads from stdin if image name is NULL. + 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) { + fprintf(stderr, "_readImage: error: invalid data encountered in \'%s\'\n", + name); + _freeImage(im); + return NULL; + } + } + /* read vectorial image body */ + else { + im->vectMode = VM_NON_INTERLACED; + if(_readNonInterlacedImageData(im) < 0) { + fprintf(stderr, "_readImage: error: invalid data encountered in \'%s\'\n", + name); + _freeImage(im); + return NULL; + } + } + 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 + is written in ANALYZE format. If file name is NULL, image is written + on stdout */ +CGAL_INLINE_FUNCTION +int _writeImage(_image *im, const char *name_to_be_written ) { + + int r = ImageIO_NO_ERROR; + int length = 0; + char *name = NULL; + char *baseName = NULL; + + if ( im == NULL ) return -1; + + /* different conventions for the standard input + */ + if ( name_to_be_written == NULL || 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') ) { + name = NULL; + } + else { + name = strdup( name_to_be_written ); + } + + initSupportedFileFormat(); + + /* what is the wanted format + */ + if ( name == NULL ) { + im->imageFormat = InrimageFormat; + } else { + int i,extLength; + PTRIMAGE_FORMAT f; + char ext[IMAGE_FORMAT_NAME_LENGTH]; + char *ptr; + + + /* scan all formats; */ + im->imageFormat=NULL; + length=strlen(name); + + for(f=firstFormat;(f!=NULL)&& (im->imageFormat==NULL);f=f->next) { + /* scan all extensions for that format */ + ptr=&f->fileExtension[0]; + + do { + /* 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;iimageFormat==NULL)); + } + + if (!im->imageFormat) { + fprintf(stderr, "_writeImage: warning : unknown extension in %s = assuming Inrimage\n",name); + im->imageFormat=InrimageFormat; + baseName=strdup(name); + } + } + + + /* open file descriptor */ + /* _openWriteImage( im, name ) ; + + + + if(!im->fd) { + fprintf(stderr, "_writeImage: error: open failed\n"); + if ( name != NULL ) free( name ); + if ( baseName != NULL ) free( baseName ); + return ImageIO_OPENING; + } + */ + + if (im->imageFormat) { + + if (im->imageFormat->writeImage==NULL) { + im->imageFormat=InrimageFormat; + } + + if ( 0 ) { + fprintf(stderr, "_writeImage: will write '%s' with '%s' format\n", + name, im->imageFormat->realName ); + } + + if ((*im->imageFormat->writeImage)(name, im)<0) { + fprintf(stderr, "_writeImage: error: unable to write \'%s\'\n", + name); + r = ImageIO_WRITING_HEADER; + } + + } + + + + /* close file descriptor */ + ImageIO_close( im ); + + im->fd = NULL; + im->openMode = OM_CLOSE; + + if ( baseName != NULL ) free( baseName ); + if ( name != NULL ) free( name ); + + return r; +} + + + + + + + + + + + + +/* 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]; + char *name = NULL; + PTRIMAGE_FORMAT f; + int res; + + *error = ImageIO_NO_ERROR; + + /* open image file */ + im = _initImage(); + if ( name_to_be_read == NULL || 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') ) { + name = NULL; + } + else { + name = strdup( name_to_be_read ); + } + + + _openReadImage(im, name); + + if(!im->fd) { + fprintf(stderr, "_readImageHeaderAndGetError: error: unable to open file \'%s\'\n", name); + _freeImage(im); + *error = ImageIO_OPENING; + if ( name != NULL ) free( name ); + return NULL; + } + + initSupportedFileFormat(); + + /* what is the wanted format ? + assume that stdin is inrimage + */ + if(im->openMode == OM_STD) { + im->imageFormat=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 */ + for(f=firstFormat;(f!=NULL)&& (im->imageFormat==NULL);f=f->next) { + /* test if it is the correct format based on magic and file extension */ + if (((*f->testImageFormat)(magic, name)) >=0) { + im->imageFormat=f; + } + } + } + + if ( im->imageFormat == NULL ) { + fprintf(stderr, "_readImageHeaderAndGetError: does not find image format for \'%s\'\n", name); + ImageIO_close( im ); + _freeImage(im); + *error = ImageIO_UNKNOWN_TYPE; + if ( name != NULL ) free( name ); + return NULL; + } + + /* now tests if the header can be read correctly */ + + res=(*(im->imageFormat)->readImageHeader)(name,im); + /* could read header only */ + if (res == 0) { + if ( name != NULL ) free( name ); + return( im ); + } + /* could read header and data */ + else if ( res > 0 ) { + ImageIO_close(im); + if ( name != NULL ) free( name ); + return im; + } + + /* could not read error : throw error */ + fprintf(stderr, "_readImageHeaderAndGetError: an error occurs when reading image\n" ); + if ( name == NULL || 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; + if ( name != NULL ) free( name ); + return NULL; + +} + + + + + + + +CGAL_INLINE_FUNCTION +static void _swapImageData( _image *im ) +{ + unsigned char *ptr1, *ptr2, b[8]; + unsigned short int si, *ptr3, *ptr4; + unsigned int i, *ptr5, *ptr6; + int size, length; + + if( _getEndianness() != im->endianness) { + + size = im->xdim * im->ydim * im->zdim * im->vdim * im->wdim; + if ( size <= 0 ) return; + + length = size / im->wdim; + ptr1 = ptr2 = (unsigned char *) im->data; + + /* 2 bytes swap */ + if(im->wdim == 2) { + /* + while(length--) { + b[0] = *ptr1++; + b[1] = *ptr1++; + *ptr2++ = b[1]; + *ptr2++ = b[0]; + } + */ + ptr3 = ptr4 = (unsigned short int *) im->data; + while( length-- ) { + si = *ptr3++; + *ptr4++ = ((si >> 8) & 0xff) | (si << 8); + } + } + + /* 4 bytes swap */ + else if(im->wdim == 4) { + /* + 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-- ) { + i = *ptr5++; + *ptr6++ = (i << 24) | ((i & 0xff00) << 8) | ((i >> 8) & 0xff00) | ((i >> 24) & 0xff); + } + } + /* 8 bytes swap */ + else if(im->wdim == 8) { + while(length--) { + 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. + If im->data is not NULL, 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; + + 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; + + + /* 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. + If im->data is not NULL, 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); + + 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++) { + 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 ); + + + /* 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 ) */ +/* { */ +/* 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++) { + 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 ); + + + /* 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 ) */ +/* { */ +/* 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; +} + + + + + + + + + + +/*-------------------------------------------------- + * + * ????? + * + --------------------------------------------------*/ + + + + + +/* 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) { +#ifdef CGAL_USE_ZLIB + f = gzdopen(fileno(stdin), "rb"); +#else + f = fdopen(fileno(stdin), "rb"); +#endif + } + else { +#ifdef CGAL_USE_ZLIB + f = gzopen(fileName, "rb"); +#else + f = fopen(fileName, "rb"); +#endif + } + + if(!f) return NULL; + +#ifdef CGAL_USE_ZLIB + gzread( f, (void *) magic, 4); +#else + fread( (void *) magic, 1, 4, f ); +#endif + + + magic[4] = '\0'; + +#ifdef CGAL_USE_ZLIB + gzclose( f ); +#else + if(fileName) fclose( f ); +#endif + + if (firstFormat==NULL) + initSupportedFileFormat(); + + for(format=firstFormat;(format!=NULL);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 + * + --------------------------------------------------*/ + + + + + +/** adds a format at the beginning of the list of image formats. + Test if all mandatory fields have been filled */ +CGAL_INLINE_FUNCTION +int addImageFormat( PTRIMAGE_FORMAT format) +{ + if ( (format->testImageFormat) && + (format->readImageHeader) && + (strlen(format->fileExtension)>0) && + (strlen(format->realName)>0) ) { + + format->next=firstFormat; + firstFormat=format; + + return 0; + + } + else { + fprintf(stderr,"addImageFormat: information missing in file format %s\n", + format->realName); + return -1; + } +} + +/** adds a format at the end of the list of image formats. + Test if all mandatory fields have been filled */ +CGAL_INLINE_FUNCTION +int addImageFormatAtEnd( PTRIMAGE_FORMAT format) +{ + PTRIMAGE_FORMAT f; + if ( (format->testImageFormat) && + (format->readImageHeader) && + (strlen(format->fileExtension)>0) && + (strlen(format->realName)>0) ) { + + format->next = NULL; + + if (firstFormat == NULL) { + firstFormat=format; + } + else { + for(f=firstFormat;(f->next!=NULL);f=f->next) + ; + f->next=format; + } + + return 0; + + } + else { + fprintf(stderr,"addImageFormatAtEnd: information missing in file format %s\n", + format->realName); + return -1; + } +} + + +/** creates supported image formats */ +CGAL_INLINE_FUNCTION +void initSupportedFileFormat() +{ + PTRIMAGE_FORMAT f; + if ( InrimageFormat == NULL ) { + 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 ); + InrimageFormat = createInrimageFormat(); + addImageFormat( InrimageFormat ); + } +} + + + +CGAL_INLINE_FUNCTION +PTRIMAGE_FORMAT firstImageFormat() { + return firstFormat; +} + + + +/** prints supported image formats */ +CGAL_INLINE_FUNCTION +void printSupportedFileFormat() { + PTRIMAGE_FORMAT f; + int i; + + initSupportedFileFormat(); + + for(i=0, f=firstFormat;(f!=NULL);i++, f=f->next) { + if ( (f->testImageFormat) && + (f->readImageHeader) && + (strlen(f->fileExtension)>0) && + (strlen(f->realName)>0)) { + fprintf( stderr, "#%2d: format name ='%s', extensions='%s'", + 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 +void removeSupportedFileFormat() { + PTRIMAGE_FORMAT f=firstFormat; + + while( f != NULL) { + PTRIMAGE_FORMAT f_old = f; + f = f->next; + ImageIO_free( f_old); + } + InrimageFormat=NULL; + +} + + +/** trilinear interpolation in an _image float type + */ +CGAL_INLINE_FUNCTION +float triLinInterp(const _image* image, + float posx, + float posy, + float posz, + float value_outside /*= 0.f */) +{ + const int dimx = image->xdim; + const int dimy = image->ydim; + const int dimz = image->zdim; + const int dimxy = dimx*dimy; + + if(posx < 0.f || posy < 0.f || posz < 0.f ) + return value_outside; + + posx = static_cast(posx /(image->vx)); + posy = static_cast(posy /(image->vy)); + posz = static_cast(posz /(image->vz)); + + //patch suggested by J.Cugnoni to prevent integer overflow + if(posz >= dimz-1 || posy >= dimy-1 || posx >= dimx-1) + return value_outside; + + 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 = i2-posz; + const float KI1 = posz-i1; + const float KJ2 = j2-posy; + const float KJ1 = posy-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) * (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-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(image, i, j, k); ); + + return 0.f; +} + +/** convert the data of the image to float +*/ +CGAL_INLINE_FUNCTION +void convertImageTypeToFloat(_image* image){ + if(image->wordKind == WK_FLOAT && image->wdim == 4) + return; + + const unsigned int dimx = image->xdim; + const unsigned int dimy = image->ydim; + const unsigned int dimz = image->zdim; + + float * array = (float*)ImageIO_alloc (dimx * dimy * dimz *sizeof(float)); + if (array == NULL ) { + fprintf ( stderr, "allocation error\n" ); + return; + } + + CGAL_IMAGE_IO_CASE + (image, + Word * typedArray = (Word *)(image->data); + for(unsigned int i = 0; idata ); + image->data = array; + + image->wordKind = WK_FLOAT; + image->wdim = 4; +} + diff --git a/CGAL_ImageIO/include/CGAL/Image_3.h b/CGAL_ImageIO/include/CGAL/Image_3.h index 3ae3164931a..9a0adabb242 100644 --- a/CGAL_ImageIO/include/CGAL/Image_3.h +++ b/CGAL_ImageIO/include/CGAL/Image_3.h @@ -490,10 +490,12 @@ Image_3::labellized_trilinear_interpolation(const Coord_type& x, } // end namespace CGAL +#ifdef CGAL_HEADER_ONLY +#include "Image_3_impl.h" +#endif // CGAL_HEADER_ONLY #if defined(BOOST_MSVC) # pragma warning(pop) #endif - #endif // CGAL_IMAGE_3_H diff --git a/CGAL_ImageIO/include/CGAL/Image_3_impl.h b/CGAL_ImageIO/include/CGAL/Image_3_impl.h new file mode 100644 index 00000000000..7fda2193521 --- /dev/null +++ b/CGAL_ImageIO/include/CGAL/Image_3_impl.h @@ -0,0 +1,232 @@ +// Copyright (c) 2005-2008 INRIA Sophia-Antipolis (France). +// 2008 GeometryFactory, Sophia Antipolis (France) +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; either version 3 of the License, +// or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Laurent Rineau, Pierre Alliez + +#ifdef CGAL_HEADER_ONLY +#define CGAL_INLINE_FUNCTION inline +#else +#define CGAL_INLINE_FUNCTION +#endif + +#include + +namespace CGAL { + +CGAL_INLINE_FUNCTION +bool Image_3::private_read(_image* im) +{ + if(im != 0) + { + if(image() != 0) + { + ::_freeImage(image()); + } + image_ptr = Image_shared_ptr(im, Image_deleter()); + +// std::cerr << +// boost::format("image=%1% (xdim=%2%, ydim=%3%, zdim=%4%)\n") +// % image_ptr.get() % image_ptr->xdim % image_ptr->ydim % image_ptr->zdim; + + } + return im != 0; +} + +CGAL_INLINE_FUNCTION +void Image_3::gl_draw(const float point_size, + const unsigned char r, + const unsigned char g, + const unsigned char b) +{ + if(image_ptr.get() == NULL) + return; + + glPointSize(point_size); + glColor3ub(r,g,b); + glBegin(GL_POINTS); + unsigned char *pData = (unsigned char*)image_ptr->data; + unsigned int xy = image_ptr->xdim * image_ptr->ydim; + for(unsigned int i=0;ixdim;i+=5) + for(unsigned int j=0;jydim;j+=5) + for(unsigned int k=0;kzdim;k+=5) + { + unsigned char value = pData[xy*k + j*image_ptr->xdim + i]; + if(value > 0) + { + double x = image_ptr->vx * i; + double y = image_ptr->vy * j; + double z = image_ptr->vz * k; + glVertex3d(x,y,z); + } + } + glEnd(); +} // end Image_3::gl_draw + + +CGAL_INLINE_FUNCTION +void Image_3::gl_draw_bbox(const float line_width, + const unsigned char red, + const unsigned char green, + const unsigned char blue) +{ + if(!image_ptr) + return; + + glLineWidth(line_width); + glColor3ub(red,green,blue); + glBegin(GL_LINES); + + struct Point { + double x_; + double y_; + double z_; + Point(double x, double y, double z) : x_(x), y_(y), z_(z) {}; + + double x() const { return x_; } + double y() const { return y_; } + double z() const { return z_; } + }; + + const double xmax = (image_ptr->xdim - 1.0)*(image_ptr->vx); + const double ymax = (image_ptr->ydim - 1.0)*(image_ptr->vy); + const double zmax = (image_ptr->zdim - 1.0)*(image_ptr->vz); + + Point a(0.0, 0.0, 0.0); + Point b(0.0, ymax, 0.0); + Point c(0.0, ymax, zmax); + Point d(0.0, 0.0, zmax); + Point e(xmax, 0.0, 0.0); + Point f(xmax, ymax, 0.0); + Point g(xmax, ymax, zmax); + Point h(xmax, 0.0, zmax); + + glVertex3d(a.x(),a.y(),a.z()); + glVertex3d(b.x(),b.y(),b.z()); + + glVertex3d(b.x(),b.y(),b.z()); + glVertex3d(c.x(),c.y(),c.z()); + + glVertex3d(c.x(),c.y(),c.z()); + glVertex3d(d.x(),d.y(),d.z()); + + glVertex3d(d.x(),d.y(),d.z()); + glVertex3d(a.x(),a.y(),a.z()); + + glVertex3d(e.x(),e.y(),e.z()); + glVertex3d(f.x(),f.y(),f.z()); + + glVertex3d(f.x(),f.y(),f.z()); + glVertex3d(g.x(),g.y(),g.z()); + + glVertex3d(g.x(),g.y(),g.z()); + glVertex3d(h.x(),h.y(),h.z()); + + glVertex3d(h.x(),h.y(),h.z()); + glVertex3d(e.x(),e.y(),e.z()); + + glVertex3d(a.x(),a.y(),a.z()); + glVertex3d(e.x(),e.y(),e.z()); + + glVertex3d(d.x(),d.y(),d.z()); + glVertex3d(h.x(),h.y(),h.z()); + + glVertex3d(c.x(),c.y(),c.z()); + glVertex3d(g.x(),g.y(),g.z()); + + glVertex3d(b.x(),b.y(),b.z()); + glVertex3d(f.x(),f.y(),f.z()); + + glEnd(); +} // end Image_3::gl_draw_bbox + +} // end namespace CGAL + +#ifdef CGAL_USE_VTK + +#include +#include + +namespace CGAL { + +namespace { + +struct VTK_to_ImageIO_type_mapper { + WORD_KIND wordKind; + SIGN sign; + unsigned int wdim; +}; + +static const VTK_to_ImageIO_type_mapper VTK_to_ImageIO_type[VTK_ID_TYPE] = + { { WK_UNKNOWN, SGN_UNKNOWN, 0}, // 0=VTK_VOID + { WK_UNKNOWN, SGN_UNKNOWN, 0}, // 1=VTK_BIT + { WK_FIXED, SGN_SIGNED, 1}, // 2=VTK_CHAR + { WK_FIXED, SGN_UNSIGNED, 1}, // 3=VTK_UNSIGNED_CHAR + { WK_FIXED, SGN_SIGNED, 2}, // 4=VTK_SHORT + { WK_FIXED, SGN_UNSIGNED, 2}, // 5=VTK_UNSIGNED_SHORT + { WK_FIXED, SGN_SIGNED, 4}, // 6=VTK_INT + { WK_FIXED, SGN_UNSIGNED, 4}, // 7=VTK_UNSIGNED_INT + { WK_FIXED, SGN_SIGNED, 8}, // 8=VTK_LONG + { WK_FIXED, SGN_UNSIGNED, 8}, // 9=VTK_UNSIGNED_LONG + { WK_FLOAT, SGN_SIGNED, 4}, // 10=VTK_FLOAT + { WK_FIXED, SGN_SIGNED, 8} // 11=VTK_DOUBLE + }; + +} //end anonymous namespace + +CGAL_INLINE_FUNCTION +bool +Image_3::read_vtk_image_data(vtkImageData* vtk_image) +{ + if(!vtk_image) + return false; + + _image* image = ::_initImage(); + const int* dims = vtk_image->GetDimensions(); + const double* spacing = vtk_image->GetSpacing(); + image->vectMode = VM_SCALAR; + image->xdim = dims[0]; + image->ydim = dims[1]; + image->zdim = dims[2]; + image->vdim = 1; + image->vx = spacing[0]; + image->vy = spacing[1]; + image->vz = spacing[2]; + vtk_image->Update(); + image->endianness = ::_getEndianness(); + int vtk_type = vtk_image->GetScalarType(); + if(vtk_type == VTK_SIGNED_CHAR) vtk_type = VTK_CHAR; + if(vtk_type < 0 || vtk_type > VTK_DOUBLE) + vtk_type = VTK_DOUBLE; + const VTK_to_ImageIO_type_mapper& imageio_type = + VTK_to_ImageIO_type[vtk_type]; + image->wdim = imageio_type.wdim; + image->wordKind = imageio_type.wordKind; + image->sign = imageio_type.sign; + image->data = ::ImageIO_alloc(dims[0]*dims[1]*dims[2]*image->wdim); + std::cerr << "GetNumberOfTuples()=" << vtk_image->GetPointData()->GetScalars()->GetNumberOfTuples() + << "\nimage->size()=" << dims[0]*dims[1]*dims[2] + << "\nwdim=" << image->wdim << '\n'; + assert(vtk_image->GetPointData()->GetScalars()->GetNumberOfTuples() == dims[0]*dims[1]*dims[2]); + vtk_image->GetPointData()->GetScalars()->ExportToVoidPointer(image->data); + + return this->private_read(image); +} + +} // end namespace CGAL + +#endif // CGAL_USE_VTK diff --git a/CGAL_ImageIO/src/CGAL_ImageIO/ImageIO.cpp b/CGAL_ImageIO/src/CGAL_ImageIO/ImageIO.cpp index 9198b14a801..7c4274db153 100644 --- a/CGAL_ImageIO/src/CGAL_ImageIO/ImageIO.cpp +++ b/CGAL_ImageIO/src/CGAL_ImageIO/ImageIO.cpp @@ -19,1568 +19,9 @@ // $Id$ // -#ifdef _MSC_VER -// Suppress deprecated warning for fileno and strdup -# pragma warning(disable:4996) +#ifndef CGAL_HEADER_ONLY -#include -#include -#include -#include -#include -#endif - -#include -#include -#include -#include - -#include - -/* formats actuellement lus - - 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 - GIF | .gif | X | - BMP | .gif | X | -*/ -#include "inr.h" -#include "gif.h" -#include "gis.h" -#include "pnm.h" -#include "bmp.h" -#include "iris.h" -#include "analyze.h" -#ifdef MINC_FILES -# include "mincio.h" -#endif - - - -/** the first file format is initialized to null */ -static PTRIMAGE_FORMAT firstFormat=NULL; - -/** the Inrimage file format (default format) is initialized to null */ -static PTRIMAGE_FORMAT InrimageFormat=NULL; - - - - - -/*-------------------------------------------------- - * - * mimics standard routines - * - --------------------------------------------------*/ - - - -extern "C" { - /* default allocation routine */ - static void *(*allocRoutine)(size_t) = 0; - /* default deallocation routine */ - static void (*deleteRoutine)(void *) = 0; -} - -void *ImageIO_alloc(size_t s) { - if(!allocRoutine) allocRoutine = malloc; - return ( (*allocRoutine)(s) ); -} -/* call allocation routine */ -void ImageIO_free(void *m) { - if(!deleteRoutine) deleteRoutine = free; - (*deleteRoutine)(m); -} -/* call deallocation routine */ - - - -/* mimics fwrite() function. - According to _openWriteImage(), openMode will has one - of the following value: - - OM_STD (for stdout) - - OM_GZ - - OM_FILE -*/ -size_t ImageIO_write(const _image *im, const void *buf, size_t len) { - - switch(im->openMode) { - default : - case OM_CLOSE : - return 0; - case OM_STD : -#ifdef CGAL_USE_ZLIB - return gzwrite(im->fd, (void *) buf, len); -#else - return fwrite(buf, 1, len, im->fd); -#endif -#ifdef CGAL_USE_ZLIB - case OM_GZ : - return gzwrite(im->fd, (void *) buf, len); -#endif - case OM_FILE: - return fwrite(buf, 1, len, (FILE*)im->fd); - } - //return 0; -} - - - -/* mimics fread() function. - According to _openReadImage(), openMode will has one - of the following value: - - OM_STD (for stdin) - - OM_GZ *or* OM_FILE -*/ -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, to_be_read)) > 0) ) { - to_be_read -= l; - b += l; - } -#else - while ( (to_be_read > 0) && ((l = fread( b, 1, 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 : - while ( (to_be_read > 0) && ((l = gzread(im->fd, (void *) b, 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, to_be_read, im->fd )) > 0) ) { - to_be_read -= l; - b += l; - } - return ( len - to_be_read ); -#endif - } - - //return 0; -} - - - -/* mimics fgets() function. - According to _openReadImage(), openMode will has one - of the following value: - - OM_STD (for stdout) - - OM_GZ *or* OM_FILE -*/ -char *ImageIO_gets( const _image *im, char *str, int size ) -{ - char *ret = NULL; - switch(im->openMode) { - default : - case OM_CLOSE : - return NULL; - 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 : - ret = (char *) gzgets(im->fd, str, size); - break; -#else - case OM_FILE : - ret = fgets(str, size, im->fd); - break; -#endif - } - return ret; -} - - - -int 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: - return gzseek(im->fd, offset, whence ); -#endif - case OM_FILE: - return fseek( (FILE*)im->fd, offset, whence ); - } -} - -/* return non 0 in case of error - */ -int ImageIO_error( const _image *im ) -{ - switch(im->openMode) { - case OM_CLOSE : - default : - return 0; -#ifdef CGAL_USE_ZLIB - case OM_GZ : - static int errnum; - (void)gzerror(im->fd, &errnum); - return( (errnum != Z_OK) || gzeof(im->fd) ); -#endif - case OM_FILE : - return( ferror( (FILE*)im->fd ) || feof( (FILE*)im->fd ) ); - } - //return 0; -} - - - -/* Upon successful completion 0 is returned. - - Closing the standard output with gzclose() - is necessary as it will flush the pending output. - */ -int ImageIO_close( _image* im ) -{ - int ret=0; - - switch ( im->openMode ) { - default : - case OM_CLOSE : - break; -#ifdef CGAL_USE_ZLIB - case OM_GZ : - case OM_STD : - ret = gzclose( im->fd ); - break; -#else - case OM_STD : - break; -#endif - case OM_FILE : - ret = fclose( (FILE*)im->fd ); - } - im->fd = NULL; - im->openMode = OM_CLOSE; - - return ret; -} - - - - - - - -/* given an initialized file descriptor and a file name, - open file from stdin (if name == NULL, or name == "-", or name == "<"), - or a standard/gzipped file otherwise (gzipped files are handled assuming - 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 -*/ -void _openReadImage(_image* im, const char *name) { - if(im->openMode == OM_CLOSE) { - - /* open from stdin */ - if( name == NULL || 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 { -#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 - - } - - } -} - - - - - -/* given an initialized file descriptor and a file name, - open file from stdout (if name == NULL, 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) - - OM_GZ - - OM_FILE -*/ -void _openWriteImage(_image* im, const char *name) -{ - im->openMode = OM_CLOSE; - - if( name == NULL || 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 -#else - im->fd = (_ImageIO_file) stdout; -#endif - im->openMode = OM_STD; - } - - else{ -#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. - */ - - if( !strncmp(name+strlen(name)-3, ".gz", 3) ) - { -#ifdef _MSC_VER - int ffd=_open(name,_O_RDWR | _O_CREAT| _O_TRUNC | _O_BINARY, _S_IREAD|_S_IWRITE); - im->fd = gzdopen( ffd, "wb" ); -#else - im->fd = gzopen( name, "wb" ); -#endif - im->openMode = OM_GZ; - } - else -#endif - { - im->fd = (_ImageIO_file) fopen(name, "wb"); - im->openMode = OM_FILE; - } - } -} - - - -/* set allocation and deallocation routines */ -void setImageIOAllocationRoutines(ALLOCATION_FUNCTION alloc, - DEALLOCATION_FUNCTION del) { - if(alloc != NULL) allocRoutine = alloc; - if(del != NULL) deleteRoutine = del; -} - - - - - -/*-------------------------------------------------- - * - * - * - --------------------------------------------------*/ - - - - - -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 */ -_image *_initImage() { - _image *im; - - im = (_image *) ImageIO_alloc(sizeof(_image)); - if ( im == NULL ) 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 */ - im->data = NULL; - - /* no file associated to image */ - im->fd = NULL; - im->openMode = OM_CLOSE; - im->endianness = END_UNKNOWN; - - /* unknown data kind - default is binary - */ - im->dataMode = DM_BINARY; - - /* no user string */ - im->user = NULL; - im->nuser = 0; - - /* unknown word kind */ - im->wdim = 0; - im->wordKind = WK_UNKNOWN; - im->vectMode = VM_SCALAR; - im->sign = SGN_UNKNOWN; - im->imageFormat = NULL; - - /** eventually initializes the supported file formats */ - if (firstFormat==NULL) - initSupportedFileFormat(); - /* return image descriptor */ - return im; -} - -_image *_createImage(int x, int y, int z, int v, - float vx, float vy, float vz, int w, - WORD_KIND wk, SIGN sgn) -{ - _image *im; - - im = (_image *) ImageIO_alloc(sizeof(_image)); - if ( im == NULL ) 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(x*y*z*v*w); - - /* no file associated to image */ - im->fd = NULL; - im->openMode = OM_CLOSE; - im->endianness = END_UNKNOWN; - - /* unknown data kind - default is binary - */ - im->dataMode = DM_BINARY; - - /* no user string */ - im->user = NULL; - im->nuser = 0; - - /* unknown word kind */ - im->wdim = w; - im->wordKind = wk; - im->vectMode = VM_SCALAR; - im->sign = sgn; - im->imageFormat = NULL; - - /** eventually initializes the supported file formats */ - if (firstFormat==NULL) - initSupportedFileFormat(); - /* return image descriptor */ - return im; -} - -/* return the bounding box of the image */ -void _get_image_bounding_box(_image* im, - 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 = (im->xdim - 1.0f)*(im->vx) + *x_min ; - *y_max = (im->ydim - 1.0f)*(im->vy) + *y_min ; - *z_max = (im->zdim - 1.0f)*(im->vz) + *z_min ; -} - -/* Free an image descriptor */ -void _freeImage(_image *im) { - unsigned int i; - - if ( im == NULL ) return; - - /* close image if opened */ - if(im->openMode != OM_CLOSE) ImageIO_close(im); - - /* free data if any */ - if(im->data != NULL) ImageIO_free(im->data); - im->data = NULL; - - /* free user string array if any */ - if( (im->nuser > 0) && (im->user != NULL) ) { - for(i = 0; i < im->nuser; i++) - if ( im->user[i] != NULL ) ImageIO_free(im->user[i]); - ImageIO_free(im->user); - } - im->nuser = 0; - im->user = NULL; - - /* free given descriptor */ - ImageIO_free(im); -} - - - - - -/* Reads an image from a file and returns an image descriptor or NULL if - reading failed. - Reads from stdin if image name is NULL. */ -_image* _readImage(const char *name) { - _image *im; - - - /* read header */ - im = _readImageHeader( name ); - - if(im != NULL && im->openMode != OM_CLOSE) { - /* read body */ - if(_readImageData(im) < 0) { - fprintf(stderr, "_readImage: error: invalid data encountered in \'%s\'\n", - name); - _freeImage(im); - return NULL; - } - ImageIO_close(im); - } - - return im; -} - -// raw -_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, - const unsigned int offset) -{ - _image *im = NULL; - im = (_image *) ImageIO_alloc(sizeof(_image)); - if ( im == NULL ) - return NULL; - - 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; - - - im->fd = NULL; - im->openMode = OM_CLOSE; - im->endianness = END_UNKNOWN; - - im->dataMode = DM_BINARY; - - // no user string - im->user = NULL; - im->nuser = 0; - - // word type (unsigned byte) - im->wdim = 1; - im->wordKind = WK_FIXED; - im->vectMode = VM_SCALAR; - im->sign = SGN_UNSIGNED; - im->imageFormat = NULL; - - // read file - ::_openReadImage(im, name); - if(!im->fd) { - fprintf(stderr, "_readImage_raw: error: unable to open file \'%s\'\n", name); - _freeImage(im); - return NULL; - } - - // 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); - if(im->data == NULL) - return NULL; - - // read - ImageIO_read(im, im->data, rx*ry*rz); - - ImageIO_close(im); - /* - unsigned int i,j,k; - unsigned char *data = (unsigned char *)im->data; - int dimxy = rx * ry; - for(i=0;i - reading failed.
- Reads from stdin if image name is NULL. - If the image is vectorial, it is uninterlaced. */ -_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) { - fprintf(stderr, "_readImage: error: invalid data encountered in \'%s\'\n", - name); - _freeImage(im); - return NULL; - } - } - /* read vectorial image body */ - else { - im->vectMode = VM_NON_INTERLACED; - if(_readNonInterlacedImageData(im) < 0) { - fprintf(stderr, "_readImage: error: invalid data encountered in \'%s\'\n", - name); - _freeImage(im); - return NULL; - } - } - 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 - is written in ANALYZE format. If file name is NULL, image is written - on stdout */ -int _writeImage(_image *im, const char *name_to_be_written ) { - - int r = ImageIO_NO_ERROR; - int length = 0; - char *name = NULL; - char *baseName = NULL; - - if ( im == NULL ) return -1; - - /* different conventions for the standard input - */ - if ( name_to_be_written == NULL || 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') ) { - name = NULL; - } - else { - name = strdup( name_to_be_written ); - } - - initSupportedFileFormat(); - - /* what is the wanted format - */ - if ( name == NULL ) { - im->imageFormat = InrimageFormat; - } else { - int i,extLength; - PTRIMAGE_FORMAT f; - char ext[IMAGE_FORMAT_NAME_LENGTH]; - char *ptr; - - - /* scan all formats; */ - im->imageFormat=NULL; - length=strlen(name); - - for(f=firstFormat;(f!=NULL)&& (im->imageFormat==NULL);f=f->next) { - /* scan all extensions for that format */ - ptr=&f->fileExtension[0]; - - do { - /* 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;iimageFormat==NULL)); - } - - if (!im->imageFormat) { - fprintf(stderr, "_writeImage: warning : unknown extension in %s = assuming Inrimage\n",name); - im->imageFormat=InrimageFormat; - baseName=strdup(name); - } - } - - - /* open file descriptor */ - /* _openWriteImage( im, name ) ; - - - - if(!im->fd) { - fprintf(stderr, "_writeImage: error: open failed\n"); - if ( name != NULL ) free( name ); - if ( baseName != NULL ) free( baseName ); - return ImageIO_OPENING; - } - */ - - if (im->imageFormat) { - - if (im->imageFormat->writeImage==NULL) { - im->imageFormat=InrimageFormat; - } - - if ( 0 ) { - fprintf(stderr, "_writeImage: will write '%s' with '%s' format\n", - name, im->imageFormat->realName ); - } - - if ((*im->imageFormat->writeImage)(name, im)<0) { - fprintf(stderr, "_writeImage: error: unable to write \'%s\'\n", - name); - r = ImageIO_WRITING_HEADER; - } - - } - - - - /* close file descriptor */ - ImageIO_close( im ); - - im->fd = NULL; - im->openMode = OM_CLOSE; - - if ( baseName != NULL ) free( baseName ); - if ( name != NULL ) free( name ); - - return r; -} - - - - - - - - - - - - -/* 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 - */ -_image *_readImageHeader( const char *name ) { - int error = 0; - return( _readImageHeaderAndGetError( name, &error ) ); -} - - - -_image *_readImageHeaderAndGetError( const char *name_to_be_read, int *error ) -{ - _image *im; - char magic[5]; - char *name = NULL; - PTRIMAGE_FORMAT f; - int res; - - *error = ImageIO_NO_ERROR; - - /* open image file */ - im = _initImage(); - if ( name_to_be_read == NULL || 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') ) { - name = NULL; - } - else { - name = strdup( name_to_be_read ); - } - - - _openReadImage(im, name); - - if(!im->fd) { - fprintf(stderr, "_readImageHeaderAndGetError: error: unable to open file \'%s\'\n", name); - _freeImage(im); - *error = ImageIO_OPENING; - if ( name != NULL ) free( name ); - return NULL; - } - - initSupportedFileFormat(); - - /* what is the wanted format ? - assume that stdin is inrimage - */ - if(im->openMode == OM_STD) { - im->imageFormat=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 */ - for(f=firstFormat;(f!=NULL)&& (im->imageFormat==NULL);f=f->next) { - /* test if it is the correct format based on magic and file extension */ - if (((*f->testImageFormat)(magic, name)) >=0) { - im->imageFormat=f; - } - } - } - - if ( im->imageFormat == NULL ) { - fprintf(stderr, "_readImageHeaderAndGetError: does not find image format for \'%s\'\n", name); - ImageIO_close( im ); - _freeImage(im); - *error = ImageIO_UNKNOWN_TYPE; - if ( name != NULL ) free( name ); - return NULL; - } - - /* now tests if the header can be read correctly */ - - res=(*(im->imageFormat)->readImageHeader)(name,im); - /* could read header only */ - if (res == 0) { - if ( name != NULL ) free( name ); - return( im ); - } - /* could read header and data */ - else if ( res > 0 ) { - ImageIO_close(im); - if ( name != NULL ) free( name ); - return im; - } - - /* could not read error : throw error */ - fprintf(stderr, "_readImageHeaderAndGetError: an error occurs when reading image\n" ); - if ( name == NULL || 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; - if ( name != NULL ) free( name ); - return NULL; - -} - - - - - - - -static void _swapImageData( _image *im ) -{ - unsigned char *ptr1, *ptr2, b[8]; - unsigned short int si, *ptr3, *ptr4; - unsigned int i, *ptr5, *ptr6; - int size, length; - - if( _getEndianness() != im->endianness) { - - size = im->xdim * im->ydim * im->zdim * im->vdim * im->wdim; - if ( size <= 0 ) return; - - length = size / im->wdim; - ptr1 = ptr2 = (unsigned char *) im->data; - - /* 2 bytes swap */ - if(im->wdim == 2) { - /* - while(length--) { - b[0] = *ptr1++; - b[1] = *ptr1++; - *ptr2++ = b[1]; - *ptr2++ = b[0]; - } - */ - ptr3 = ptr4 = (unsigned short int *) im->data; - while( length-- ) { - si = *ptr3++; - *ptr4++ = ((si >> 8) & 0xff) | (si << 8); - } - } - - /* 4 bytes swap */ - else if(im->wdim == 4) { - /* - 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-- ) { - i = *ptr5++; - *ptr6++ = (i << 24) | ((i & 0xff00) << 8) | ((i >> 8) & 0xff00) | ((i >> 24) & 0xff); - } - } - /* 8 bytes swap */ - else if(im->wdim == 8) { - while(length--) { - 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. - If im->data is not NULL, assume that the buffer was previously allocated - Swap bytes depending on the endianness and the current architecture */ -int _readImageData(_image *im) { - unsigned long size, nread; - - 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; - } - - nread = ImageIO_read(im, im->data, size); - if(nread != size) return -1; - - - /* 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. - If im->data is not NULL, assume that the buffer was previously allocated - Swap bytes depending on the endianness and the current architecture. */ -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); - - 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++) { - 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 ); - - - /* 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 ) */ -/* { */ -/* 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. */ -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++) { - 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 ); - - - /* 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 ) */ -/* { */ -/* 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; -} - - - - - - - - - - -/*-------------------------------------------------- - * - * ????? - * - --------------------------------------------------*/ - - - - - -/* check the type of image in fileName */ -PTRIMAGE_FORMAT imageType(const char *fileName) { - _ImageIO_file f; - char magic[5]; - PTRIMAGE_FORMAT format; - - if(!fileName) { -#ifdef CGAL_USE_ZLIB - f = gzdopen(fileno(stdin), "rb"); -#else - f = fdopen(fileno(stdin), "rb"); -#endif - } - else { -#ifdef CGAL_USE_ZLIB - f = gzopen(fileName, "rb"); -#else - f = fopen(fileName, "rb"); -#endif - } - - if(!f) return NULL; - -#ifdef CGAL_USE_ZLIB - gzread( f, (void *) magic, 4); -#else - fread( (void *) magic, 1, 4, f ); -#endif - - - magic[4] = '\0'; - -#ifdef CGAL_USE_ZLIB - gzclose( f ); -#else - if(fileName) fclose( f ); -#endif - - if (firstFormat==NULL) - initSupportedFileFormat(); - - for(format=firstFormat;(format!=NULL);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 - * - --------------------------------------------------*/ - - - - - -/** adds a format at the beginning of the list of image formats. - Test if all mandatory fields have been filled */ -int addImageFormat( PTRIMAGE_FORMAT format) -{ - if ( (format->testImageFormat) && - (format->readImageHeader) && - (strlen(format->fileExtension)>0) && - (strlen(format->realName)>0) ) { - - format->next=firstFormat; - firstFormat=format; - - return 0; - - } - else { - fprintf(stderr,"addImageFormat: information missing in file format %s\n", - format->realName); - return -1; - } -} - -/** adds a format at the end of the list of image formats. - Test if all mandatory fields have been filled */ -int addImageFormatAtEnd( PTRIMAGE_FORMAT format) -{ - PTRIMAGE_FORMAT f; - if ( (format->testImageFormat) && - (format->readImageHeader) && - (strlen(format->fileExtension)>0) && - (strlen(format->realName)>0) ) { - - format->next = NULL; - - if (firstFormat == NULL) { - firstFormat=format; - } - else { - for(f=firstFormat;(f->next!=NULL);f=f->next) - ; - f->next=format; - } - - return 0; - - } - else { - fprintf(stderr,"addImageFormatAtEnd: information missing in file format %s\n", - format->realName); - return -1; - } -} - - -/** creates supported image formats */ -void initSupportedFileFormat() -{ - PTRIMAGE_FORMAT f; - if ( InrimageFormat == NULL ) { - 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 ); - InrimageFormat = createInrimageFormat(); - addImageFormat( InrimageFormat ); - } -} - - - -PTRIMAGE_FORMAT firstImageFormat() { - return firstFormat; -} - - - -/** prints supported image formats */ -void printSupportedFileFormat() { - PTRIMAGE_FORMAT f; - int i; - - initSupportedFileFormat(); - - for(i=0, f=firstFormat;(f!=NULL);i++, f=f->next) { - if ( (f->testImageFormat) && - (f->readImageHeader) && - (strlen(f->fileExtension)>0) && - (strlen(f->realName)>0)) { - fprintf( stderr, "#%2d: format name ='%s', extensions='%s'", - i, f->realName, f->fileExtension ); - if (f->readImageHeader) - fprintf( stderr, ", read" ); - if (f->writeImage) - fprintf( stderr, ", write" ); - fprintf( stderr, "\n" ); - } - } -} - - -/** remove supported image formats */ -void removeSupportedFileFormat() { - PTRIMAGE_FORMAT f=firstFormat; - - while( f != NULL) { - PTRIMAGE_FORMAT f_old = f; - f = f->next; - ImageIO_free( f_old); - } - InrimageFormat=NULL; - -} - - -/** trilinear interpolation in an _image float type - */ -float triLinInterp(const _image* image, - float posx, - float posy, - float posz, - float value_outside /*= 0.f */) -{ - const int dimx = image->xdim; - const int dimy = image->ydim; - const int dimz = image->zdim; - const int dimxy = dimx*dimy; - - if(posx < 0.f || posy < 0.f || posz < 0.f ) - return value_outside; - - posx = static_cast(posx /(image->vx)); - posy = static_cast(posy /(image->vy)); - posz = static_cast(posz /(image->vz)); - - //patch suggested by J.Cugnoni to prevent integer overflow - if(posz >= dimz-1 || posy >= dimy-1 || posx >= dimx-1) - return value_outside; - - 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 = i2-posz; - const float KI1 = posz-i1; - const float KJ2 = j2-posy; - const float KJ1 = posy-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) * (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-k1); - ); - return 0.f; -} - -// Gives the value of the image at pixel (i,j,k), converted in float. -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(image, i, j, k); ); - - return 0.f; -} - -/** convert the data of the image to float -*/ -void convertImageTypeToFloat(_image* image){ - if(image->wordKind == WK_FLOAT && image->wdim == 4) - return; - - const unsigned int dimx = image->xdim; - const unsigned int dimy = image->ydim; - const unsigned int dimz = image->zdim; - - float * array = (float*)ImageIO_alloc (dimx * dimy * dimz *sizeof(float)); - if (array == NULL ) { - fprintf ( stderr, "allocation error\n" ); - return; - } - - CGAL_IMAGE_IO_CASE - (image, - Word * typedArray = (Word *)(image->data); - for(unsigned int i = 0; idata ); - image->data = array; - - image->wordKind = WK_FLOAT; - image->wdim = 4; -} +#include "ImageIO.h" +#include "ImageIO_impl.h" +#endif // CGAL_HEADER_ONLY diff --git a/CGAL_ImageIO/src/CGAL_ImageIO/Image_3.cpp b/CGAL_ImageIO/src/CGAL_ImageIO/Image_3.cpp index f0f5e028903..e16e8601161 100644 --- a/CGAL_ImageIO/src/CGAL_ImageIO/Image_3.cpp +++ b/CGAL_ImageIO/src/CGAL_ImageIO/Image_3.cpp @@ -18,206 +18,9 @@ // // Author(s) : Laurent Rineau, Pierre Alliez +#ifndef CGAL_HEADER_ONLY + #include -#include +#include -namespace CGAL { - -bool Image_3::private_read(_image* im) -{ - if(im != 0) - { - if(image() != 0) - { - ::_freeImage(image()); - } - image_ptr = Image_shared_ptr(im, Image_deleter()); - -// std::cerr << -// boost::format("image=%1% (xdim=%2%, ydim=%3%, zdim=%4%)\n") -// % image_ptr.get() % image_ptr->xdim % image_ptr->ydim % image_ptr->zdim; - - } - return im != 0; -} - -void Image_3::gl_draw(const float point_size, - const unsigned char r, - const unsigned char g, - const unsigned char b) -{ - if(image_ptr.get() == NULL) - return; - - glPointSize(point_size); - glColor3ub(r,g,b); - glBegin(GL_POINTS); - unsigned char *pData = (unsigned char*)image_ptr->data; - unsigned int xy = image_ptr->xdim * image_ptr->ydim; - for(unsigned int i=0;ixdim;i+=5) - for(unsigned int j=0;jydim;j+=5) - for(unsigned int k=0;kzdim;k+=5) - { - unsigned char value = pData[xy*k + j*image_ptr->xdim + i]; - if(value > 0) - { - double x = image_ptr->vx * i; - double y = image_ptr->vy * j; - double z = image_ptr->vz * k; - glVertex3d(x,y,z); - } - } - glEnd(); -} // end Image_3::gl_draw - - -void Image_3::gl_draw_bbox(const float line_width, - const unsigned char red, - const unsigned char green, - const unsigned char blue) -{ - if(!image_ptr) - return; - - glLineWidth(line_width); - glColor3ub(red,green,blue); - glBegin(GL_LINES); - - struct Point { - double x_; - double y_; - double z_; - Point(double x, double y, double z) : x_(x), y_(y), z_(z) {}; - - double x() const { return x_; } - double y() const { return y_; } - double z() const { return z_; } - }; - - const double xmax = (image_ptr->xdim - 1.0)*(image_ptr->vx); - const double ymax = (image_ptr->ydim - 1.0)*(image_ptr->vy); - const double zmax = (image_ptr->zdim - 1.0)*(image_ptr->vz); - - Point a(0.0, 0.0, 0.0); - Point b(0.0, ymax, 0.0); - Point c(0.0, ymax, zmax); - Point d(0.0, 0.0, zmax); - Point e(xmax, 0.0, 0.0); - Point f(xmax, ymax, 0.0); - Point g(xmax, ymax, zmax); - Point h(xmax, 0.0, zmax); - - glVertex3d(a.x(),a.y(),a.z()); - glVertex3d(b.x(),b.y(),b.z()); - - glVertex3d(b.x(),b.y(),b.z()); - glVertex3d(c.x(),c.y(),c.z()); - - glVertex3d(c.x(),c.y(),c.z()); - glVertex3d(d.x(),d.y(),d.z()); - - glVertex3d(d.x(),d.y(),d.z()); - glVertex3d(a.x(),a.y(),a.z()); - - glVertex3d(e.x(),e.y(),e.z()); - glVertex3d(f.x(),f.y(),f.z()); - - glVertex3d(f.x(),f.y(),f.z()); - glVertex3d(g.x(),g.y(),g.z()); - - glVertex3d(g.x(),g.y(),g.z()); - glVertex3d(h.x(),h.y(),h.z()); - - glVertex3d(h.x(),h.y(),h.z()); - glVertex3d(e.x(),e.y(),e.z()); - - glVertex3d(a.x(),a.y(),a.z()); - glVertex3d(e.x(),e.y(),e.z()); - - glVertex3d(d.x(),d.y(),d.z()); - glVertex3d(h.x(),h.y(),h.z()); - - glVertex3d(c.x(),c.y(),c.z()); - glVertex3d(g.x(),g.y(),g.z()); - - glVertex3d(b.x(),b.y(),b.z()); - glVertex3d(f.x(),f.y(),f.z()); - - glEnd(); -} // end Image_3::gl_draw_bbox - -} // end namespace CGAL - -#ifdef CGAL_USE_VTK - -#include -#include - -namespace CGAL { - -namespace { - -struct VTK_to_ImageIO_type_mapper { - WORD_KIND wordKind; - SIGN sign; - unsigned int wdim; -}; - -static const VTK_to_ImageIO_type_mapper VTK_to_ImageIO_type[VTK_ID_TYPE] = - { { WK_UNKNOWN, SGN_UNKNOWN, 0}, // 0=VTK_VOID - { WK_UNKNOWN, SGN_UNKNOWN, 0}, // 1=VTK_BIT - { WK_FIXED, SGN_SIGNED, 1}, // 2=VTK_CHAR - { WK_FIXED, SGN_UNSIGNED, 1}, // 3=VTK_UNSIGNED_CHAR - { WK_FIXED, SGN_SIGNED, 2}, // 4=VTK_SHORT - { WK_FIXED, SGN_UNSIGNED, 2}, // 5=VTK_UNSIGNED_SHORT - { WK_FIXED, SGN_SIGNED, 4}, // 6=VTK_INT - { WK_FIXED, SGN_UNSIGNED, 4}, // 7=VTK_UNSIGNED_INT - { WK_FIXED, SGN_SIGNED, 8}, // 8=VTK_LONG - { WK_FIXED, SGN_UNSIGNED, 8}, // 9=VTK_UNSIGNED_LONG - { WK_FLOAT, SGN_SIGNED, 4}, // 10=VTK_FLOAT - { WK_FIXED, SGN_SIGNED, 8} // 11=VTK_DOUBLE - }; - -} //end anonymous namespace - -bool -Image_3::read_vtk_image_data(vtkImageData* vtk_image) -{ - if(!vtk_image) - return false; - - _image* image = ::_initImage(); - const int* dims = vtk_image->GetDimensions(); - const double* spacing = vtk_image->GetSpacing(); - image->vectMode = VM_SCALAR; - image->xdim = dims[0]; - image->ydim = dims[1]; - image->zdim = dims[2]; - image->vdim = 1; - image->vx = spacing[0]; - image->vy = spacing[1]; - image->vz = spacing[2]; - vtk_image->Update(); - image->endianness = ::_getEndianness(); - int vtk_type = vtk_image->GetScalarType(); - if(vtk_type == VTK_SIGNED_CHAR) vtk_type = VTK_CHAR; - if(vtk_type < 0 || vtk_type > VTK_DOUBLE) - vtk_type = VTK_DOUBLE; - const VTK_to_ImageIO_type_mapper& imageio_type = - VTK_to_ImageIO_type[vtk_type]; - image->wdim = imageio_type.wdim; - image->wordKind = imageio_type.wordKind; - image->sign = imageio_type.sign; - image->data = ::ImageIO_alloc(dims[0]*dims[1]*dims[2]*image->wdim); - std::cerr << "GetNumberOfTuples()=" << vtk_image->GetPointData()->GetScalars()->GetNumberOfTuples() - << "\nimage->size()=" << dims[0]*dims[1]*dims[2] - << "\nwdim=" << image->wdim << '\n'; - assert(vtk_image->GetPointData()->GetScalars()->GetNumberOfTuples() == dims[0]*dims[1]*dims[2]); - vtk_image->GetPointData()->GetScalars()->ExportToVoidPointer(image->data); - - return this->private_read(image); -} - -} // end namespace CGAL - -#endif // CGAL_USE_VTK +#endif // CGAL_HEADER_ONLY diff --git a/CGAL_ImageIO/src/CGAL_ImageIO/bmpendian.cpp b/CGAL_ImageIO/src/CGAL_ImageIO/bmpendian.cpp index 8ca93732ef9..f252541763b 100644 --- a/CGAL_ImageIO/src/CGAL_ImageIO/bmpendian.cpp +++ b/CGAL_ImageIO/src/CGAL_ImageIO/bmpendian.cpp @@ -19,223 +19,9 @@ // // Author(s) : ASCLEPIOS Project (INRIA Sophia-Antipolis), Laurent Rineau +#ifndef CGAL_HEADER_ONLY -/* - * These functions read and write our basic integer types from a little-endian - * file. The endian and word-size of the host machine will not affect this - * code. The only assumption made is that the C data type (char) is one byte - * long. This should be a safe assumption. - */ - -#include -#include "bmptypes.h" #include "bmpendian.h" +#include "bmpendian_impl.h" -/***************************************************************************** -* -* Read functions. All read functions take an open file pointer as the first -* parameter and a pointer to data as the second parameter. The return value -* will be 0 on success, and EOF on failure. If successful, the second -* parameter will point to the data read. -*/ - -/* - * The CGAL_INT8 and CGAL_UINT8 types are stored as a single byte on disk. The INT8 - * type is a signed integer with range (-128..127). The CGAL_UINT8 type is an - * unsigned integer with range (0..255). - */ -int readINT8little(FILE *f, CGAL_INT8 *i) -{ - int rc; - - rc = fgetc(f); - if (rc == EOF) - return rc; - - *i = (rc & 0xff); - return 0; -} - -int readUINT8little(FILE *f, CGAL_UINT8 *i) -{ - int rc; - - rc = fgetc(f); - if (rc == EOF) - return rc; - - *i = (rc & 0xff); - return 0; -} - - -/* - * The CGAL_INT16 and CGAL_UINT16 types are stored as two bytes on disk. The INT16 type - * is a signed integer with range (-32768..32767). The CGAL_UINT16 type is an - * unisgned integer with range (0..65535). - */ -int readINT16little(FILE *f, CGAL_INT16 *i) -{ - int rc; - CGAL_INT16 temp = 0; - - temp = (fgetc(f) & 0xff); - - rc = fgetc(f); - if (rc == EOF) - return rc; - - temp |= ((rc & 0xff) << 8); - *i = temp; - return 0; -} - -int readUINT16little(FILE *f, CGAL_UINT16 *i) -{ - int rc; - CGAL_UINT16 temp = 0; - - temp = (fgetc(f) & 0xff); - - rc = fgetc(f); - if (rc == EOF) - return rc; - - temp |= ((rc & 0xff) << 8); - *i = temp; - return 0; -} - -/* - * The CGAL_INT32 and CGAL_UINT32 types are stored as four bytes on disk. The INT32 - * type is a signed integer with range (-2147483648..2147483647). The CGAL_UINT32 - * type is an unisgned integer with range (0..4294967295). - */ -int readINT32little(FILE *f, CGAL_INT32 *i) -{ - int rc; - CGAL_INT32 temp = 0; - - temp = ((long)fgetc(f) & 0xff); - temp |= (((long)fgetc(f) & 0xff) << 8); - temp |= (((long)fgetc(f) & 0xff) << 16); - - rc = fgetc(f); - if (rc == EOF) - return rc; - - temp |= (((long)rc & 0xff) << 24); - *i = temp; - return 0; -} - -int readUINT32little(FILE *f, CGAL_UINT32 *i) -{ - int rc; - CGAL_UINT32 temp = 0; - - temp = ((long)fgetc(f) & 0xff); - temp |= (((long)fgetc(f) & 0xff) << 8); - temp |= (((long)fgetc(f) & 0xff) << 16); - - rc = fgetc(f); - if (rc == EOF) - return rc; - - temp |= (((long)rc & 0xff) << 24); - *i = temp; - return 0; -} - -/***************************************************************************** -* -* Write functions. All write functions take an open file pointer as the first -* parameter and a data as the second parameter. The return value will be 0 on -* success, and EOF on failure. If successful, the second parameter will have -* been written to the open file. -*/ - -int writeINT8little(FILE *f, CGAL_INT8 i) -{ - return fputc(i, f); -} - -int writeUINT8little(FILE *f, CGAL_UINT8 i) -{ - return fputc(i, f); -} - -int writeINT16little(FILE *f, CGAL_INT16 i) -{ - int rc; - - rc = fputc((i & 0xff), f); - if (rc == EOF) - return rc; - - return fputc(((i >> 8) & 0xff), f); -} - -int writeUINT16little(FILE *f, CGAL_UINT16 i) -{ - int rc; - - rc = fputc((i & 0xff), f); - if (rc == EOF) - return rc; - - return fputc(((i >> 8) & 0xff), f); -} - -int writeINT32little(FILE *f, CGAL_INT32 i) -{ - int rc; - - rc = fputc((i & 0xff), f); - if (rc == EOF) - return rc; - - rc = fputc(((i >> 8) & 0xff), f); - if (rc == EOF) - return rc; - - rc = fputc(((i >> 16) & 0xff), f); - if (rc == EOF) - return rc; - - return fputc(((i >> 24) & 0xff), f); -} - - -int writeUINT32little(FILE *f, CGAL_UINT32 i) -{ - int rc; - - rc = fputc((i & 0xff), f); - if (rc == EOF) - return rc; - - rc = fputc(((i >> 8) & 0xff), f); - if (rc == EOF) - return rc; - - rc = fputc(((i >> 16) & 0xff), f); - if (rc == EOF) - return rc; - - return fputc(((i >> 24) & 0xff), f); -} - -/* - * Formatting information for emacs in c-mode - * - * Local Variables: - * c-indent-level:4 - * c-continued-statement-offset:4 - * c-brace-offset:-4 - * c-brace-imaginary-offset:0 - * c-argdecl-indent:4 - * c-label-offset:-4 - * End: - */ - +#endif // CGAL_HEADER_ONLY diff --git a/CGAL_ImageIO/src/CGAL_ImageIO/bmpendian.h b/CGAL_ImageIO/src/CGAL_ImageIO/bmpendian.h index 76a7fb67511..53593d27540 100644 --- a/CGAL_ImageIO/src/CGAL_ImageIO/bmpendian.h +++ b/CGAL_ImageIO/src/CGAL_ImageIO/bmpendian.h @@ -54,6 +54,10 @@ int writeUINT8little(FILE *f, CGAL_UINT8 i); int writeUINT16little(FILE *f, CGAL_UINT16 i); int writeUINT32little(FILE *f, CGAL_UINT32 i); +#ifdef CGAL_HEADER_ONLY +#include "bmpendian_impl.h" +#endif // CGAL_HEADER_ONLY + #endif /* __ENDIAN_H_INCLUDED__ */ diff --git a/CGAL_ImageIO/src/CGAL_ImageIO/bmpendian_impl.h b/CGAL_ImageIO/src/CGAL_ImageIO/bmpendian_impl.h new file mode 100644 index 00000000000..8686a187759 --- /dev/null +++ b/CGAL_ImageIO/src/CGAL_ImageIO/bmpendian_impl.h @@ -0,0 +1,257 @@ +// Copyright (c) 2005-2008 ASCLEPIOS Project, INRIA Sophia-Antipolis (France) +// All rights reserved. +// +// This file is part of the ImageIO Library, and as been adapted for +// CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the +// GNU Lesser General Public License as published by the Free Software Foundation; +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// These files are provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : ASCLEPIOS Project (INRIA Sophia-Antipolis), Laurent Rineau + +#ifdef CGAL_HEADER_ONLY +#define CGAL_INLINE_FUNCTION inline +#else +#define CGAL_INLINE_FUNCTION +#endif + +/* + * These functions read and write our basic integer types from a little-endian + * file. The endian and word-size of the host machine will not affect this + * code. The only assumption made is that the C data type (char) is one byte + * long. This should be a safe assumption. + */ + +#include +#include "bmptypes.h" + +/***************************************************************************** +* +* Read functions. All read functions take an open file pointer as the first +* parameter and a pointer to data as the second parameter. The return value +* will be 0 on success, and EOF on failure. If successful, the second +* parameter will point to the data read. +*/ + +/* + * The CGAL_INT8 and CGAL_UINT8 types are stored as a single byte on disk. The INT8 + * type is a signed integer with range (-128..127). The CGAL_UINT8 type is an + * unsigned integer with range (0..255). + */ +CGAL_INLINE_FUNCTION +int readINT8little(FILE *f, CGAL_INT8 *i) +{ + int rc; + + rc = fgetc(f); + if (rc == EOF) + return rc; + + *i = (rc & 0xff); + return 0; +} + +CGAL_INLINE_FUNCTION +int readUINT8little(FILE *f, CGAL_UINT8 *i) +{ + int rc; + + rc = fgetc(f); + if (rc == EOF) + return rc; + + *i = (rc & 0xff); + return 0; +} + + +/* + * The CGAL_INT16 and CGAL_UINT16 types are stored as two bytes on disk. The INT16 type + * is a signed integer with range (-32768..32767). The CGAL_UINT16 type is an + * unisgned integer with range (0..65535). + */ +CGAL_INLINE_FUNCTION +int readINT16little(FILE *f, CGAL_INT16 *i) +{ + int rc; + CGAL_INT16 temp = 0; + + temp = (fgetc(f) & 0xff); + + rc = fgetc(f); + if (rc == EOF) + return rc; + + temp |= ((rc & 0xff) << 8); + *i = temp; + return 0; +} + +CGAL_INLINE_FUNCTION +int readUINT16little(FILE *f, CGAL_UINT16 *i) +{ + int rc; + CGAL_UINT16 temp = 0; + + temp = (fgetc(f) & 0xff); + + rc = fgetc(f); + if (rc == EOF) + return rc; + + temp |= ((rc & 0xff) << 8); + *i = temp; + return 0; +} + +/* + * The CGAL_INT32 and CGAL_UINT32 types are stored as four bytes on disk. The INT32 + * type is a signed integer with range (-2147483648..2147483647). The CGAL_UINT32 + * type is an unisgned integer with range (0..4294967295). + */ +CGAL_INLINE_FUNCTION +int readINT32little(FILE *f, CGAL_INT32 *i) +{ + int rc; + CGAL_INT32 temp = 0; + + temp = ((long)fgetc(f) & 0xff); + temp |= (((long)fgetc(f) & 0xff) << 8); + temp |= (((long)fgetc(f) & 0xff) << 16); + + rc = fgetc(f); + if (rc == EOF) + return rc; + + temp |= (((long)rc & 0xff) << 24); + *i = temp; + return 0; +} + +CGAL_INLINE_FUNCTION +int readUINT32little(FILE *f, CGAL_UINT32 *i) +{ + int rc; + CGAL_UINT32 temp = 0; + + temp = ((long)fgetc(f) & 0xff); + temp |= (((long)fgetc(f) & 0xff) << 8); + temp |= (((long)fgetc(f) & 0xff) << 16); + + rc = fgetc(f); + if (rc == EOF) + return rc; + + temp |= (((long)rc & 0xff) << 24); + *i = temp; + return 0; +} + +/***************************************************************************** +* +* Write functions. All write functions take an open file pointer as the first +* parameter and a data as the second parameter. The return value will be 0 on +* success, and EOF on failure. If successful, the second parameter will have +* been written to the open file. +*/ + +CGAL_INLINE_FUNCTION +int writeINT8little(FILE *f, CGAL_INT8 i) +{ + return fputc(i, f); +} + +CGAL_INLINE_FUNCTION +int writeUINT8little(FILE *f, CGAL_UINT8 i) +{ + return fputc(i, f); +} + +CGAL_INLINE_FUNCTION +int writeINT16little(FILE *f, CGAL_INT16 i) +{ + int rc; + + rc = fputc((i & 0xff), f); + if (rc == EOF) + return rc; + + return fputc(((i >> 8) & 0xff), f); +} + +CGAL_INLINE_FUNCTION +int writeUINT16little(FILE *f, CGAL_UINT16 i) +{ + int rc; + + rc = fputc((i & 0xff), f); + if (rc == EOF) + return rc; + + return fputc(((i >> 8) & 0xff), f); +} + +CGAL_INLINE_FUNCTION +int writeINT32little(FILE *f, CGAL_INT32 i) +{ + int rc; + + rc = fputc((i & 0xff), f); + if (rc == EOF) + return rc; + + rc = fputc(((i >> 8) & 0xff), f); + if (rc == EOF) + return rc; + + rc = fputc(((i >> 16) & 0xff), f); + if (rc == EOF) + return rc; + + return fputc(((i >> 24) & 0xff), f); +} + + +CGAL_INLINE_FUNCTION +int writeUINT32little(FILE *f, CGAL_UINT32 i) +{ + int rc; + + rc = fputc((i & 0xff), f); + if (rc == EOF) + return rc; + + rc = fputc(((i >> 8) & 0xff), f); + if (rc == EOF) + return rc; + + rc = fputc(((i >> 16) & 0xff), f); + if (rc == EOF) + return rc; + + return fputc(((i >> 24) & 0xff), f); +} + +/* + * Formatting information for emacs in c-mode + * + * Local Variables: + * c-indent-level:4 + * c-continued-statement-offset:4 + * c-brace-offset:-4 + * c-brace-imaginary-offset:0 + * c-argdecl-indent:4 + * c-label-offset:-4 + * End: + */ + diff --git a/CGAL_ImageIO/src/CGAL_ImageIO/fgetns.cpp b/CGAL_ImageIO/src/CGAL_ImageIO/fgetns.cpp index 31fe741de29..8145f55aa67 100644 --- a/CGAL_ImageIO/src/CGAL_ImageIO/fgetns.cpp +++ b/CGAL_ImageIO/src/CGAL_ImageIO/fgetns.cpp @@ -19,23 +19,9 @@ // // Author(s) : ASCLEPIOS Project (INRIA Sophia-Antipolis), Laurent Rineau -#include +#ifndef CGAL_HEADER_ONLY -#include "gis.h" -#include "inr.h" +#include "fgets.h" +#include "fgets_impl.h" -/* get a string from a file and discard the ending newline character - if any */ -char *fgetns(char *str, int n, _image *im ) { - char *ret; - int l; - - memset( str, 0, n ); - ret = ImageIO_gets( im, str, n ); - - if(!ret) return NULL; - - l = strlen(str); - if(l > 0 && str[l-1] == '\n') str[l-1] = '\0'; - return ret; -} +#endif // CGAL_HEADER_ONLY diff --git a/CGAL_ImageIO/src/CGAL_ImageIO/fgetns.h b/CGAL_ImageIO/src/CGAL_ImageIO/fgetns.h index 8cb1764d010..7c243524426 100644 --- a/CGAL_ImageIO/src/CGAL_ImageIO/fgetns.h +++ b/CGAL_ImageIO/src/CGAL_ImageIO/fgetns.h @@ -19,6 +19,9 @@ // // Author(s) : ASCLEPIOS Project (INRIA Sophia-Antipolis), Laurent Rineau +#ifndef FGETNS_H +#define FGETNS_H + #include #include "gis.h" @@ -27,3 +30,9 @@ /* get a string from a file and discard the ending newline character if any */ char *fgetns(char *str, int n, _image *im ); + +#ifdef CGAL_HEADER_ONLY +#include "fgetns_impl.h" +#endif // CGAL_HEADER_ONLY + +#endif // FGETNS_H diff --git a/CGAL_ImageIO/src/CGAL_ImageIO/fgetns_impl.h b/CGAL_ImageIO/src/CGAL_ImageIO/fgetns_impl.h new file mode 100644 index 00000000000..d3ffcf2d947 --- /dev/null +++ b/CGAL_ImageIO/src/CGAL_ImageIO/fgetns_impl.h @@ -0,0 +1,48 @@ +// Copyright (c) 2005-2008 ASCLEPIOS Project, INRIA Sophia-Antipolis (France) +// All rights reserved. +// +// This file is part of the ImageIO Library, and as been adapted for +// CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the +// GNU Lesser General Public License as published by the Free Software Foundation; +// either version 3 of the License, or (at your option) any later version. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// These files are provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : ASCLEPIOS Project (INRIA Sophia-Antipolis), Laurent Rineau + +#ifdef CGAL_HEADER_ONLY +#define CGAL_INLINE_FUNCTION inline +#else +#define CGAL_INLINE_FUNCTION +#endif + +#include + +#include "gis.h" +#include "inr.h" + +/* get a string from a file and discard the ending newline character + if any */ +CGAL_INLINE_FUNCTION +char *fgetns(char *str, int n, _image *im ) { + char *ret; + int l; + + memset( str, 0, n ); + ret = ImageIO_gets( im, str, n ); + + if(!ret) return NULL; + + l = strlen(str); + if(l > 0 && str[l-1] == '\n') str[l-1] = '\0'; + return ret; +} diff --git a/cppfiles.txt b/cppfiles.txt index 3d85f6bbfcc..933432f7871 100644 --- a/cppfiles.txt +++ b/cppfiles.txt @@ -66,11 +66,11 @@ DONE #include "/home/gdamiand/sources/CGAL/CGAL_ImageIO/src/CGAL_ImageIO/gif.cpp DONE #include "/home/gdamiand/sources/CGAL/CGAL_ImageIO/src/CGAL_ImageIO/gis.cpp" DONE #include "/home/gdamiand/sources/CGAL/CGAL_ImageIO/src/CGAL_ImageIO/bmp.cpp" DONE #include "/home/gdamiand/sources/CGAL/CGAL_ImageIO/src/CGAL_ImageIO/reech4x4.cpp" - -#include "/home/gdamiand/sources/CGAL/CGAL_ImageIO/src/CGAL_ImageIO/bmpendian.cpp" -#include "/home/gdamiand/sources/CGAL/CGAL_ImageIO/src/CGAL_ImageIO/iris.cpp" -#include "/home/gdamiand/sources/CGAL/CGAL_ImageIO/src/CGAL_ImageIO/fgetns.cpp" -#include "/home/gdamiand/sources/CGAL/CGAL_ImageIO/src/CGAL_ImageIO/Image_3.cpp" -#include "/home/gdamiand/sources/CGAL/CGAL_ImageIO/src/CGAL_ImageIO/pnm.cpp" +DONE #include "/home/gdamiand/sources/CGAL/CGAL_ImageIO/src/CGAL_ImageIO/bmpendian.cpp" +DONE #include "/home/gdamiand/sources/CGAL/CGAL_ImageIO/src/CGAL_ImageIO/fgetns.cpp" +DONE #include "/home/gdamiand/sources/CGAL/CGAL_ImageIO/src/CGAL_ImageIO/Image_3.cpp" +DONE #include "/home/gdamiand/sources/CGAL/CGAL_ImageIO/src/CGAL_ImageIO/iris.cpp" #include "/home/gdamiand/sources/CGAL/CGAL_ImageIO/src/CGAL_ImageIO/ImageIO.cpp" + +#include "/home/gdamiand/sources/CGAL/CGAL_ImageIO/src/CGAL_ImageIO/pnm.cpp" #include "/home/gdamiand/sources/CGAL/CGAL_ImageIO/src/CGAL_ImageIO/inr.cpp"