⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rpf.c

📁 linux下将各类格式图片转换工具
💻 C
字号:
/* *  rpf.c:		Conversion of float to reduced precision format values * *  Written by:		Stefan Frank *			Richard Krampfl *			Ullrich Hafner *		 *  This file is part of FIASCO (獸籸actal 獻籱age 獳籲d 玈籩quence 獵O籨ec) *  Copyright (C) 1994-2000 Ullrich Hafner <hafner@bigfoot.de> *//* *  $Date: 2000/06/14 20:49:37 $ *  $Author: hafner $ *  $Revision: 5.1 $ *  $State: Exp $ */#include "config.h"#include "types.h"#include "macros.h"#include "error.h"#include "misc.h"#include "rpf.h"/*  * CAUTION: The IEEE float format must be used by your compiler, *          or all following code is void! */#ifdef WORDS_BIGENDIAN/* *  Big-Endian Architecture (e.g. SUN, Motorola) *  Memory representation of integer 0x00112233 is 00,11,22,33 */enum real_bytes {BYTE_0, BYTE_1, BYTE_2, BYTE_3};#else  /* not WORDS_BIGENDIAN *//* *  Little-Endian Architecture (e.g. Intel, VAX, Alpha) *  Memory representation of integer 0x00112233 is 33,22,11,00 */enum real_bytes {BYTE_3, BYTE_2, BYTE_1, BYTE_0};#endif /* not WORDS_BIGENDIAN */const int RPF_ZERO = -1;/*****************************************************************************			       private code  *****************************************************************************/intrtob (real_t f, const rpf_t *rpf)/* *  Convert real number 'f' into fixed point format. *  The real number in [-'range'; +'range'] is scaled to [-1 ; +1]. *  Sign and the first 'precision' - 1 bits of the mantissa are *  packed into one integer.   * *  Return value: *	real value in reduced precision format */{     unsigned int	mantissa;   int		exponent, sign;   union   {      float f;      unsigned char c[4];   } v;					/* conversion dummy */   f  /= rpf->range;			/* scale f to [-1,+1] */	   v.f = f;   /*    *  Extract mantissa (23 Bits), exponent (8 Bits) and sign (1 Bit)    */   mantissa = ((((v.c[BYTE_1] & 127) << 8 ) | v.c[BYTE_2]) << 8) | v.c[BYTE_3];   exponent = (((v.c[BYTE_0] & 127) << 1) | (v.c[BYTE_1] & 128 ? 1 : 0)) - 126;   sign     = v.c[BYTE_0] & 128 ? 1 : 0;		   /*    *  Generate reduced precision mantissa.    */   mantissa >>= 1;				/* shift 1 into from left */   mantissa  |= (1 << 22);   if (exponent > 0)       mantissa <<= exponent;   else      mantissa >>= -exponent;        mantissa >>= (23 - rpf->mantissa_bits - 1);   mantissa +=  1;			/* Round last bit. */   mantissa >>= 1;      if (mantissa == 0)			/* close to zero */      return RPF_ZERO;   else if (mantissa >= (1U << rpf->mantissa_bits)) /* overflow */      return sign;   else      return ((mantissa & ((1U << rpf->mantissa_bits) - 1)) << 1) | sign;}floatbtor (int binary, const rpf_t *rpf)/* *  Convert value 'binary' in reduced precision format to a real value. *  For more information refer to function lin_rtob() above. * *  Return value: *	converted value */{   unsigned int	mantissa;   int		sign, exponent;   union   {      float f;      unsigned char c[4];   } value;   if (binary == RPF_ZERO)      return 0;   if (binary < 0 || binary >= 1 << (rpf->mantissa_bits + 1))      error ("Reduced precision format: value %d out of range.", binary);   /*    *  Restore IEEE float format:    *  mantissa (23 Bits), exponent (8 Bits) and sign (1 Bit)    */      sign       = binary & 1;   mantissa   = (binary & ((1 << (rpf->mantissa_bits + 1)) - 1)) >> 1;    mantissa <<= (23 - rpf->mantissa_bits);   exponent   = 0;   if (mantissa == 0)   {      value.f = (sign ? -1.0 : 1.0);   }   else   {      while (!(mantissa & (1 << 22)))	/* normalize mantissa */      {	 exponent--;	 mantissa <<= 1;      }      mantissa <<= 1;      value.c[BYTE_0] = (sign << 7) | ((exponent + 126) >> 1);      value.c[BYTE_1] = (((exponent + 126) & 1) << 7)			| ((mantissa  >> 16) & 127);      value.c[BYTE_2] = (mantissa >> 8) & 255;      value.c[BYTE_3] = mantissa & 255;   }      return value.f * rpf->range;		/* expand [ -1 ; +1 ] to					   [ -range ; +range ] */}rpf_t *alloc_rpf (unsigned mantissa, fiasco_rpf_range_e range)/* *  Reduced precision format constructor. *  Allocate memory for the rpf_t structure. *  Number of mantissa bits is given by `mantissa'. *  The range of the real values is in the interval [-`range', +`range']. *  In case of invalid parameters, a structure with default values is *  returned.  * *  Return value *	pointer to the new rpf structure */{   rpf_t *rpf = Calloc (1, sizeof (rpf_t));      if (mantissa < 2)   {      warning (_("Size of RPF mantissa has to be in the interval [2,8]. "		 "Using minimum value 2.\n"));      mantissa = 2;   }   else if (mantissa > 8)   {      warning (_("Size of RPF mantissa has to be in the interval [2,8]. "		 "Using maximum value 8.\n"));      mantissa = 2;   }   rpf->mantissa_bits = mantissa;   rpf->range_e       = range;   switch (range)   {      case FIASCO_RPF_RANGE_0_75:	 rpf->range = 0.75;	 break;      case FIASCO_RPF_RANGE_1_50:	 rpf->range = 1.50;	 break;      case FIASCO_RPF_RANGE_2_00:	 rpf->range = 2.00;	 break;      case FIASCO_RPF_RANGE_1_00:	 rpf->range = 1.00;	 break;      default:	 warning (_("Invalid RPF range specified. Using default value 1.0."));	 rpf->range   = 1.00;	 rpf->range_e = FIASCO_RPF_RANGE_1_00;	 break;   }   return rpf;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -