psd_bool psd_incept_rect(psd_rect * r1, psd_rect * r2, psd_rect * dst_rect) { dst_rect->left = PSD_MAX(r1->left, r2->left); dst_rect->right = PSD_MIN(r1->right, r2->right); dst_rect->top = PSD_MAX(r1->top, r2->top); dst_rect->bottom = PSD_MIN(r1->bottom, r2->bottom); if(dst_rect->left >= dst_rect->right || dst_rect->top >= dst_rect->bottom) return psd_false; return psd_true; }
psd_status psd_get_path(psd_context * context, psd_int length) { psd_status status; if(context->path_count >= context->malloc_path) { context->malloc_path = PSD_MAX(context->malloc_path * 2, PSD_MIN_PATH_COUNT); context->paths = (psd_path *)psd_realloc(context->paths, context->malloc_path * sizeof(psd_path)); if(context->paths == NULL) return psd_status_malloc_failed; } status = psd_get_path_record(context, &context->paths[context->path_count], length); if(status != psd_status_done) return status; context->path_count ++; return psd_status_done; }
void psd_bitmap_gaussian_blur_alpha_channel(psd_bitmap * bitmap, psd_double radius) { psd_int width, height; psd_int *buf, *bb; psd_int pixels; psd_int total = 1, total2; psd_int i, row, col; psd_int start, end; psd_int *curve; psd_int *sum = NULL; psd_int val; psd_int length; psd_int initial_p, initial_m; psd_double std_dev; psd_color_component * src, * sp; psd_argb_color * src_data, * dst_data; if(radius <= 0.0) return; width = bitmap->width; height = bitmap->height; if(width < 1 || height < 1) return; buf = (psd_int *)psd_malloc(PSD_MAX(width, height) * 2 * sizeof(psd_int)); src = (psd_color_component *)psd_malloc(PSD_MAX(width, height)); /* First the vertical pass */ radius = fabs(radius) * 1.4; std_dev = sqrt(-(radius * radius) / (2 * log(1.0 / 255.0))); curve = psd_make_curve (std_dev, &length); sum = (psd_int *)psd_malloc((2 * length + 1) * sizeof(psd_int)); sum[0] = 0; for(i = 1; i <= length*2; i++) sum[i] = curve[i-length-1] + sum[i-1]; sum += length; total = sum[length] - sum[-length]; total2 = total / 2; /* First, the vertical pass */ for(col = 0; col < width; col++) { for(row = 0, src_data = bitmap->image_data + width + col; row < height - 1; row ++, src_data += width) src[row] = PSD_GET_ALPHA_COMPONENT(*src_data); src[height - 1] = 0; sp = src; initial_p = *sp; initial_m = *(sp + height - 1); /* Determine a run-length encoded version of the row */ psd_run_length_encode(sp, buf, height); for(row = 0, dst_data = bitmap->image_data + col; row < height; row ++, dst_data += width) { start = (row < length) ? -row : -length; end = (height <= (row + length) ? (height - row - 1) : length); val = 0; i = start; bb = buf + (row + i) * 2; if(start != -length) val += initial_p * (sum[start] - sum[-length]); while(i < end) { pixels = bb[0]; i += pixels; if(i > end) i = end; val += bb[1] * (sum[i] - sum[start]); bb += (pixels * 2); start = i; } if(end != length) val += initial_m * (sum[length] - sum[end]); *dst_data = (*dst_data & 0x00FFFFFF) | ((val + total2) / total << 24); } } /* Now the horizontal pass */ for(row = 0; row < height; row++) { for(col = 0, src_data = bitmap->image_data + row * width + 1; col < width - 1; col ++, src_data ++) src[col] = PSD_GET_ALPHA_COMPONENT(*src_data); src[width - 1] = 0; sp = src; initial_p = *sp; initial_m = *(sp + width - 1); /* Determine a run-length encoded version of the row */ psd_run_length_encode(sp, buf, width); for(col = 0, dst_data = bitmap->image_data + row * width; col < width; col ++, dst_data ++) { start = (col < length) ? -col : -length; end = (width <= (col + length)) ? (width - col - 1) : length; val = 0; i = start; bb = buf + (col + i) * 2; if(start != -length) val += initial_p * (sum[start] - sum[-length]); while(i < end) { pixels = bb[0]; i += pixels; if(i > end) i = end; val += bb[1] * (sum[i] - sum[start]); bb += (pixels * 2); start = i; } if(end != length) val += initial_m * (sum[length] - sum[end]); *dst_data = (*dst_data & 0x00FFFFFF) | ((val + total2) / total << 24); } } /* free buffers */ psd_free(curve - length); psd_free(sum - length); psd_free(buf); psd_free(src); }