190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber/*
2f71323e297a928af368937089d3ed71239786f86Andreas Huber *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber *
4f71323e297a928af368937089d3ed71239786f86Andreas Huber *  Use of this source code is governed by a BSD-style license
5f71323e297a928af368937089d3ed71239786f86Andreas Huber *  that can be found in the LICENSE file in the root of the source
6f71323e297a928af368937089d3ed71239786f86Andreas Huber *  tree. An additional intellectual property rights grant can be found
7f71323e297a928af368937089d3ed71239786f86Andreas Huber *  in the file PATENTS.  All contributing project authors may
8f71323e297a928af368937089d3ed71239786f86Andreas Huber *  be found in the AUTHORS file in the root of the source tree.
990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber */
1090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#include <stdlib.h>
1290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber#include <string.h>
13da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian
14f71323e297a928af368937089d3ed71239786f86Andreas Huber#include "vpx/vpx_image.h"
15ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian#include "vpx/vpx_integer.h"
16da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian#include "vpx_mem/vpx_mem.h"
17da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian
187bc9febe8749e98a3812a0dc4380ceae75c29450Johannstatic vpx_image_t *img_alloc_helper(vpx_image_t *img, vpx_img_fmt_t fmt,
197bc9febe8749e98a3812a0dc4380ceae75c29450Johann                                     unsigned int d_w, unsigned int d_h,
20da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian                                     unsigned int buf_align,
21da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian                                     unsigned int stride_align,
22ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian                                     unsigned char *img_data) {
23da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  unsigned int h, w, s, xcs, ycs, bps;
24da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  unsigned int stride_in_bytes;
25da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  int align;
2690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
27ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /* Treat align==0 like align==1 */
287bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (!buf_align) buf_align = 1;
291b362b15af34006e6a11974088a46d42b903418eJohann
30ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /* Validate alignment (must be power of 2) */
317bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (buf_align & (buf_align - 1)) goto fail;
321b362b15af34006e6a11974088a46d42b903418eJohann
33ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /* Treat align==0 like align==1 */
347bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (!stride_align) stride_align = 1;
3590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
36ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /* Validate alignment (must be power of 2) */
377bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (stride_align & (stride_align - 1)) goto fail;
3890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
39ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /* Get sample size for this format */
40ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  switch (fmt) {
41f71323e297a928af368937089d3ed71239786f86Andreas Huber    case VPX_IMG_FMT_RGB32:
42f71323e297a928af368937089d3ed71239786f86Andreas Huber    case VPX_IMG_FMT_RGB32_LE:
43f71323e297a928af368937089d3ed71239786f86Andreas Huber    case VPX_IMG_FMT_ARGB:
447bc9febe8749e98a3812a0dc4380ceae75c29450Johann    case VPX_IMG_FMT_ARGB_LE: bps = 32; break;
45f71323e297a928af368937089d3ed71239786f86Andreas Huber    case VPX_IMG_FMT_RGB24:
467bc9febe8749e98a3812a0dc4380ceae75c29450Johann    case VPX_IMG_FMT_BGR24: bps = 24; break;
47f71323e297a928af368937089d3ed71239786f86Andreas Huber    case VPX_IMG_FMT_RGB565:
48f71323e297a928af368937089d3ed71239786f86Andreas Huber    case VPX_IMG_FMT_RGB565_LE:
49f71323e297a928af368937089d3ed71239786f86Andreas Huber    case VPX_IMG_FMT_RGB555:
50f71323e297a928af368937089d3ed71239786f86Andreas Huber    case VPX_IMG_FMT_RGB555_LE:
51f71323e297a928af368937089d3ed71239786f86Andreas Huber    case VPX_IMG_FMT_UYVY:
52f71323e297a928af368937089d3ed71239786f86Andreas Huber    case VPX_IMG_FMT_YUY2:
537bc9febe8749e98a3812a0dc4380ceae75c29450Johann    case VPX_IMG_FMT_YVYU: bps = 16; break;
54f71323e297a928af368937089d3ed71239786f86Andreas Huber    case VPX_IMG_FMT_I420:
55f71323e297a928af368937089d3ed71239786f86Andreas Huber    case VPX_IMG_FMT_YV12:
56f71323e297a928af368937089d3ed71239786f86Andreas Huber    case VPX_IMG_FMT_VPXI420:
577bc9febe8749e98a3812a0dc4380ceae75c29450Johann    case VPX_IMG_FMT_VPXYV12: bps = 12; break;
58ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    case VPX_IMG_FMT_I422:
597bc9febe8749e98a3812a0dc4380ceae75c29450Johann    case VPX_IMG_FMT_I440: bps = 16; break;
607bc9febe8749e98a3812a0dc4380ceae75c29450Johann    case VPX_IMG_FMT_I444: bps = 24; break;
617bc9febe8749e98a3812a0dc4380ceae75c29450Johann    case VPX_IMG_FMT_I42016: bps = 24; break;
62ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    case VPX_IMG_FMT_I42216:
637bc9febe8749e98a3812a0dc4380ceae75c29450Johann    case VPX_IMG_FMT_I44016: bps = 32; break;
647bc9febe8749e98a3812a0dc4380ceae75c29450Johann    case VPX_IMG_FMT_I44416: bps = 48; break;
657bc9febe8749e98a3812a0dc4380ceae75c29450Johann    default: bps = 16; break;
66ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
6790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
68ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /* Get chroma shift values for this format */
69ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  switch (fmt) {
70f71323e297a928af368937089d3ed71239786f86Andreas Huber    case VPX_IMG_FMT_I420:
71f71323e297a928af368937089d3ed71239786f86Andreas Huber    case VPX_IMG_FMT_YV12:
72f71323e297a928af368937089d3ed71239786f86Andreas Huber    case VPX_IMG_FMT_VPXI420:
73f71323e297a928af368937089d3ed71239786f86Andreas Huber    case VPX_IMG_FMT_VPXYV12:
74ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    case VPX_IMG_FMT_I422:
75ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    case VPX_IMG_FMT_I42016:
767bc9febe8749e98a3812a0dc4380ceae75c29450Johann    case VPX_IMG_FMT_I42216: xcs = 1; break;
777bc9febe8749e98a3812a0dc4380ceae75c29450Johann    default: xcs = 0; break;
78ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
7990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
80ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  switch (fmt) {
81f71323e297a928af368937089d3ed71239786f86Andreas Huber    case VPX_IMG_FMT_I420:
82da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    case VPX_IMG_FMT_I440:
83f71323e297a928af368937089d3ed71239786f86Andreas Huber    case VPX_IMG_FMT_YV12:
84f71323e297a928af368937089d3ed71239786f86Andreas Huber    case VPX_IMG_FMT_VPXI420:
85f71323e297a928af368937089d3ed71239786f86Andreas Huber    case VPX_IMG_FMT_VPXYV12:
86da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    case VPX_IMG_FMT_I42016:
877bc9febe8749e98a3812a0dc4380ceae75c29450Johann    case VPX_IMG_FMT_I44016: ycs = 1; break;
887bc9febe8749e98a3812a0dc4380ceae75c29450Johann    default: ycs = 0; break;
89ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
90ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
9155cd1dd7c8d0a3de907d22e0f12718733f4e41d9Jerome Jiang  /* Calculate storage sizes. If the buffer was allocated externally, the width
9255cd1dd7c8d0a3de907d22e0f12718733f4e41d9Jerome Jiang   * and height shouldn't be adjusted. */
9355cd1dd7c8d0a3de907d22e0f12718733f4e41d9Jerome Jiang  w = d_w;
9455cd1dd7c8d0a3de907d22e0f12718733f4e41d9Jerome Jiang  h = d_h;
95ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  s = (fmt & VPX_IMG_FMT_PLANAR) ? w : bps * w / 8;
96ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  s = (s + stride_align - 1) & ~(stride_align - 1);
97da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  stride_in_bytes = (fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? s * 2 : s;
98ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
99ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /* Allocate the new image */
100ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (!img) {
101ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    img = (vpx_image_t *)calloc(1, sizeof(vpx_image_t));
10290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1037bc9febe8749e98a3812a0dc4380ceae75c29450Johann    if (!img) goto fail;
10490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
105ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    img->self_allocd = 1;
106ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  } else {
107ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    memset(img, 0, sizeof(vpx_image_t));
108ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
10990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
110ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  img->img_data = img_data;
11190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
112ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (!img_data) {
11355cd1dd7c8d0a3de907d22e0f12718733f4e41d9Jerome Jiang    uint64_t alloc_size;
11455cd1dd7c8d0a3de907d22e0f12718733f4e41d9Jerome Jiang    /* Calculate storage sizes given the chroma subsampling */
11555cd1dd7c8d0a3de907d22e0f12718733f4e41d9Jerome Jiang    align = (1 << xcs) - 1;
11655cd1dd7c8d0a3de907d22e0f12718733f4e41d9Jerome Jiang    w = (d_w + align) & ~align;
11755cd1dd7c8d0a3de907d22e0f12718733f4e41d9Jerome Jiang    align = (1 << ycs) - 1;
11855cd1dd7c8d0a3de907d22e0f12718733f4e41d9Jerome Jiang    h = (d_h + align) & ~align;
11955cd1dd7c8d0a3de907d22e0f12718733f4e41d9Jerome Jiang
12055cd1dd7c8d0a3de907d22e0f12718733f4e41d9Jerome Jiang    s = (fmt & VPX_IMG_FMT_PLANAR) ? w : bps * w / 8;
12155cd1dd7c8d0a3de907d22e0f12718733f4e41d9Jerome Jiang    s = (s + stride_align - 1) & ~(stride_align - 1);
12255cd1dd7c8d0a3de907d22e0f12718733f4e41d9Jerome Jiang    stride_in_bytes = (fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? s * 2 : s;
12355cd1dd7c8d0a3de907d22e0f12718733f4e41d9Jerome Jiang    alloc_size = (fmt & VPX_IMG_FMT_PLANAR) ? (uint64_t)h * s * bps / 8
12455cd1dd7c8d0a3de907d22e0f12718733f4e41d9Jerome Jiang                                            : (uint64_t)h * s;
125ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
1267bc9febe8749e98a3812a0dc4380ceae75c29450Johann    if (alloc_size != (size_t)alloc_size) goto fail;
127ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian
128da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian    img->img_data = (uint8_t *)vpx_memalign(buf_align, (size_t)alloc_size);
129ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    img->img_data_owner = 1;
130ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
13190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1327bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (!img->img_data) goto fail;
13390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
134ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  img->fmt = fmt;
135da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  img->bit_depth = (fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? 16 : 8;
136ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  img->w = w;
137ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  img->h = h;
138ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  img->x_chroma_shift = xcs;
139ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  img->y_chroma_shift = ycs;
140ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  img->bps = bps;
14190d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
142ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /* Calculate strides */
143da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  img->stride[VPX_PLANE_Y] = img->stride[VPX_PLANE_ALPHA] = stride_in_bytes;
144da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian  img->stride[VPX_PLANE_U] = img->stride[VPX_PLANE_V] = stride_in_bytes >> xcs;
14590d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
146ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /* Default viewport to entire image */
1477bc9febe8749e98a3812a0dc4380ceae75c29450Johann  if (!vpx_img_set_rect(img, 0, 0, d_w, d_h)) return img;
14890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
14990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huberfail:
150ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  vpx_img_free(img);
151ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return NULL;
15290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
15390d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1547bc9febe8749e98a3812a0dc4380ceae75c29450Johannvpx_image_t *vpx_img_alloc(vpx_image_t *img, vpx_img_fmt_t fmt,
1557bc9febe8749e98a3812a0dc4380ceae75c29450Johann                           unsigned int d_w, unsigned int d_h,
1567bc9febe8749e98a3812a0dc4380ceae75c29450Johann                           unsigned int align) {
157ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return img_alloc_helper(img, fmt, d_w, d_h, align, align, NULL);
15890d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
15990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1607bc9febe8749e98a3812a0dc4380ceae75c29450Johannvpx_image_t *vpx_img_wrap(vpx_image_t *img, vpx_img_fmt_t fmt, unsigned int d_w,
1617bc9febe8749e98a3812a0dc4380ceae75c29450Johann                          unsigned int d_h, unsigned int stride_align,
1627bc9febe8749e98a3812a0dc4380ceae75c29450Johann                          unsigned char *img_data) {
163ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /* By setting buf_align = 1, we don't change buffer alignment in this
164ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang   * function. */
165ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return img_alloc_helper(img, fmt, d_w, d_h, 1, stride_align, img_data);
16690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
16790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
1687bc9febe8749e98a3812a0dc4380ceae75c29450Johannint vpx_img_set_rect(vpx_image_t *img, unsigned int x, unsigned int y,
1697bc9febe8749e98a3812a0dc4380ceae75c29450Johann                     unsigned int w, unsigned int h) {
1707bc9febe8749e98a3812a0dc4380ceae75c29450Johann  unsigned char *data;
171ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
172ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (x + w <= img->w && y + h <= img->h) {
173ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    img->d_w = w;
174ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    img->d_h = h;
175ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
176ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    /* Calculate plane pointers */
177ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    if (!(img->fmt & VPX_IMG_FMT_PLANAR)) {
178ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      img->planes[VPX_PLANE_PACKED] =
1797bc9febe8749e98a3812a0dc4380ceae75c29450Johann          img->img_data + x * img->bps / 8 + y * img->stride[VPX_PLANE_PACKED];
180ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    } else {
181da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian      const int bytes_per_sample =
182da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian          (img->fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? 2 : 1;
183ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      data = img->img_data;
184ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
185ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (img->fmt & VPX_IMG_FMT_HAS_ALPHA) {
186ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        img->planes[VPX_PLANE_ALPHA] =
187da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian            data + x * bytes_per_sample + y * img->stride[VPX_PLANE_ALPHA];
188ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        data += img->h * img->stride[VPX_PLANE_ALPHA];
189ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
190ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
1917bc9febe8749e98a3812a0dc4380ceae75c29450Johann      img->planes[VPX_PLANE_Y] =
1927bc9febe8749e98a3812a0dc4380ceae75c29450Johann          data + x * bytes_per_sample + y * img->stride[VPX_PLANE_Y];
193ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      data += img->h * img->stride[VPX_PLANE_Y];
194ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
195ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      if (!(img->fmt & VPX_IMG_FMT_UV_FLIP)) {
196da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian        img->planes[VPX_PLANE_U] =
197da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian            data + (x >> img->x_chroma_shift) * bytes_per_sample +
198da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian            (y >> img->y_chroma_shift) * img->stride[VPX_PLANE_U];
199ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        data += (img->h >> img->y_chroma_shift) * img->stride[VPX_PLANE_U];
200da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian        img->planes[VPX_PLANE_V] =
201da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian            data + (x >> img->x_chroma_shift) * bytes_per_sample +
202da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian            (y >> img->y_chroma_shift) * img->stride[VPX_PLANE_V];
203ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      } else {
204da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian        img->planes[VPX_PLANE_V] =
205da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian            data + (x >> img->x_chroma_shift) * bytes_per_sample +
206da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian            (y >> img->y_chroma_shift) * img->stride[VPX_PLANE_V];
207ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang        data += (img->h >> img->y_chroma_shift) * img->stride[VPX_PLANE_V];
208da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian        img->planes[VPX_PLANE_U] =
209da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian            data + (x >> img->x_chroma_shift) * bytes_per_sample +
210da49e34c1fb5e99681f4ad99c21d9cfd83eddb96Vignesh Venkatasubramanian            (y >> img->y_chroma_shift) * img->stride[VPX_PLANE_U];
211ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang      }
21290d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber    }
213ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang    return 0;
214ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
215ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  return -1;
21690d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
21790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
218ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangvoid vpx_img_flip(vpx_image_t *img) {
219ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  /* Note: In the calculation pointer adjustment calculation, we want the
220ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang   * rhs to be promoted to a signed type. Section 6.3.1.8 of the ISO C99
221ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang   * standard indicates that if the adjustment parameter is unsigned, the
222ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang   * stride parameter will be promoted to unsigned, causing errors when
223ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang   * the lhs is a larger type than the rhs.
224ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang   */
225ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  img->planes[VPX_PLANE_Y] += (signed)(img->d_h - 1) * img->stride[VPX_PLANE_Y];
226ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  img->stride[VPX_PLANE_Y] = -img->stride[VPX_PLANE_Y];
227ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2287bc9febe8749e98a3812a0dc4380ceae75c29450Johann  img->planes[VPX_PLANE_U] += (signed)((img->d_h >> img->y_chroma_shift) - 1) *
2297bc9febe8749e98a3812a0dc4380ceae75c29450Johann                              img->stride[VPX_PLANE_U];
230ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  img->stride[VPX_PLANE_U] = -img->stride[VPX_PLANE_U];
231ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2327bc9febe8749e98a3812a0dc4380ceae75c29450Johann  img->planes[VPX_PLANE_V] += (signed)((img->d_h >> img->y_chroma_shift) - 1) *
2337bc9febe8749e98a3812a0dc4380ceae75c29450Johann                              img->stride[VPX_PLANE_V];
234ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  img->stride[VPX_PLANE_V] = -img->stride[VPX_PLANE_V];
235ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang
2367bc9febe8749e98a3812a0dc4380ceae75c29450Johann  img->planes[VPX_PLANE_ALPHA] +=
2377bc9febe8749e98a3812a0dc4380ceae75c29450Johann      (signed)(img->d_h - 1) * img->stride[VPX_PLANE_ALPHA];
238ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  img->stride[VPX_PLANE_ALPHA] = -img->stride[VPX_PLANE_ALPHA];
23990d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
24090d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
241ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuangvoid vpx_img_free(vpx_image_t *img) {
242ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  if (img) {
2437bc9febe8749e98a3812a0dc4380ceae75c29450Johann    if (img->img_data && img->img_data_owner) vpx_free(img->img_data);
24490d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber
2457bc9febe8749e98a3812a0dc4380ceae75c29450Johann    if (img->self_allocd) free(img);
246ba164dffc5a6795bce97fae02b51ccf3330e15e4hkuang  }
24790d3ed91ae9228e1c8bab561b6138d4cb8c1e4fdAndreas Huber}
248