Vector FXAA::filterPixel(int row, int col, const ScalarImagePtr &img) const { const Vector rgbNW = pixel(row-1, col-1, img); const Vector rgbNE = pixel(row-1, col+1, img); const Vector rgbSW = pixel(row+1, col-1, img); const Vector rgbSE = pixel(row+1, col+1, img); const Vector rgbM = pixel(row, col, img); const Vector luma = Vector(Scalar(0.299), Scalar(0.587), Scalar(0.114)); Scalar lumaNW = rgbNW.dot(luma); Scalar lumaNE = rgbNE.dot(luma); Scalar lumaSW = rgbSW.dot(luma); Scalar lumaSE = rgbSE.dot(luma); Scalar lumaM = rgbM.dot(luma); Scalar lumaMin = SMIN(lumaNW, SMIN(lumaNE, SMIN(lumaSW, SMIN(lumaSE, lumaM)))); Scalar lumaMax = SMAX(lumaNW, SMAX(lumaNE, SMAX(lumaSW, SMAX(lumaSE, lumaM)))); // FXAA params - fixed here for now. const Scalar fxaa_reduce_mul = Scalar(1) / Scalar(32); const Scalar fxaa_reduce_min = Scalar(1) / Scalar(128); const Scalar fxaa_span_max = Scalar(8); // Find direction and blur orthogonal to edge. Vector2 dir; dir.x() = -((lumaNW + lumaNE) - (lumaSW + lumaSE)); dir.y() = ((lumaNW + lumaSW) - (lumaNE + lumaSE)); Scalar dirRed = SMAX((lumaNW + lumaNE + lumaSW + lumaSE) * (Scalar(0.25) * fxaa_reduce_mul), fxaa_reduce_min); Scalar invDirMin = Scalar(1) / (SMIN(abs(dir.x()), abs(dir.y())) + dirRed); dir *= invDirMin; dir.x() = clamp(dir.x(), -fxaa_span_max, fxaa_span_max); dir.y() = clamp(dir.y(), -fxaa_span_max, fxaa_span_max); const Scalar c = Scalar(1)/Scalar(3) - Scalar(0.5); const Scalar d = Scalar(2)/Scalar(3) - Scalar(0.5); const Scalar e = Scalar(0)/Scalar(3) - Scalar(0.5); const Scalar f = Scalar(3)/Scalar(3) - Scalar(0.5); Vector rgbA = Scalar(0.5) * (bilinearSample(row + c, col + c, img) + bilinearSample(row + d, col + d, img)); Vector rgbB = rgbA * Scalar(0.5) + Scalar(0.25) * (bilinearSample(row + e, col + e, img) + bilinearSample(row + f, col + f, img)); Scalar lumaB = rgbB.dot(luma); if ((lumaB < lumaMin) || (lumaB > lumaMax)) { return rgbA; } else { return rgbB; } }
int sa_share_zfs(sa_share_t share, sa_resource_t resource, char *path, share_t *sh, void *exportdata, zfs_share_op_t operation) { libzfs_handle_t *libhandle; sa_group_t group; sa_handle_t sahandle; char *dataset; int err = EINVAL; int i, j; char newpath[MAXPATHLEN]; char *pathp; /* * First find the dataset name */ if ((group = sa_get_parent_group(share)) == NULL) { return (EINVAL); } if ((sahandle = sa_find_group_handle(group)) == NULL) { return (EINVAL); } /* * If get_zfs_dataset fails, see if it is a subdirectory */ pathp = path; while ((dataset = get_zfs_dataset(sahandle, pathp, B_TRUE)) == NULL) { char *p; if (pathp == path) { (void) strlcpy(newpath, path, sizeof (newpath)); pathp = newpath; } /* * Make sure only one leading '/' This condition came * about when using HAStoragePlus which insisted on * putting an extra leading '/' in the ZFS path * name. The problem is fixed in other areas, but this * will catch any other ways that a double slash might * get introduced. */ while (*pathp == '/' && *(pathp + 1) == '/') pathp++; /* * chop off part of path, but if we are at root then * make sure path is a / */ if ((strlen(pathp) > 1) && (p = strrchr(pathp, '/'))) { if (pathp == p) { *(p + 1) = '\0'; /* skip over /, root case */ } else { *p = '\0'; } } else { return (EINVAL); } } libhandle = libzfs_init(); if (libhandle != NULL) { char *resource_name; i = (sh->sh_path ? strlen(sh->sh_path) : 0); sh->sh_size = i; j = (sh->sh_res ? strlen(sh->sh_res) : 0); sh->sh_size += j; SMAX(i, j); j = (sh->sh_fstype ? strlen(sh->sh_fstype) : 0); sh->sh_size += j; SMAX(i, j); j = (sh->sh_opts ? strlen(sh->sh_opts) : 0); sh->sh_size += j; SMAX(i, j); j = (sh->sh_descr ? strlen(sh->sh_descr) : 0); sh->sh_size += j; SMAX(i, j); resource_name = sa_get_resource_attr(resource, "name"); err = zfs_deleg_share_nfs(libhandle, dataset, path, resource_name, exportdata, sh, i, operation); if (err == SA_OK) sa_update_sharetab_ts(sahandle); else err = errno; if (resource_name) sa_free_attr_string(resource_name); libzfs_fini(libhandle); } free(dataset); return (err); }