Exemple #1
0
///
/// Тоже, что и attr_int, только для чтения child_value()
/// В конфиге это выглядит как <param>1234<param>
///
int child_value_int(const pugi::xml_node &node, const char *text)
{
	pugi::xml_node child_node = node.child(text);
	if (!child_node)
	{
		snprintf(buf, MAX_STRING_LENGTH, "...%s read fail", text);
		mudlog(buf, CMP, LVL_IMMORT, SYSLOG, TRUE);
	}
	return cast_to_int(child_node.child_value());
}
Exemple #2
0
///
/// Обертка на pugixml для чтения числового аттрибута
/// с логирование в имм- и сислог
/// В конфиге это выглядит как <param value="1234" />
/// \return -1 в случае неудачи
int attr_int(const pugi::xml_node &node, const char *text)
{
	pugi::xml_attribute attr = node.attribute(text);
	if (!attr)
	{
		snprintf(buf, MAX_STRING_LENGTH, "...%s read fail", text);
		mudlog(buf, CMP, LVL_IMMORT, SYSLOG, TRUE);
	}
	return cast_to_int(attr.value());
}
// The make_clist() method generates, for all destination samples,
// the list of all source samples with non-zero weighted contributions.
Resampler::Contrib_List* Resampler::make_clist(
   int src_x, int dst_x, Boundary_Op boundary_op,
   Resample_Real (*Pfilter)(Resample_Real),
   Resample_Real filter_support,
   Resample_Real filter_scale,
   Resample_Real src_ofs)
{
   typedef struct
   {
      // The center of the range in DISCRETE coordinates (pixel center = 0.0f).
      Resample_Real center;
      int left, right;
   } Contrib_Bounds;

   int i, j, k, n, left, right;
   Resample_Real total_weight;
   Resample_Real xscale, center, half_width, weight;
   Contrib_List* Pcontrib;
   Contrib* Pcpool;
   Contrib* Pcpool_next;
   Contrib_Bounds* Pcontrib_bounds;

   if ((Pcontrib = (Contrib_List*)calloc(dst_x, sizeof(Contrib_List))) == NULL)
      return NULL;

   Pcontrib_bounds = (Contrib_Bounds*)calloc(dst_x, sizeof(Contrib_Bounds));
   if (!Pcontrib_bounds)
   {
      free(Pcontrib);
      return (NULL);
   }

   const Resample_Real oo_filter_scale = 1.0f / filter_scale;

   const Resample_Real NUDGE = 0.5f;
   xscale = dst_x / (Resample_Real)src_x;

   if (xscale < 1.0f)
   {
      int total; (void)total;

      /* Handle case when there are fewer destination
      * samples than source samples (downsampling/minification).
      */

      // stretched half width of filter
      half_width = (filter_support / xscale) * filter_scale;

      // Find the range of source sample(s) that will contribute to each destination sample.

      for (i = 0, n = 0; i < dst_x; i++)
      {
         // Convert from discrete to continuous coordinates, scale, then convert back to discrete.
         center = ((Resample_Real)i + NUDGE) / xscale;
         center -= NUDGE;
         center += src_ofs;

         left   = cast_to_int((Resample_Real)floor(center - half_width));
         right  = cast_to_int((Resample_Real)ceil(center + half_width));

         Pcontrib_bounds[i].center = center;
         Pcontrib_bounds[i].left		= left;
         Pcontrib_bounds[i].right	= right;

         n += (right - left + 1);
      }

      /* Allocate memory for contributors. */

      if ((n == 0) || ((Pcpool = (Contrib*)calloc(n, sizeof(Contrib))) == NULL))
      {
         free(Pcontrib);
         free(Pcontrib_bounds);
         return NULL;
      }
      total = n;

      Pcpool_next = Pcpool;

      /* Create the list of source samples which
      * contribute to each destination sample.
      */

      for (i = 0; i < dst_x; i++)
      {
         int max_k = -1;
         Resample_Real max_w = -1e+20f;

         center = Pcontrib_bounds[i].center;
         left   = Pcontrib_bounds[i].left;
         right  = Pcontrib_bounds[i].right;

         Pcontrib[i].n = 0;
         Pcontrib[i].p = Pcpool_next;
         Pcpool_next += (right - left + 1);
         resampler_assert ((Pcpool_next - Pcpool) <= total);

         total_weight = 0;

         for (j = left; j <= right; j++)
            total_weight += (*Pfilter)((center - (Resample_Real)j) * xscale * oo_filter_scale);
         const Resample_Real norm = static_cast<Resample_Real>(1.0f / total_weight);

         total_weight = 0;

#if RESAMPLER_DEBUG
         printf("%i: ", i);
#endif

         for (j = left; j <= right; j++)
         {
            weight = (*Pfilter)((center - (Resample_Real)j) * xscale * oo_filter_scale) * norm;
            if (weight == 0.0f)
               continue;

            n = reflect(j, src_x, boundary_op);

#if RESAMPLER_DEBUG
            printf("%i(%f), ", n, weight);
#endif

            /* Increment the number of source
            * samples which contribute to the
            * current destination sample.
            */

            k = Pcontrib[i].n++;

            Pcontrib[i].p[k].pixel  = (unsigned short)(n);       /* store src sample number */
            Pcontrib[i].p[k].weight = weight; /* store src sample weight */

            total_weight += weight;          /* total weight of all contributors */

            if (weight > max_w)
            {
               max_w = weight;
               max_k = k;
            }
         }

#if RESAMPLER_DEBUG
         printf("\n\n");
#endif

         //resampler_assert(Pcontrib[i].n);
         //resampler_assert(max_k != -1);
         if ((max_k == -1) || (Pcontrib[i].n == 0))
         {
            free(Pcpool);
            free(Pcontrib);
            free(Pcontrib_bounds);
            return NULL;
         }

         if (total_weight != 1.0f)
            Pcontrib[i].p[max_k].weight += 1.0f - total_weight;
      }
   }
   else
   {
      /* Handle case when there are more
      * destination samples than source
      * samples (upsampling).
      */

      half_width = filter_support * filter_scale;

      // Find the source sample(s) that contribute to each destination sample.

      for (i = 0, n = 0; i < dst_x; i++)
      {
         // Convert from discrete to continuous coordinates, scale, then convert back to discrete.
         center = ((Resample_Real)i + NUDGE) / xscale;
         center -= NUDGE;
         center += src_ofs;

         left   = cast_to_int((Resample_Real)floor(center - half_width));
         right  = cast_to_int((Resample_Real)ceil(center + half_width));

         Pcontrib_bounds[i].center = center;
         Pcontrib_bounds[i].left		= left;
         Pcontrib_bounds[i].right	= right;

         n += (right - left + 1);
      }

      /* Allocate memory for contributors. */

      int total = n;
      if ((total == 0) || ((Pcpool = (Contrib*)calloc(total, sizeof(Contrib))) == NULL))
      {
         free(Pcontrib);
         free(Pcontrib_bounds);
         return NULL;
      }

      Pcpool_next = Pcpool;

      /* Create the list of source samples which
      * contribute to each destination sample.
      */

      for (i = 0; i < dst_x; i++)
      {
         int max_k = -1;
         Resample_Real max_w = -1e+20f;

         center = Pcontrib_bounds[i].center;
         left   = Pcontrib_bounds[i].left;
         right  = Pcontrib_bounds[i].right;

         Pcontrib[i].n = 0;
         Pcontrib[i].p = Pcpool_next;
         Pcpool_next += (right - left + 1);
         resampler_assert((Pcpool_next - Pcpool) <= total);

         total_weight = 0;
         for (j = left; j <= right; j++)
            total_weight += (*Pfilter)((center - (Resample_Real)j) * oo_filter_scale);

         const Resample_Real norm = static_cast<Resample_Real>(1.0f / total_weight);

         total_weight = 0;

#if RESAMPLER_DEBUG
         printf("%i: ", i);
#endif

         for (j = left; j <= right; j++)
         {
            weight = (*Pfilter)((center - (Resample_Real)j) * oo_filter_scale) * norm;
            if (weight == 0.0f)
               continue;

            n = reflect(j, src_x, boundary_op);

#if RESAMPLER_DEBUG
            printf("%i(%f), ", n, weight);
#endif

            /* Increment the number of source
            * samples which contribute to the
            * current destination sample.
            */

            k = Pcontrib[i].n++;

            Pcontrib[i].p[k].pixel  = (unsigned short)(n);       /* store src sample number */
            Pcontrib[i].p[k].weight = weight; /* store src sample weight */

            total_weight += weight;          /* total weight of all contributors */

            if (weight > max_w)
            {
               max_w = weight;
               max_k = k;
            }
         }

#if RESAMPLER_DEBUG
         printf("\n\n");
#endif

         //resampler_assert(Pcontrib[i].n);
         //resampler_assert(max_k != -1);

         if ((max_k == -1) || (Pcontrib[i].n == 0))
         {
            free(Pcpool);
            free(Pcontrib);
            free(Pcontrib_bounds);
            return NULL;
         }

         if (total_weight != 1.0f)
            Pcontrib[i].p[max_k].weight += 1.0f - total_weight;
      }
   }

#if RESAMPLER_DEBUG
   printf("*******\n");
#endif

   free(Pcontrib_bounds);

   return Pcontrib;
}