// 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$ // SPDX-License-Identifier: LGPL-3.0+ // // // Author(s) : ASCLEPIOS Project (INRIA Sophia-Antipolis), Laurent Rineau /************************************************************************* * convert.c - conversion between types * * $Id$ * * Copyright©INRIA 1999 * * AUTHOR: * Gregoire Malandain (greg@sophia.inria.fr) * * CREATION DATE: * June, 9 1998 * * ADDITIONS, CHANGES * * - Tue Feb 22 11:25:39 MET 2000 (G. Malandain) * add in ConvertBuffer(): * USHORT to UCHAR * USHORT to SHORT * */ #ifdef CGAL_HEADER_ONLY #define CGAL_INLINE_FUNCTION inline #else #define CGAL_INLINE_FUNCTION #endif CGAL_INLINE_FUNCTION void ConvertBuffer( void *bufferIn, bufferType typeIn, void *bufferOut, bufferType typeOut, int bufferLength ) { const char *proc = "ConvertBuffer"; int i; u8 *u8buf; s8 *s8buf; u16 *u16buf; s16 *s16buf; s32 *s32buf; r32 *r32buf; r64 *r64buf; if ( (typeOut == typeIn) && (bufferOut == bufferIn) ) return; if ( bufferLength <= 0 ) { fprintf( stderr, " Fatal error in %s: buffer length is negative or zero.\n", proc ); return; } if ( (bufferIn == (void*)NULL) || (bufferOut == (void*)NULL) ) { fprintf( stderr, " Fatal error in %s: NULL buffer(s).\n", proc ); return; } switch ( typeOut ) { case CGAL_SCHAR : { s8buf = (s8*)bufferOut; s8 min = -128, max = 127; switch( typeIn ) { case CGAL_SCHAR : if ( bufferOut == bufferIn ) return; (void)memcpy( bufferOut, bufferIn, bufferLength * sizeof(s8) ); break; case CGAL_FLOAT : r32buf = (r32*)bufferIn; for (i=bufferLength; i>0; i--, s8buf++, r32buf++ ) { if ( *r32buf < min ) *s8buf = min; else if ( *r32buf < 0.0 ) *s8buf = (s8)(*r32buf - 0.5); else if ( *r32buf < max ) *s8buf = (s8)(*r32buf + 0.5); else *s8buf = max; } break; case CGAL_DOUBLE : r64buf = (r64*)bufferIn; for (i=bufferLength; i>0; i--, s8buf++, r64buf++ ) { if ( *r64buf < min ) *s8buf = min; else if ( *r64buf < 0.0 ) *s8buf = (s8)(*r64buf - 0.5); else if ( *r64buf < max ) *s8buf = (s8)(*r64buf + 0.5); else *s8buf = max; } break; default : fprintf( stderr, " Error in %s: such conversion not yet implemented.\n", proc ); return; } break; /* end case typeOut = CGAL_SCHAR */ } case CGAL_UCHAR : { u8buf = (u8*)bufferOut; u8 min = 0, max = 255; switch( typeIn ) { case CGAL_UCHAR : if ( bufferOut == bufferIn ) return; (void)memcpy( bufferOut, bufferIn, bufferLength * sizeof(u8) ); break; case CGAL_USHORT : u16buf = (u16*)bufferIn; for (i=bufferLength; i>0; i--, u8buf++, u16buf++ ) { if ( *u16buf < max ) *u8buf = (u8)*u16buf; else *u8buf = max; } break; case CGAL_FLOAT : r32buf = (r32*)bufferIn; for (i=bufferLength; i>0; i--, u8buf++, r32buf++ ) { if ( *r32buf < min ) *u8buf = min; else if ( *r32buf < max ) *u8buf = (u8)(*r32buf + 0.5); else *u8buf = max; } break; case CGAL_DOUBLE : r64buf = (r64*)bufferIn; for (i=bufferLength; i>0; i--, u8buf++, r64buf++ ) { if ( *r64buf < min ) *u8buf = min; else if ( *r64buf < max ) *u8buf = (u8)(*r64buf + 0.5); else *u8buf = max; } break; default : fprintf( stderr, " Error in %s: such conversion not yet implemented.\n", proc ); return; } break; /* end case typeOut = CGAL_UCHAR */ } case CGAL_SSHORT : { s16buf = (s16*)bufferOut; s16 min = -32768, max = 32767; switch( typeIn ) { case CGAL_SSHORT : if ( bufferOut == bufferIn ) return; (void)memcpy( bufferOut, bufferIn, bufferLength * sizeof(s16) ); break; case CGAL_USHORT : u16buf = (u16*)bufferIn; for (i=bufferLength; i>0; i--, s16buf++, u16buf++ ) { if ( *u16buf < max ) *s16buf = (s16)*u16buf; else *s16buf = max; } break; case CGAL_FLOAT : r32buf = (r32*)bufferIn; for (i=bufferLength; i>0; i--, s16buf++, r32buf++ ) { if ( *r32buf < min ) *s16buf = min; else if ( *r32buf < 0.0 ) *s16buf = (s16)(*r32buf - 0.5); else if ( *r32buf < max ) *s16buf = (s16)(*r32buf + 0.5); else *s16buf = max; } break; case CGAL_DOUBLE : r64buf = (r64*)bufferIn; for (i=bufferLength; i>0; i--, s16buf++, r64buf++ ) { if ( *r64buf < min ) *s16buf = min; else if ( *r64buf < 0.0 ) *s16buf = (s16)(*r64buf - 0.5); else if ( *r64buf < max ) *s16buf = (s16)(*r64buf + 0.5); else *s16buf = max; } break; default : fprintf( stderr, " Error in %s: such conversion not yet implemented.\n", proc ); return; } break; /* end case typeOut = CGAL_SSHORT */ } case CGAL_USHORT : { u16buf = (u16*)bufferOut; u16 min = 0, max = 65535; switch( typeIn ) { case CGAL_USHORT : if ( bufferOut == bufferIn ) return; (void)memcpy( bufferOut, bufferIn, bufferLength * sizeof(u16) ); break; case CGAL_FLOAT : r32buf = (r32*)bufferIn; for (i=bufferLength; i>0; i--, u16buf++, r32buf++ ) { if ( *r32buf < min ) *u16buf = min; else if ( *r32buf < 0.0 ) *u16buf = (u16)(*r32buf - 0.5); else if ( *r32buf < max ) *u16buf = (u16)(*r32buf + 0.5); else *u16buf = max; } break; case CGAL_DOUBLE : r64buf = (r64*)bufferIn; for (i=bufferLength; i>0; i--, u16buf++, r64buf++ ) { if ( *r64buf < min ) *u16buf = min; else if ( *r64buf < 0.0 ) *u16buf = (u16)(*r64buf - 0.5); else if ( *r64buf < max ) *u16buf = (u16)(*r64buf + 0.5); else *u16buf = max; } break; default : fprintf( stderr, " Error in %s: such conversion not yet implemented.\n", proc ); return; } break; /* end case typeOut = CGAL_USHORT */ } case CGAL_INT : s32buf = (s32*)bufferOut; switch( typeIn ) { case CGAL_INT : if ( bufferOut == bufferIn ) return; (void)memcpy( bufferOut, bufferIn, bufferLength * sizeof(s32) ); break; case CGAL_FLOAT : r32buf = (r32*)bufferIn; for (i=bufferLength; i>0; i--, s32buf++, r32buf++ ) { *s32buf = (int)(*r32buf); } break; case CGAL_DOUBLE : r64buf = (r64*)bufferIn; for (i=bufferLength; i>0; i--, s32buf++, r64buf++ ) { *s32buf = (int)(*r64buf); } break; default : fprintf( stderr, " Error in %s: such conversion not yet implemented.\n", proc ); return; } break; /* end case typeOut = CGAL_INT */ case CGAL_FLOAT : r32buf = (r32*)bufferOut; switch( typeIn ) { case CGAL_UCHAR : u8buf = (u8*)bufferIn; for (i=bufferLength; i>0; i--, r32buf++, u8buf++ ) { *r32buf = (float)(*u8buf); } break; case CGAL_SCHAR : s8buf = (s8*)bufferIn; for (i=bufferLength; i>0; i--, r32buf++, s8buf++ ) { *r32buf = (float)(*s8buf); } break; case CGAL_USHORT : u16buf = (u16*)bufferIn; for (i=bufferLength; i>0; i--, r32buf++, u16buf++ ) { *r32buf = (float)(*u16buf); } break; case CGAL_SSHORT : s16buf = (s16*)bufferIn; for (i=bufferLength; i>0; i--, r32buf++, s16buf++ ) { *r32buf = (float)(*s16buf); } break; case CGAL_INT : s32buf = (s32*)bufferIn; for (i=bufferLength; i>0; i--, r32buf++, s32buf++ ) { *r32buf = (float)(*s32buf); } break; case CGAL_FLOAT : if ( bufferOut == bufferIn ) return; (void)memcpy( bufferOut, bufferIn, bufferLength * sizeof(r32) ); break; case CGAL_DOUBLE : r64buf = (r64*)bufferIn; for (i=bufferLength; i>0; i--, r32buf++, r64buf++ ) { *r32buf = (float)(*r64buf); } break; default : fprintf( stderr, " Error in %s: such conversion not yet implemented.\n", proc ); return; } break; /* end case typeOut = CGAL_FLOAT */ case CGAL_DOUBLE : r64buf = (r64*)bufferOut; switch( typeIn ) { case CGAL_UCHAR : u8buf = (u8*)bufferIn; for (i=bufferLength; i>0; i--, r64buf++, u8buf++ ) { *r64buf = (double)(*u8buf); } break; case CGAL_SCHAR : s8buf = (s8*)bufferIn; for (i=bufferLength; i>0; i--, r64buf++, s8buf++ ) { *r64buf = (double)(*s8buf); } break; case CGAL_USHORT : u16buf = (u16*)bufferIn; for (i=bufferLength; i>0; i--, r64buf++, u16buf++ ) { *r64buf = (double)(*u16buf); } break; case CGAL_SSHORT : s16buf = (s16*)bufferIn; for (i=bufferLength; i>0; i--, r64buf++, s16buf++ ) { *r64buf = (double)(*s16buf); } break; case CGAL_INT : s32buf = (s32*)bufferIn; for (i=bufferLength; i>0; i--, r64buf++, s32buf++ ) { *r64buf = (double)(*s32buf); } break; case CGAL_FLOAT : r32buf = (r32*)bufferIn; for (i=bufferLength; i>0; i--, r32buf++, r64buf++ ) { *r64buf = (double)(*r32buf); } break; case CGAL_DOUBLE : if ( bufferOut == bufferIn ) return; (void)memcpy( bufferOut, bufferIn, bufferLength * sizeof(r64) ); break; default : fprintf( stderr, " Error in %s: such conversion not yet implemented.\n", proc ); return; } break; /* end case typeOut = CGAL_DOUBLE */ default : fprintf( stderr, " Error in %s: such output type not yet handled.\n", proc ); return; } } CGAL_INLINE_FUNCTION void Convert_r32_to_s8( r32 *theBuf, s8 *resBuf, int size ) { int i; r32* tb = theBuf; s8* rb = resBuf; for ( i=0; i