Exemplo n.º 1
0
int stats3_decompress(unsigned char *in,int inlen,unsigned char *out, int *outlen)
{
  range_coder *c=range_new_coder(inlen);
  bcopy(in,c->bit_stream,inlen);
  c->bit_stream_length=inlen*8;
  c->bits_used=0;
  c->low=0;
  c->high=0xffffffff;
  range_decode_prefetch(c);

  stats3_decompress_bits(c,out,outlen);

  range_coder_free(c);
  return 0;
}
Exemplo n.º 2
0
Arquivo: recipe.c Projeto: Azizou/smac
int recipe_decode_field(struct recipe *recipe,stats_handle *stats, range_coder *c,
			int fieldnumber,char *value,int value_size)
{
  int normalised_value;
  int minimum;
  int maximum;
  int precision;

  int r;
  
  precision=recipe->fields[fieldnumber].precision;

  switch (recipe->fields[fieldnumber].type) {
  case FIELDTYPE_INTEGER:
    minimum=recipe->fields[fieldnumber].minimum;
    maximum=recipe->fields[fieldnumber].maximum;
    normalised_value=range_decode_equiprobable(c,maximum-minimum+2);
    if (normalised_value==(maximum-minimum+1)) {
      // out of range value, so decode it as a string.
      fprintf(stderr,"FIELDTYPE_INTEGER: Illegal value - decoding string representation.\n");
      r=stats3_decompress_bits(c,(unsigned char *)value,&value_size,stats,NULL);
    } else 
      sprintf(value,"%d",normalised_value+minimum);
    return 0;
  case FIELDTYPE_FLOAT:
    {
      // Sign
      int sign = range_decode_equiprobable(c,2);
      // Exponent
      int exponent = range_decode_equiprobable(c,256)-128;
      // Mantissa
      int mantissa = 0;
      int b;
      b=range_decode_equiprobable(c,256); mantissa |= b<<16;
      b=range_decode_equiprobable(c,256); mantissa |= b<<8; 
      b=range_decode_equiprobable(c,256); mantissa |= b<<0; 
      float f = mantissa*1.0/0xffffff;
      if (sign) f=-f;
      f = ldexp( f, exponent);
      fprintf(stderr,"sign=%d, exp=%d, mantissa=%x, f=%f\n",
	      sign,exponent,mantissa,f);
      sprintf(value,"%f",f);
      return 0;
    }
  case FIELDTYPE_BOOLEAN:
    normalised_value=range_decode_equiprobable(c,2);
    sprintf(value,"%d",normalised_value);
    return 0;
    break;
  case FIELDTYPE_MULTISELECT:
    {
      int k;
      int vlen=0;
      // Get bitmap of enum fields
      for(k=0;k<recipe->fields[fieldnumber].enum_count;k++)
      {
	if (range_decode_equiprobable(c,2)) {
	  // Field value is present
	  if (vlen) {
	    value[vlen++]='|'; value[vlen]=0;
	  }
	  sprintf(&value[vlen],"%s",recipe->fields[fieldnumber].enum_values[k]);
	  vlen=strlen(value);
	}
      }
      return 0;
      break;
    }
  case FIELDTYPE_ENUM:
    normalised_value=range_decode_equiprobable(c,recipe->fields[fieldnumber]
					       .enum_count);
    if (normalised_value<0||normalised_value>=recipe->fields[fieldnumber].enum_count)      {
      printf("enum: range_decode_equiprobable returned illegal value %d for range %d..%d\n",
	     normalised_value,0,recipe->fields[fieldnumber].enum_count-1);
      return -1;
    }
    sprintf(value,"%s",recipe->fields[fieldnumber].enum_values[normalised_value]);
    printf("enum: decoding %s as %d of %d\n",
	   value,normalised_value,recipe->fields[fieldnumber].enum_count);
    return 0;
    break;
  case FIELDTYPE_TEXT:
    r=stats3_decompress_bits(c,(unsigned char *)value,&value_size,stats,NULL);
    return 0;
  case FIELDTYPE_TIMEDATE:
    // time is 32-bit seconds since 1970.
    // Format as yyyy-mm-ddThh:mm:ss+hh:mm
    {
      // SMAC has a bug with encoding large ranges, so break into smaller pieces
      time_t t = 0;
      t=range_decode_equiprobable(c,0x8000)<<16;
      t|=range_decode_equiprobable(c,0x10000);
      printf("TIMEDATE: decoding t=%d\n",(int)t);
      struct tm tm;
      // gmtime_r(&t,&tm);
      localtime_r(&t,&tm);
      sprintf(value,"%04d-%02d-%02dT%02d:%02d:%02d+00:00",
	      tm.tm_year+1900,tm.tm_mon+1,tm.tm_mday,
	      tm.tm_hour,tm.tm_min,tm.tm_sec);
      return 0;
    }
  case FIELDTYPE_MAGPITIMEDATE:
    // time encodes each field precisely, allowing years 0 - 9999
    // Format as yyyy-mm-dd hh:mm:ss
    {
      struct tm tm;
      bzero(&tm,sizeof(tm));

      tm.tm_year=range_decode_equiprobable(c,10000);
      tm.tm_mon=range_decode_equiprobable(c,12);
      tm.tm_mday=range_decode_equiprobable(c,31);
      tm.tm_hour=range_decode_equiprobable(c,25);
      tm.tm_min=range_decode_equiprobable(c,60);
      tm.tm_sec=range_decode_equiprobable(c,62);
      
      sprintf(value,"%04d-%02d-%02d %02d:%02d:%02d",
	      tm.tm_year,tm.tm_mon+1,tm.tm_mday,
	      tm.tm_hour,tm.tm_min,tm.tm_sec);
      return 0;
    }
  case FIELDTYPE_DATE:
    // Date encoded using:
    // normalised_value=y*372+(m-1)*31+(d-1);
    // So year = value / 372 ...
    {
      if (precision==0) precision=22;
      int minimum=0;
      int maximum=10000*372;
      maximum=maximum>> (22-precision);
      int normalised_value = range_decode_equiprobable(c,maximum-minimum+1);
      int year = normalised_value / 372;
      int day_of_year = normalised_value - (year*372);
      int month = day_of_year/31+1;
      int day_of_month = day_of_year%31+1;
      // American date format for Magpi
      sprintf(value,"%02d-%02d-%04d",month,day_of_month,year);
      return 0;
    }
  case FIELDTYPE_UUID:
    {
      int i,j=5;      
      sprintf(value,"uuid:");
      for(i=0;i<16;i++)
	{
	  int b=0;
	  if ((!recipe->fields[fieldnumber].precision)
	      ||(i<recipe->fields[fieldnumber].precision))
	    b=range_decode_equiprobable(c,256);
	  switch(i) {
	  case 4: case 6: case 8: case 10:
	    value[j++]='-';
	  }
	  sprintf(&value[j],"%02x",b); j+=2;
	  value[j]=0;
	}
      return 0;
    }
  case FIELDTYPE_MAGPIUUID:
    // 64bit hex followed by seconds since UNIX epoch?
    {
      int i,j=0;      
      value[0]=0;
      for(i=0;i<8;i++)
	{
	  int b=0;
	  b=range_decode_equiprobable(c,256);
	  sprintf(&value[j],"%02x",b); j+=2;
	  value[j]=0;
	}
      // 48 bits of milliseconds since unix epoch
      long long timestamp=0;
      for(i=0;i<6;i++) {
	timestamp=timestamp<<8LL;
	int b=range_decode_equiprobable(c,256);	
	timestamp|=b;
      }
      sprintf(&value[j],"-%lld",timestamp);
      return 0;
    }
  case FIELDTYPE_LATLONG:
    {
      int ilat,ilon;
      double lat,lon;
      switch(recipe->fields[fieldnumber].precision) {
      case 0: case 34:
	ilat=range_decode_equiprobable(c,182*112000); ilat-=90*112000;
	ilon=range_decode_equiprobable(c,361*112000); ilon-=180*112000;
	lat=ilat/112000.0; lon=ilon/112000.0;
	break;
      case 16:
	ilat=range_decode_equiprobable(c,182); ilat-=90;
	ilon=range_decode_equiprobable(c,361); ilon-=180;
	lat=ilat; lon=ilon;
	break;
      default:
	sprintf(recipe_error,"Illegal LATLONG precision of %d bits.  Should be 16 or 34.\n",recipe->fields[fieldnumber].precision);
	return -1;
      }
      sprintf(value,"%.5f %.5f",lat,lon);
      return 0;
    }
  default:
    snprintf(recipe_error,1024,"Attempting decompression of unsupported field type of '%s'.\n",recipe_field_type_name(recipe->fields[fieldnumber].type));
    return -1;
  }

  return 0;
}