/// /// Тоже, что и 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()); }
/// /// Обертка на 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; }