/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
/****************************************************************************
Acknowlegments
Portions of this file were based on the original code of the Ply library
of Greg Turk and on the work of Claudio Rocchini
****************************************************************************/
/****************************************************************************
History
$Log: not supported by cvs2svn $
Revision 1.12 2006/01/27 09:09:10 corsini
Fix signed/unsigned mismatch
Revision 1.11 2005/12/02 00:00:53 cignoni
Moved and corrected interpret_texture_name from plystuff.h to plylib.cpp
Revision 1.10 2005/11/26 00:22:46 cignoni
added untested code of interpret_texture
Revision 1.9 2005/11/12 07:07:47 cignoni
Changed Offset types to remove warnings
Revision 1.8 2005/03/15 11:46:52 cignoni
Cleaning of the automatic bbox caching support for ply files. First working version.
Revision 1.7 2005/01/03 10:35:59 cignoni
Improved the compatibility for ply format for faces having the list size (e.g. number of vertexes of a face) as a char instead of a uchar.
Added a couple of new face descriptors, corrected a bug in error reporting function (and restructured) and translated a few comments.
Thanks to Patrick Min for the careful bug reporting
Revision 1.6 2004/06/23 15:36:57 cignoni
Restructured management of error, now the standard open for any mesh type return the error code, the default success value is zero
Any import class has a method ErrorMsg that give a verbal description of an error code.
Revision 1.5 2004/06/23 00:06:45 ponchio
Moved #define LITTLE_MACHINE outside of #ifdef WIN32 (linux on PC is little too).
Revision 1.4 2004/05/12 17:21:08 ganovelli
inclusion of io.h removed (unnecessary)
Revision 1.3 2004/05/12 10:13:29 ganovelli
direct.h was included also without WIN32 definition
Revision 1.2 2004/04/06 21:48:50 cignoni
Commented out unused parameter names
Revision 1.1 2004/03/03 15:00:51 cignoni
Initial commit
****************************************************************************/
// Note that on ppc mac (the only bigendian machine around)
// the preprocessor def __BIG_ENDIAN__ is always defined.
// Otherwise we should be on a little endian machine (intel/amd based)
#ifndef __BIG_ENDIAN__
#define LITTLE_MACHINE
#endif
#ifdef WIN32
#define assert ASSERT
#else
#include <assert.h>
#endif
#ifdef _MSC_VER
#pragma warning( disable : 4267 )
#endif
#ifdef WIN32
#include <direct.h>
#endif
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <assert.h>
#include <vector>
#include <algorithm>
#include "plylib.h"
using namespace std;
namespace vcg{
namespace ply{
typedef unsigned short ushort;
typedef unsigned long ulong;
typedef unsigned char uchar;
typedef unsigned int uint;
//#ifdef USE_ZLIB
//#include <zlib.h>
//#define XFILE void
//#define pb_fclose gzclose
//#define pb_fopen gzopen
//#define pb_fgets(s,n,f) gzgets(f,s,n)
//#define pb_fread(b,s,n,f) gzread(f,b,(s)*(n))
//#else
#define XFILE FILE
#define pb_fclose fclose
#define pb_fopen fopen
#define pb_fgets(s,n,f) fgets(s,n,f)
#define pb_fread(b,s,n,f) fread(b,s,n,f)
//#endif
//#ifdef WIN32
#define pb_mkdir(n) _mkdir(n)
#define pb_access _access
#define pb_stat _stat
#define pb_open _open
#define pb_close _close
/*
#else
#define pb_mkdir(n) mkdir(n,0)
#define pb_access access
#define pb_stat stat
#define pb_open open
#define pb_close close
#endif
*/
// Funzioni statiche per la lettura di un elemento
int ReadBin ( XFILE * fp, const PlyProperty * pr, void * mem, int fmt );
int ReadAscii( XFILE * fp, const PlyProperty * pr, void * mem, int fmt );
const char * ::vcg::ply::PlyFile::typenames[9]=
{
"none",
"char",
"short",
"int",
"uchar",
"ushort",
"uint",
"float",
"double"
};
const char * PlyFile::newtypenames[9]=
{
"none",
"int8",
"int16",
"int32",
"uint8",
"uint16",
"uint32",
"float32",
"float64"
};
static int TypeSize[] = {
0, 1, 2, 4, 1, 2, 4, 4, 8
};
size_t PropDescriptor::memtypesize() const {return TypeSize[memtype1];}
size_t PropDescriptor::stotypesize() const {return TypeSize[stotype1];}
const char *PropDescriptor::memtypename() const {return PlyFile::typenames[memtype1];}
const char *PropDescriptor::stotypename() const {return PlyFile::typenames[stotype1];}
static char CrossType[9][9]=
{
{0,0,0,0,0,0,0,0,0},
{0,1,1,1,1,1,1,0,0},
{0,0,1,1,0,1,1,0,0},
{0,0,0,1,0,0,1,0,0},
{0,1,1,1,1,1,1,0,0},
{0,0,1,1,0,1,1,0,0},
{0,0,0,1,0,0,1,0,0},
{0,0,0,0,0,0,0,1,1},
{0,0,0,0,0,0,0,1,1}
};
// ******************************************************
// Funzioni di supporto per la lettura/scrittura dei dati
// ******************************************************
// Big-little endian
static inline void SwapShort( ushort * s )
{
assert(s);
*s = ushort( (int(*s)>>8) | (int(*s)<<8) );
}
static inline void SwapInt( uint * x )
{
assert(x);
*x =
( ((*x)>>24) & 0x000000FF ) |
( ((*x)>> 8) & 0x0000FF00 ) |
( ((*x)<< 8) & 0x00FF0000 ) |
( ((*x)<<24) & 0xFF000000 ) ;
}
static inline void SwapDouble( double * /*d*/ )
{
// Come si fa?
assert(0);
}
// Lettura tipi binari
static inline int ReadCharB( XFILE * fp, char * c, int /*format*/ )
{
assert(fp);
assert(c);
return pb_fread(c,1,1,fp);
}
static inline int ReadShortB( XFILE * fp, short * s, int format )
{
assert(fp);
assert(s);
int r;
r = pb_fread(s,sizeof(short),1,fp);
#ifdef LITTLE_MACHINE
if(format==F_BINBIG)
#else
if(format==F_BINLITTLE)
#endif
SwapShort((ushort *)s);
return r;
}
static inline int ReadIntB( XFILE * fp, int * i, int format )
{
assert(fp);
assert(i);
int r;
r = pb_fread(i,sizeof(int),1,fp);
#ifdef LITTLE_MACHINE
if(format==F_BINBIG)
#else
if(format==F_BINLITTLE)
#endif
SwapInt((uint *)i);
return r;
}
static inline int ReadUCharB( XFILE * fp, uchar * uc, int /*format*/ )
{
assert(fp);
assert(uc);
return pb_fread(uc,1,1,fp);
}
static inline int ReadUShortB( XFILE * fp, ushort * us, int format )
{
assert(fp);
assert(us);
int r;
r = pb_fread(us,sizeof(ushort),1,fp);
#ifdef LITTLE_MACHINE
if(format==F_BINBIG)
#else
if(format==F_BINLITTLE)
#endif
SwapShort(us);
r