#define YUV420_y(v) (Caml_ba_data_val(Field(v,0)))
#define YUV420_y_stride(v) (Int_val(Field(v,1)))
#define YUV420_u(v) (Caml_ba_data_val(Field(v,2)))
#define YUV420_v(v) (Caml_ba_data_val(Field(v,3)))
#define YUV420_uv_stride(v) (Int_val(Field(v,4)))
#define YUV420_width(v) (Int_val(Field(v,5)))
#define YUV420_height(v) (Int_val(Field(v,6)))
#define YUV420_alpha(v) (Is_block(Field(v,7))?Caml_ba_data_val(Field(Field(v,7),0)):NULL)

typedef struct
{
  int width;
  int height;
  unsigned char *y;
  int y_stride;
  unsigned char *u;
  unsigned char *v;
  int uv_stride;
  unsigned char *alpha;
} yuv420;

static void yuv420_of_value(yuv420 *yuv, value v)
{
  yuv->y = YUV420_y(v);
  yuv->y_stride = YUV420_y_stride(v);
  yuv->u = YUV420_u(v);
  yuv->v = YUV420_v(v);
  yuv->uv_stride = YUV420_uv_stride(v);
  yuv->width = YUV420_width(v);
  yuv->height = YUV420_height(v);
  yuv->alpha = YUV420_alpha(v);
}

#define Y(yuv,i,j) yuv.y[j*yuv.y_stride+i]
#define U(yuv,i,j) yuv.u[(j/2)*yuv.uv_stride+(i/2)]
#define V(yuv,i,j) yuv.v[(j/2)*yuv.uv_stride+(i/2)]
#define A(yuv,i,j) yuv.alpha[j*yuv.y_stride+i]
