/*!\brief Open a descriptor, using existing storage for the underlying image * * Returns a descriptor for storing an image of the given format. The * storage for descriptor has been allocated elsewhere, and a descriptor is * desired to "wrap" that storage. * * \param[in] img Pointer to storage for descriptor. If this * parameter is NULL, the storage for the descriptor * will be allocated on the heap. * \param[in] fmt Format for the image * \param[in] d_w Width of the image * \param[in] d_h Height of the image * \param[in] stride_align Alignment, in bytes, of each row in the image. * \param[in] img_data Storage to use for the image * * \return Returns a pointer to the initialized image descriptor. If the img * parameter is non-null, the value of the img parameter will be * returned. */ //vpx_image_t* vpx_img_wrap(vpx_image_t* img, vpx_img_fmt_t fmt, unsigned int d_w, // unsigned int d_h, unsigned int stride_align, // unsigned char* img_data); public vpx_image_t vpx_img_wrap(vpx_image_t img, vpx_img_fmt_t fmt, uint d_w, uint d_h, uint stride_align, byte *img_data) { /* By setting buf_align = 1, we don't change buffer alignment in this * function. */ return(img_alloc_helper(img, fmt, d_w, d_h, 1, stride_align, img_data)); }
private static vpx_image_t img_alloc_helper(vpx_image_t img, vpx_img_fmt_t fmt, uint d_w, uint d_h, uint buf_align, uint stride_align, byte *img_data) { uint h, w, s, xcs, ycs, bps; uint stride_in_bytes; int align; /* Treat align==0 like align==1 */ if (buf_align == 0) { buf_align = 1; } /* Validate alignment (must be power of 2) */ if ((buf_align & (buf_align - 1)) != 0) { goto fail; } /* Treat align==0 like align==1 */ if (stride_align == 0) { stride_align = 1; } /* Validate alignment (must be power of 2) */ if ((stride_align & (stride_align - 1)) != 0) { goto fail; } /* Get sample size for this format */ switch (fmt) { case vpx_img_fmt_t.VPX_IMG_FMT_I420: case vpx_img_fmt_t.VPX_IMG_FMT_YV12: case vpx_img_fmt_t.VPX_IMG_FMT_NV12: bps = 12; break; case vpx_img_fmt_t.VPX_IMG_FMT_I422: case vpx_img_fmt_t.VPX_IMG_FMT_I440: bps = 16; break; case vpx_img_fmt_t.VPX_IMG_FMT_I444: bps = 24; break; case vpx_img_fmt_t.VPX_IMG_FMT_I42016: bps = 24; break; case vpx_img_fmt_t.VPX_IMG_FMT_I42216: case vpx_img_fmt_t.VPX_IMG_FMT_I44016: bps = 32; break; case vpx_img_fmt_t.VPX_IMG_FMT_I44416: bps = 48; break; default: bps = 16; break; } /* Get chroma shift values for this format */ // For VPX_IMG_FMT_NV12, xcs needs to be 0 such that UV data is all read at // one time. switch (fmt) { case vpx_img_fmt_t.VPX_IMG_FMT_I420: case vpx_img_fmt_t.VPX_IMG_FMT_YV12: case vpx_img_fmt_t.VPX_IMG_FMT_I422: case vpx_img_fmt_t.VPX_IMG_FMT_I42016: case vpx_img_fmt_t.VPX_IMG_FMT_I42216: xcs = 1; break; default: xcs = 0; break; } switch (fmt) { case vpx_img_fmt_t.VPX_IMG_FMT_I420: case vpx_img_fmt_t.VPX_IMG_FMT_NV12: case vpx_img_fmt_t.VPX_IMG_FMT_I440: case vpx_img_fmt_t.VPX_IMG_FMT_YV12: case vpx_img_fmt_t.VPX_IMG_FMT_I42016: case vpx_img_fmt_t.VPX_IMG_FMT_I44016: ycs = 1; break; default: ycs = 0; break; } /* Calculate storage sizes. If the buffer was allocated externally, the width * and height shouldn't be adjusted. */ w = d_w; h = d_h; s = (((int)fmt & vpx_image_t.VPX_IMG_FMT_PLANAR) > 0) ? w : bps * w / 8; s = (s + stride_align - 1) & ~(stride_align - 1); stride_in_bytes = (((int)fmt & vpx_image_t.VPX_IMG_FMT_HIGHBITDEPTH) > 0) ? s * 2 : s; /* Allocate the new image */ if (img == null) { //img = (vpx_image_t*)calloc(1, sizeof(vpx_image_t)); //if (!img) goto fail; img = new vpx_image_t(); img.self_allocd = 1; } else { //memset(img, 0, sizeof(vpx_image_t)); } img.img_data = img_data; if (img_data == null) { ulong alloc_size; /* Calculate storage sizes given the chroma subsampling */ align = (1 << (int)xcs) - 1; w = (uint)((d_w + align) & ~align); align = (1 << (int)ycs) - 1; h = (uint)((d_h + align) & ~align); s = (((int)fmt & vpx_image_t.VPX_IMG_FMT_PLANAR) > 0) ? w : bps * w / 8; s = (s + stride_align - 1) & ~(stride_align - 1); stride_in_bytes = (((int)fmt & vpx_image_t.VPX_IMG_FMT_HIGHBITDEPTH) > 0) ? s * 2 : s; alloc_size = (((int)fmt & vpx_image_t.VPX_IMG_FMT_PLANAR) > 0) ? (ulong)h * s * bps / 8 : (ulong)h * s; //if (alloc_size != (size_t)alloc_size) goto fail; //img.img_data = (byte*)vpx_memalign(buf_align, (size_t)alloc_size); img.img_data = (byte *)Marshal.AllocHGlobal((int)alloc_size); img.img_data_owner = 1; } if (img.img_data == null) { goto fail; } img.fmt = fmt; img.bit_depth = (((int)fmt & vpx_image_t.VPX_IMG_FMT_HIGHBITDEPTH) > 0) ? 16U : 8U; img.w = w; img.h = h; img.x_chroma_shift = xcs; img.y_chroma_shift = ycs; img.bps = (int)bps; /* Calculate strides */ img.stride[vpx_image_t.VPX_PLANE_Y] = img.stride[vpx_image_t.VPX_PLANE_ALPHA] = (int)stride_in_bytes; img.stride[vpx_image_t.VPX_PLANE_U] = img.stride[vpx_image_t.VPX_PLANE_V] = (int)(stride_in_bytes >> (int)xcs); /* Default viewport to entire image */ if (vpx_img_set_rect(img, 0, 0, d_w, d_h) == 0) { return(img); } fail: vpx_img_free(img); return(null); }
/*!\brief Open a descriptor, allocating storage for the underlying image * * Returns a descriptor for storing an image of the given format. The * storage for the descriptor is allocated on the heap. * * \param[in] img Pointer to storage for descriptor. If this parameter * is NULL, the storage for the descriptor will be * allocated on the heap. * \param[in] fmt Format for the image * \param[in] d_w Width of the image * \param[in] d_h Height of the image * \param[in] align Alignment, in bytes, of the image buffer and * each row in the image(stride). * * \return Returns a pointer to the initialized image descriptor. If the img * parameter is non-null, the value of the img parameter will be * returned. */ //vpx_image_t* vpx_img_alloc(vpx_image_t* img, vpx_img_fmt_t fmt, // unsigned int d_w, unsigned int d_h, // unsigned int align); public static vpx_image_t vpx_img_alloc(vpx_image_t img, vpx_img_fmt_t fmt, uint d_w, uint d_h, uint align) { return(img_alloc_helper(img, fmt, d_w, d_h, align, align, null)); }